초광대역 (UWB) 통신

초광대역 통신은 기기 간의 정확한 측정(위치를 10cm 정확도로 측정)에 중점을 둔 무선 기술입니다. 이 무선 기술은 단거리 측정에 낮은 에너지 밀도를 사용하고 무선 스펙트럼의 상당 부분에서 고대역폭 신호를 보낼 수 있습니다. UWB의 대역폭이 500MHz를 초과하거나 (또는 20% 의 대역폭 비율을 초과)

컨트롤러/시작자와 제어 대상/응답자 비교

UWB 통신은 두 기기 간에 발생하며, 하나는 컨트롤러이고 다른 하나는 제어 대상입니다. 컨트롤러는 두 기기가 공유할 복잡한 채널(UwbComplexChannel)을 결정하고 이니시에이터이며, 제어 대상은 응답자입니다.

컨트롤러는 여러 컨트롤러를 처리할 수 있지만 컨트롤러는 단일 컨트롤러에만 구독할 수 있습니다. 컨트롤러/이니시에이터 구성과 제어 대상/응답자 구성이 모두 지원됩니다.

범위 매개변수

컨트롤러와 제어 대상은 서로를 식별하고 범위 설정 매개변수를 통신하여 범위 설정을 시작해야 합니다. 이 교환은 애플리케이션이 선택한 보안 비표준(OOB) 메커니즘(예: 저전력 블루투스(BLE))을 사용하여 구현하도록 둡니다.

범위 매개변수에는 로컬 주소, 복잡한 채널, 세션 키 등이 포함됩니다. 이러한 매개변수는 측정 세션이 종료된 후 회전하거나 변경될 수 있으며 측정을 다시 시작하려면 다시 통신해야 합니다.

백그라운드 반경 설정

백그라운드에서 실행되는 앱은 기기에서 지원하는 경우 UWB 측정 세션을 시작할 수 있습니다. 기기 기능을 확인하려면 RangingCapabilities를 참고하세요.

앱이 백그라운드에서 실행 중일 때는 측정 보고를 수신하지 않습니다. 앱이 포그라운드로 이동하면 측정 보고를 수신합니다.

STS 구성

앱 또는 서비스는 스크램블된 타임스탬프 시퀀스 (STS)를 사용하여 각 세션의 세션 키를 프로비저닝합니다. 프로비저닝된 STS는 정적 STS 구성보다 안전합니다. 프로비저닝된 STS는 Android 14 이상을 실행하는 모든 UWB 지원 기기에서 지원됩니다.

위협 카테고리 정적 STS 프로비저닝된 STS
공기: 수동 관찰자 완화됨 완화됨
Air: 신호 증폭 완화됨 완화됨
Air: 재전송/중계 공격 취약함 완화됨

프로비저닝된 STS의 경우:

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

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

정적 STS의 경우:

  1. 정적 STS를 지원하는 RangingParametersuwbConfigType를 사용합니다.

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

단계

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

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

사용 제한

UWB API 사용에는 다음과 같은 제한사항이 적용됩니다.

  1. 앞에서 설명한 대로 백그라운드 측정이 지원되지 않는 한 새 UWB 측정 세션을 시작하는 앱은 포그라운드 앱 또는 서비스여야 합니다.
  2. 세션이 진행되는 동안 앱이 백그라운드로 이동하면 앱이 더 이상 측정 보고를 수신하지 못할 수 있습니다. 그러나 UWB 세션은 하위 레이어에서 계속 유지됩니다. 앱이 포그라운드로 다시 이동하면 측정 보고가 재개됩니다.

코드 샘플

샘플 앱

UWB Jetpack 라이브러리를 사용하는 방법에 관한 엔드 투 엔드 예시는 GitHub의 샘플 애플리케이션을 확인하세요. 이 샘플 앱에서는 Android 기기에서 UWB 호환성을 검증하고, OOB 메커니즘을 사용하여 검색 프로세스를 사용 설정하고, 두 개의 UWB 지원 기기 간에 UWB 범위를 설정하는 방법을 설명합니다. 이 샘플에서는 기기 제어 및 미디어 공유 사용 사례도 다룹니다.

UWB 측정

이 코드 샘플은 제어 대상의 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 지원 휴대기기

2025년 1월부터 다음 기기에서 Android UWB Jetpack 라이브러리가 지원됩니다.

공급업체 기기 모델
Google Pixel Pro (6 Pro 이상), Fold, Tablet
Motorola Edge 50 Ultra
삼성 Galaxy Note 20, Galaxy Plus 및 Ultra (S21 이상), Galaxy Z Fold (Fold2 이상)

참고: 백그라운드 UWB 측정은 다음을 제외한 모든 기기에서 지원됩니다.

  • Pixel 6 Pro 및 Pixel 7 Pro
  • Android 13 이하를 실행하는 삼성 휴대전화
  • Android 14 이하를 실행하는 삼성 중국 휴대전화

서드 파티 SDK

2023년 4월부터 이러한 파트너 솔루션은 현재 Jetpack 라이브러리와 호환됩니다.

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

Android 13 이하에서는 Android UWB 스택이 다음 필드의 바이트 순서를 잘못 반전합니다.

  • 기기 MAC 주소
  • 대상 MAC 주소
  • 정적 STS 공급업체 ID

Android 스택이 이러한 필드를 배열이 아닌 값으로 처리하기 때문에 바이트 순서가 반전됩니다. Google은 FiRa와 협력하여 이러한 필드를 배열로 취급해야 한다고 명시적으로 명시하도록 UCI 사양(CR-1112)을 업데이트하고 있습니다.

이 문제는 2320XXXX 출시의 GMS Core 업데이트를 통해 해결될 예정입니다. 그때부터 Android 기기를 준수하려면 IOT 공급업체가 이러한 필드의 바이트 순서가 역전되지 않도록 구현을 수정해야 합니다.