Communication à bande ultralarge (UWB)

La communication en bande ultralarge est une technologie radio axée sur une mesure précise de la distance (mesure la position avec une précision de 10 cm) entre les appareils. Cette technologie radio peut utiliser une densité à faible consommation d'énergie pour les mesures à courte portée et effectuer un signal à haut débit sur une grande partie du spectre radio. La bande passante de l'UWB est supérieure à 500 MHz (ou supérieure à 20% fractionnaire) bande passante).

Contrôleur/Initiateur par rapport au Contrôleur/Répondant

La communication UWB a lieu entre deux appareils, dont l'un est un contrôleur, et l'autre autre est un Controlee. Le contrôleur détermine le canal complexe (UwbComplexChannel) qui les deux appareils partagent et en sont à l'origine, tandis que le Controlee est le répondant.

Un contrôleur peut gérer plusieurs personnes contrôlées, mais une personne contrôlée ne peut que s'abonner à un seul contrôleur. Contrôleur/Initiateur et Contrôleur/Répondant sont prises en charge.

Paramètres de plage

Le responsable du traitement et le responsable du contrôle doivent s'identifier et communiquer paramètres de plage pour commencer la plage. Cet échange est laissé aux applications implémenter à l'aide d'un mécanisme externe sécurisé de son choix, tel que Bluetooth à basse consommation (BLE).

Les paramètres de plage incluent une adresse locale, un canal complexe et une clé de session, entre autres. Remarque que ces paramètres peuvent alterner ou changer d'une autre manière après la session de mesure des distances. se termine et doit être communiqué à nouveau pour redémarrer la mesure des distances.

Portée de l'arrière-plan

Une application exécutée en arrière-plan peut lancer une session de mesure des distances par UWB si l'appareil le prend en charge. Pour vérifier les fonctionnalités de votre appareil, consultez RangingCapabilities.

L'application ne reçoit pas de rapports sur les distances lorsqu'elle s'exécute en arrière-plan. l'application reçoit des rapports sur les distances lorsqu'il passe au premier plan.

Configurations STS

L'application ou le service provisionne une clé de session pour chaque session à l'aide d'une clé Séquence d'horodatage (STS). Le mécanisme STS provisionné est plus sécurisé qu'un STS statique configuration. Le STS provisionné est compatible avec tous les appareils compatibles avec la UWB exécutant Android 14 ou version ultérieure

Catégorie de la menace STS statique Service STS autorisé
Air: observateur passif Atténué Atténué
Air: amplification du signal Atténué Atténué
Air: attaque par rejeu/relais Susceptible Atténué

Pour le mécanisme STS provisionné:

  1. Utilisez le uwbConfigType dans RangingParameters qui est compatible avec le protocole STS provisionné.

  2. Indiquez la clé de 16 octets dans le champ sessionKeyInfo.

Pour le protocole STS statique:

  1. Utilisez le uwbConfigType dans RangingParameters qui est compatible avec le protocole STS statique.

  2. Indiquez la clé de huit octets dans le champ sessionKeyInfo.

Étapes

Pour utiliser l'API UWB, procédez comme suit:

  1. Assurez-vous que les appareils Android sont équipés d'Android 12 ou version ultérieure et qu'ils prendre en charge l'UWB à l'aide PackageManager#hasSystemFeature("android.hardware.uwb")
  2. S'il s'agit d'appareils IoT, assurez-vous qu'ils sont conformes à la norme FiRa MAC 1.3. est conforme à nos règles.
  3. Découvrez les appareils pairs compatibles avec la UWB à l'aide d'un mécanisme OOB de votre choix tels que BluetoothLeScanner
  4. Échangez des paramètres de plage à l'aide d'un mécanisme OOB sécurisé de votre choix. par exemple BluetoothGatt.
  5. Si l'utilisateur souhaite arrêter la session, annulez la portée de la session.

Restrictions d'utilisation

Les restrictions suivantes s'appliquent à l'utilisation de l'API UWB:

  1. L'application qui lance de nouvelles sessions de mesure des distances par UWB doit être au premier plan application ou service, sauf si la gestion des plages en arrière-plan est compatible comme illustré ici plus tôt.
  2. Lorsque l'application passe en arrière-plan (pendant que la session est en cours), l'application risquent de ne plus recevoir de rapports sur les plages. La session UWB sont maintenues dans les couches inférieures. Lorsque l'application revient au premier plan, les rapports sur les distances sont réactivés.

Exemples de code

Application exemple

Pour obtenir un exemple de bout en bout montrant comment utiliser la bibliothèque Jetpack UWB, consultez notre exemple d'application sur GitHub. Cet exemple d'application explique comment valider la compatibilité de la UWB sur un appareil Android, activer le processus de découverte à l'aide d'un mécanisme OOB et configurer la UWB entre deux appareils compatibles avec la UWB. L'exemple couvre également les cas d'utilisation du contrôle des appareils et du partage de contenu multimédia.

Gamme UWB

Cet exemple de code lance et arrête la plage UWB pour un contrôleur:

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

Compatibilité avec RxJava3

La prise en charge de Rxjava3 est désormais disponible pour favoriser l'interopérabilité avec Java clients. Cette bibliothèque permet d'obtenir des résultats échelonnés en tant qu'observable ou Flowable et pour récupérer l'UwbClientSessionScope en tant qu'objet Single.

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

Compatibilité avec l'écosystème

Voici les appareils partenaires et les SDK tiers compatibles.

Appareils mobiles compatibles avec la UWB

Depuis mars 2024, ces appareils sont compatibles avec la bibliothèque Jetpack Android UWB:

Fournisseur Modèle de l'appareil
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 tiers

Depuis avril 2023, ces solutions partenaires sont compatibles avec bibliothèque Jetpack actuelle.

Problème connu: ordre des octets inversé pour les champs d'adresse MAC et d'ID de fournisseur STS statique

Sur Android 13 et versions antérieures, la pile Android UWB inverse à tort l'octet pour les champs suivants:

  • Adresse MAC de l'appareil
  • Adresse MAC de destination
  • ID de fournisseur STS statique

L'inversion de l'ordre des octets se produit, car la pile Android traite ces champs. sous forme de valeurs et non de tableaux. Nous collaborons avec la FiRa pour mettre à jour les spécifications UCI (CR-1112). pour indiquer explicitement que ces champs doivent être traités comme des tableaux.

Ce problème sera résolu via la mise à jour GMS Core dans la version 2320XXXX. Pour se conformer aux appareils Android à partir de ce moment-là, les fournisseurs IoT doivent modifier votre implémentation pour éviter d'inverser l'ordre des octets de ces champs.