Comunicazione a banda ultralarga (UWB)

La comunicazione a banda ultralarga è una tecnologia radio focalizzata sulla gamma precisa (misurando la posizione con una precisione di 10 cm) tra i dispositivi. Questa tecnologia radio può utilizzare una densità a bassa energia per misurazioni a corto raggio ed eseguono segnali ad alta larghezza di banda in gran parte dello spettro radio. La larghezza di banda della tecnologia UWB è superiore a 500 MHz (o supera il 20% frazionario larghezza di banda larga).

Titolare/iniziatore/responsabile del controllo/risponditore

La comunicazione UWB avviene tra due dispositivi, di cui uno è un controller, l'altra è una persona di controllo. Il controller determina il canale complesso (UwbComplexChannel) che i due dispositivi condivideranno e ne sarà l'iniziatore, mentre il Controllore è all'intervistato.

Un controller può gestire più persone controllate, mentre un destinatario può solo sottoscrivere un abbonamento a un singolo Titolare. Sia titolare/iniziatore che controllante/rispondente sono supportate.

Diversi parametri

Il titolare e il soggetto controllato devono identificarsi a vicenda e comunicare per iniziare a fornire. Questo scambio viene lasciato alle applicazioni implementare utilizzando un meccanismo sicuro fuori banda (OOB) a scelta, come Bluetooth Low Energy (BLE).

I parametri vari che includono, ad esempio, indirizzo locale, canale complesso e chiave di sessione. Nota che questi parametri possano ruotare o cambiare in altro modo dopo la sessione di intervallo termina e devono essere ricomunicati per riavviare il rilevamento.

Background (sfondo)

Un'app in esecuzione in background può avviare una sessione di rilevamento UWB se il dispositivo la supporta. Per controllare le funzionalità del dispositivo, vedi RangingCapabilities.

L'app non riceve report relativi alla distanza quando viene eseguita in background; l'app riceve report di intervallo quando passa in primo piano.

Configurazioni STS

L'app o il servizio esegue il provisioning di una chiave di sessione per ogni sessione utilizzando una chiave sequenza di timestamp (STS). Il servizio STS sottoposto a provisioning è più sicuro di uno STS statico configurazione. Il servizio STS di cui è stato eseguito il provisioning è supportato su tutti i dispositivi abilitati per UWB in esecuzione Android 14 o versioni successive.

Categoria di minaccia STS statico STS previsto
Aria: osservatore passivo Mitigato Mitigato
Air: amplificazione del segnale Mitigato Mitigato
Air: attacco di ripetizione/invio tramite relè Suscettibile Mitigato

Per STS di cui è stato eseguito il provisioning:

  1. Utilizza l'elemento uwbConfigType in RangingParameters che supporta STS di cui è stato eseguito il provisioning.

  2. Fornisci la chiave da 16 byte nel campo sessionKeyInfo.

Per STS statico:

  1. Utilizza il uwbConfigType in RangingParameters che supporta STS statico.

  2. Fornisci la chiave da 8 byte nel campo sessionKeyInfo.

Passi

Per utilizzare l'API UWB, segui questi passaggi:

  1. Assicurati che i dispositivi Android utilizzino Android 12 o versioni successive e che supportare la tecnologia UWB con PackageManager#hasSystemFeature("android.hardware.uwb").
  2. Se vanno contro dispositivi IoT, assicurarsi che siano FiRa MAC 1.3 conforme.
  3. Scopri i dispositivi peer compatibili con UWB utilizzando un meccanismo OOB a tua scelta. come BluetoothLeScanner
  4. Scambia parametri con un intervallo di valori usando un meccanismo OOB sicuro a tua scelta. ad esempio BluetoothGatt.
  5. Se l'utente vuole interrompere la sessione, annulla l'ambito della sessione.

Limitazioni all'utilizzo

All'uso dell'API UWB si applicano le seguenti limitazioni:

  1. L'app che avvia nuove sessioni UWB deve essere in primo piano app o servizio, a meno che non sia supportato l'intervallo in background, come illustrato in precedenza.
  2. Quando l'app passa in background (durante la sessione), potrebbero non ricevere più report sulla distanza. La sessione UWB, tuttavia, continuerà a essere mantenuta negli strati inferiori. Quando l'app torna alla in primo piano, verranno ripristinati i report.

Esempi di codice

App di esempio

Per un esempio end-to-end su come utilizzare la libreria UWB Jetpack, controlla la nostra applicazione di esempio su GitHub. Questa app di esempio spiega la convalida della compatibilità UWB su un dispositivo Android, l'attivazione del processo di rilevamento tramite un meccanismo OOB e la configurazione della tecnologia UWB tra due dispositivi che supportano la tecnologia UWB. L'esempio riguarda anche i casi d'uso relativi al controllo dei dispositivi e alla condivisione di contenuti multimediali.

Intervallo UWB

Questo esempio di codice avvia e termina la tecnologia UWB per una persona di controllo:

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

Supporto RxJava3

Il supporto Rxjava3 è ora disponibile per facilitare l'interoperabilità con Java clienti. Questa libreria fornisce un modo per ottenere risultati relativi a una scala come Osservabile o Flusso fluido e recuperare UwbClientSessionScope come oggetto singolo.

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

Supporto dell'ecosistema

Di seguito sono riportati i dispositivi dei partner e gli SDK di terze parti supportati.

Dispositivi mobili con tecnologia UWB

A partire da marzo 2024, questi dispositivi supporteranno la libreria Android UWB Jetpack:

Fornitore Modello del dispositivo
Google Pixel 6 Pro, 7 Pro, 8 Pro, Fold, Tablet
Samsung Galaxy Note 20, S21+, S22+, S23+, S24+ Z Fold 2, 3, 4, 5

SDK di terze parti

A partire da aprile 2023, queste soluzioni dei partner sono compatibili con attuale libreria Jetpack.

Problema noto: ordine dei byte invertito per i campi degli indirizzi MAC e degli ID fornitore STS statici

Su Android 13 e versioni precedenti, lo stack UWB Android inverte erroneamente i byte per i seguenti campi:

  • Indirizzo MAC del dispositivo
  • Indirizzo MAC di destinazione
  • ID fornitore STS statico

L'inversione dell'ordine dei byte si verifica perché lo stack Android tratta questi campi come valori, non come array. Stiamo collaborando con FiRa per aggiornare la specifica UCI (CR-1112) per indicare esplicitamente che questi campi devono essere trattati come array.

Questo problema verrà risolto tramite l'aggiornamento GMS Core nella release 2320XXXX. Per essere conformi con i dispositivi Android da quel momento in poi, i fornitori di IoT devono modificare la tua implementazione per evitare di invertire l'ordine dei byte di questi campi.