Komunikacja ultraszerokopasmowa (UWB)

Komunikacja ultraszerokopasmowa to technologia radiowa skupiająca się na precyzyjnym określaniu odległości (pomiar lokalizacji z dokładnością do 10 cm między urządzeniami). Ta technologia radiowa może wykorzystywać gęstość energii o niskiej gęstości energii do pomiarów krótkiego zasięgu oraz wykonywać sygnalizację o dużej przepustowości w dużej części pasma radiowego. Przepustowość UWB przekracza 500 MHz (lub przekracza 20% przepustowości cząstkowej).

Kontroler/inicjator vs. użytkownik kontrolny/użytkownik odpowiadający

Komunikacja UWB zachodzi między 2 urządzeniami, z których jedno jest kontrolerem, a drugie osobą kontrolną. Administrator określa złożony kanał (UwbComplexChannel), który będą współużytkować oba urządzenia, i jest inicjatorem, a Osoba kontrolna jest osobą odpowiedzialną.

Kontroler może obsługiwać wiele elementów sterujących, a osoba ta może subskrybować tylko jeden kontroler. Obsługiwane są zarówno konfiguracje kontrolera/inicjatora, jak i kontrolera/respondenta.

Parametry zakresu

Aby rozpocząć zakres, kontroler i osoba kontrolna muszą się zidentyfikować i przekazać różne parametry. Wymiana ta pozostawia się aplikacjom do implementacji przy użyciu wybranego przez siebie bezpiecznego zewnętrznego mechanizmu (OOB), takiego jak Bluetooth Low Energy (BLE).

Parametry zakresu obejmują m.in. lokalny adres, złożony kanał i klucz sesji. Pamiętaj, że po zakończeniu sesji zakresu te parametry mogą się zmieniać lub w inny sposób zmieniać. Aby można było wznowić zakres, trzeba je ponownie przekazać.

Zakres w tle

Aplikacja działająca w tle może rozpocząć sesję UWB, jeśli urządzenie ją obsługuje. Aby sprawdzić możliwości urządzenia, otwórz stronę RangingCapabilities.

Gdy aplikacja działa w tle, nie otrzymuje raportów o zakresie zakresu. Gdy przejdzie na pierwszy plan, otrzyma raporty o zakresie zakresu.

Konfiguracje STS

Aplikacja lub usługa udostępnia klucz sesji dla każdej sesji przy użyciu zaszyfrowanej sekwencji sygnatury czasowej (STS). Zarejestrowana konfiguracja STS jest bezpieczniejsza niż statyczna konfiguracja STS. Udostępniana funkcja STS jest obsługiwana na wszystkich urządzeniach z Androidem 14 lub nowszym, które obsługują UWB.

Kategoria zagrożenia Statyczny STS Zarejestrowana usługa STS
Powietrze: bierny obserwator Złagodzenie Złagodzenie
W powietrzu: wzmocnienie sygnału Złagodzenie Złagodzenie
W powietrzu: atak typu sztafet Podatne Złagodzenie

W przypadku obsługiwanej usługi STS:

  1. Użyj w domenie RangingParameters klucza uwbConfigType, który obsługuje obsługiwane STS.

  2. W polu sessionKeyInfo podaj klucz 16-bajtowy.

W przypadku statycznego STS:

  1. Użyj w RangingParameters tagu uwbConfigType, który obsługuje statyczny STS.

  2. W polu sessionKeyInfo podaj klucz 8-bajtowy.

Kroki

Aby użyć interfejsu UWB API, wykonaj te czynności:

  1. Upewnij się, że urządzenia z Androidem działają z Androidem 12 lub nowszym i obsługują UWB za pomocą technologii PackageManager#hasSystemFeature("android.hardware.uwb").
  2. Jeśli poruszasz się po urządzeniach IoT, upewnij się, że są one zgodne ze standardem FiRa MAC 1.3.
  3. Odkryj urządzenia równorzędne z obsługą UWB, korzystając z wybranego mechanizmu OOB, np. BluetoothLeScanner.
  4. Wymieniaj parametry zakresu za pomocą wybranego przez siebie bezpiecznego mechanizmu OOB, takiego jak BluetoothGatt.
  5. Jeśli użytkownik chce zatrzymać sesję, anuluj jej zakres.

Ograniczenia w zakresie użytkowania

Korzystanie z interfejsu UWB API podlega tym ograniczeniom:

  1. Aplikacja inicjująca nowe sesje zakresowania UWB musi być aplikacją lub usługą na pierwszym planie, chyba że zakres działania w tle jest obsługiwany, jak pokazano wcześniej.
  2. Gdy aplikacja przejdzie do działania w tle (podczas trwania sesji), może przestać otrzymywać raporty o zakresie zakresu. Sesja UWB będzie jednak nadal utrzymywana w niższych warstwach. Gdy aplikacja wróci na pierwszy plan, raporty zakresu zostaną wznowione.

Przykłady kodu

Przykładowa aplikacja

Pełny przykład korzystania z biblioteki UWB Jetpack znajdziesz w naszej przykładowej aplikacji na GitHubie. Ta przykładowa aplikacja obejmuje sprawdzanie zgodności UWB na urządzeniu z Androidem, włączanie procesu wykrywania za pomocą mechanizmu OOB i konfigurowanie 2 urządzeń obsługujących UWB. Przykład obejmuje też sterowanie urządzeniem i udostępnianie multimediów.

Numeracja UWB

Ten przykładowy kod inicjuje i zatrzymuje odczyt UWB dla elementu sterującego:

// 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()
    }
}

Obsługa RxJava3

Obsługa Rxjava3 ułatwia osiągnięcie interoperacyjności z klientami Java. Ta biblioteka umożliwia uzyskiwanie wyników w postaci zakresu w postaci strumienia obserwowalnego lub przepływowego oraz pobieranie obiektu UwbClientSessionScope jako pojedynczego obiektu.

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();

Obsługa ekosystemu

Oto obsługiwane urządzenia partnerów i pakiety SDK innych firm.

Urządzenia mobilne z obsługą UWB

Od marca 2024 roku te urządzenia obsługują bibliotekę Android UWB Jetpack:

Dostawca Model urządzenia
Google Pixel 6 Pro, 7 Pro, 8 Pro, Fold, tablet
Samsung Galaxy Note 20, S21+, S22+, S23+, S24+ Z Fold 2, 3, 4, 5

Pakiety SDK innych firm

Od kwietnia 2023 r. te rozwiązania partnerów są zgodne z aktualną biblioteką Jetpack.

Znany problem: odwrócona kolejność bajtów w polach adresu MAC i statycznego identyfikatora dostawcy usługi STS

W Androidzie 13 i starszych stos UWB Androida nieprawidłowo odwraca kolejność bajtów w tych polach:

  • Adres MAC urządzenia
  • Adres MAC miejsca docelowego
  • Statyczny identyfikator dostawcy usługi STS

Cofnięcie kolejności bajtów ma miejsce, ponieważ stos Androida traktuje te pola jako wartości, a nie tablice. Współpracujemy z FiRa, aby zaktualizować specyfikację UCI (CR-1112), by wyraźnie określić, że te pola powinny być traktowane jak tablice.

Ten problem zostanie rozwiązany w ramach podstawowej aktualizacji GMS w wersji 2320XXXX. Aby od tej pory zapewnić zgodność z urządzeniami z Androidem, dostawcy IOT muszą zmodyfikować Twoją implementację, aby uniknąć zmiany kolejności bajtów w tych polach.