Ultrabreitband-Kommunikation (UWB)

Ultrabreitband-Kommunikation ist eine Funktechnologie mit Fokus auf präzise Entfernungsbestimmung (Standortmessung auf 10 cm Genauigkeit) zwischen Geräten. Diese Funktechnologie kann Messungen mit niedriger Energiedichte für kurze Distanzen verwenden. und Signale mit hoher Bandbreite über einen großen Teil des Funkspektrums übertragen. Die Bandbreite von UWB ist größer als 500 MHz bzw. mehr als 20 %. Bandbreite).

Verantwortlicher/Initiator im Vergleich zu Kontrollgruppe/Teilnehmer

Die UWB-Kommunikation erfolgt zwischen zwei Geräten, wobei das eine Gerät ein Controller ist und das ein Controlee. Der Controller bestimmt den komplexen Kanal (UwbComplexChannel), die werden die beiden Geräte geteilt und ist der Initiator, während der Controlee der Teilnehmer.

Ein Controller kann mehrere Controlees verarbeiten, ein Controlee kann aber nur Abos abschließen auf einen einzelnen Verantwortlichen. Sowohl Verantwortlicher/Initiator als auch Controlee/Teilnehmer Konfigurationen unterstützt werden.

Bereichsparameter

Datenverantwortliche und Aufsichtsverantwortliche müssen sich gegenseitig identifizieren und miteinander kommunizieren mit dem Bereichsrang beginnen. Dieser Austausch bleibt den Anwendungen überlassen, einen sicheren Out-of-Band-Mechanismus (OOB) ihrer Wahl implementieren, z. B. Bluetooth Low Energy (BLE)

Die Bereichsparameter sind u. a. die lokale Adresse, der komplexe Channel und der Sitzungsschlüssel. Hinweis Diese Parameter können sich nach der Bereichserkennungssitzung drehen oder sich anderweitig ändern. und müssen benachrichtigt werden, um die Bereichserkennung neu zu starten.

Bereichserkennung im Hintergrund

Eine im Hintergrund ausgeführte App kann eine UWB-Ortungssitzung starten, wenn das Gerät unterstützt. Informationen zu den Funktionen Ihres Geräts finden Sie unter RangingCapabilities.

Wenn die App im Hintergrund ausgeführt wird, erhält sie keine Reichweitenberichte. die App erhält Entfernungsberichte, wenn er in den Vordergrund wechselt.

STS-Konfigurationen

Die Anwendung oder der Dienst stellt einen Sitzungsschlüssel für jede Sitzung mithilfe eines verschlüsselten Skripts bereit. Zeitstempelsequenz (STS). Bereitgestelltes STS ist sicherer als statisches STS Konfiguration. Bereitgestelltes STS wird auf allen UWB-fähigen Geräten unterstützt, auf denen Android 14 oder höher.

Bedrohungskategorie Statisches STS Bereitgestelltes STS
Luft: Passiver Beobachter Mitigated (gemindert) Mitigated (gemindert)
Luft: Signalverstärkung Mitigated (gemindert) Mitigated (gemindert)
Air: Replay-/Relay-Angriff Anfällig Mitigated (gemindert)

Bereitgestelltes STS:

  1. Verwenden Sie die uwbConfigType in RangingParameters, die bereitgestelltes STS unterstützt.

  2. Geben Sie den 16-Byte-Schlüssel im Feld sessionKeyInfo an.

Für statisches STS:

  1. Verwenden Sie die uwbConfigType in RangingParameters, die statisches STS unterstützt.

  2. Geben Sie den 8-Byte-Schlüssel im Feld sessionKeyInfo an.

Schritte

So verwendest du die UWB API:

  1. Achten Sie darauf, dass Android-Geräte mit Android 12 oder höher laufen und unterstützen UWB mit PackageManager#hasSystemFeature("android.hardware.uwb")
  2. Bei der Auswahl an IoT-Geräten stellen Sie sicher, dass diese den FiRa MAC 1.3-Standard haben. konform sind.
  3. Finde UWB-fähige Peer-Geräte mit einem OOB-Mechanismus deiner Wahl zum Beispiel BluetoothLeScanner
  4. Bereichsparameter mit einem sicheren OOB-Mechanismus Ihrer Wahl austauschen wie BluetoothGatt.
  5. Wenn der Nutzer die Sitzung beenden möchte, brechen Sie den Umfang der Sitzung ab.

Nutzungsbeschränkungen

Für die Nutzung der UWB API gelten die folgenden Einschränkungen:

  1. Die App, die neue UWB-Entfernungssitzungen initiiert, muss ein Vordergrund sein App oder Dienst, es sei denn, die Bereichserkennung im Hintergrund wird wie dargestellt unterstützt. zuvor.
  2. Wenn die App in den Hintergrund wechselt (während der Sitzung), wird die App erhält unter Umständen keine Berichte mit Bereichsumfang mehr. Die UWB-Sitzung wird jedoch weiterhin in den unteren Layern verwaltet werden. Wenn die App zum im Vordergrund, werden die Reichweitenberichte fortgesetzt.

Codebeispiele

Beispiel-App

Ein End-to-End-Beispiel zur Verwendung der UWB-Jetpack-Bibliothek finden Sie in unserer Beispielanwendung auf GitHub. In dieser Beispiel-App geht es um die Überprüfung der UWB-Kompatibilität auf einem Android-Gerät, die Aktivierung der Erkennung mithilfe eines OOB-Mechanismus und die Einrichtung von UWB zwischen zwei UWB-fähigen Geräten. Es werden auch Anwendungsfälle für die Gerätesteuerung und die Medienfreigabe behandelt.

UWB-Reichweite

In diesem Codebeispiel wird die UWB-Bereichsbestimmung für eine Controlee initiiert und beendet:

// 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-Unterstützung

Unterstützung für Rxjava3 ist jetzt verfügbar, um Interoperabilität mit Java zu erreichen Kundschaft. Diese Bibliothek ermöglicht es, verschiedene Ergebnisse als beobachtbare oder Fließbarer Stream und zum Abrufen des UwbClientSessionScope als einzelnes Objekt.

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

Systemunterstützung

Folgende Partnergeräte und SDKs von Drittanbietern werden unterstützt.

UWB-fähige Mobilgeräte

Seit März 2024 unterstützen die folgenden Geräte die Android UWB Jetpack-Bibliothek:

Vendor Gerätemodell
Google Pixel 6 Pro, Pixel 7 Pro, Pixel 8 Pro, Fold, Tablet
Samsung Galaxy Note 20, S21+, S22+, S23+, S24+ Z Fold 2, 3, 4, 5

Drittanbieter-SDKs

Seit April 2023 sind diese Partnerlösungen mit den aktueller Jetpack-Bibliothek.

Bekanntes Problem: Bytereihenfolge für MAC-Adressfelder und statische STS-Anbieter-ID-Felder umgekehrt

Unter Android 13 und niedriger kehrt der Android-UWB-Stack das Byte fälschlicherweise um für die folgenden Felder ein:

  • MAC-Adresse des Geräts
  • MAC-Zieladresse
  • Anbieter-ID für statische STS

Die Umkehrung der Bytereihenfolge erfolgt, weil der Android-Stack diese Felder als Werte und nicht als Arrays. Wir arbeiten mit FiRa an der Aktualisierung der UCI-Spezifikation (CR-1112) explizit angeben, dass diese Felder als Arrays behandelt werden sollen.

Dieses Problem wird durch das GMS Core-Update in der 2320XXXX-Version behoben. Damit Android-Geräte ab diesem Zeitpunkt konform sind, müssen IoT-Anbieter Änderungen vornehmen, Implementierung, um eine Umkehrung der Bytereihenfolge dieser Felder zu vermeiden.