Komunikasi ultra-wideband (UWB)

Komunikasi ultra-wideband adalah teknologi radio yang berfokus pada rentang presisi (mengukur lokasi hingga akurasi 10 cm) antarperangkat. Teknologi radio ini dapat menggunakan kepadatan energi rendah untuk pengukuran jarak pendek dan melakukan sinyal bandwidth tinggi pada sebagian besar spektrum radio. Bandwidth UWB lebih besar dari 500 MHz (atau melebihi 20% bandwidth pecahan).

Pengontrol/Inisiator vs. Pengendali/Responden

Komunikasi UWB terjadi antara dua perangkat, dengan salah satunya sebagai Pengontrol dan lainnya sebagai Controlee. Pengontrol menentukan saluran kompleks (UwbComplexChannel) yang akan digunakan bersama oleh kedua perangkat dan merupakan inisiator, sedangkan Controlee adalah penanggap.

Pengontrol dapat menangani beberapa Pengontrol, tetapi Penerima Kontrol hanya dapat berlangganan ke satu Pengontrol. Konfigurasi Pengontrol/Inisiator dan Controlee/Responder didukung.

Menentukan parameter

Pengontrol dan Controlee perlu mengidentifikasi satu sama lain dan mengomunikasikan parameter untuk memulai ranging. Pertukaran ini diserahkan ke aplikasi untuk diimplementasikan menggunakan mekanisme out-of-band (OOB) yang aman sesuai pilihan mereka, seperti Bluetooth Hemat Energi (BLE).

Parameter rentang mencakup, di antaranya alamat lokal, saluran kompleks, dan kunci sesi. Perhatikan bahwa parameter ini dapat dirotasi atau berubah setelah sesi ranging berakhir dan harus dikomunikasikan ulang untuk memulai ulang ranging.

Rentang latar belakang

Aplikasi yang berjalan di latar belakang dapat memulai sesi rentang UWB jika perangkat mendukungnya. Untuk memeriksa kemampuan perangkat Anda, lihat RangingCapabilities.

Aplikasi tidak menerima laporan rentang saat berjalan di latar belakang; aplikasi menerima laporan rentang saat berpindah ke latar depan.

Konfigurasi STS

Aplikasi atau layanan menyediakan kunci sesi untuk setiap sesi menggunakan Urutan Stempel Waktu Acak (STS). STS yang disediakan lebih aman daripada konfigurasi STS statis. STS yang disediakan didukung di semua perangkat yang mendukung UWB yang menjalankan Android 14 atau yang lebih baru.

Kategori ancaman STS Statis STS yang ditetapkan
Udara: Pengamat pasif Dimitigasi Dimitigasi
Udara: Penguatan sinyal Dimitigasi Dimitigasi
Air: Serangan replay/relay Rentan Dimitigasi

Untuk STS yang disediakan:

  1. Gunakan uwbConfigType di RangingParameters yang mendukung STS yang disediakan.

  2. Berikan kunci 16 byte di kolom sessionKeyInfo.

Untuk STS statis:

  1. Gunakan uwbConfigType di RangingParameters yang mendukung STS statis.

  2. Masukkan kunci 8 byte di kolom sessionKeyInfo.

Langkah

Untuk menggunakan UWB API, ikuti langkah-langkah berikut:

  1. Pastikan perangkat Android berjalan di Android 12 atau yang lebih tinggi dan mendukung UWB menggunakan PackageManager#hasSystemFeature("android.hardware.uwb").
  2. Jika beragam untuk perangkat IoT, pastikan perangkat tersebut mematuhi FiRa MAC 1.3.
  3. Temukan perangkat pembanding yang mendukung UWB menggunakan mekanisme OOB pilihan Anda, seperti BluetoothLeScanner.
  4. Menukar parameter rentang menggunakan mekanisme OOB aman pilihan Anda, seperti BluetoothGatt.
  5. Jika pengguna ingin menghentikan sesi, batalkan cakupan sesi.

Batasan penggunaan

Pembatasan berikut berlaku untuk penggunaan UWB API:

  1. Aplikasi yang memulai sesi rentang UWB baru harus merupakan aplikasi atau layanan latar depan, kecuali jika rentang latar belakang didukung seperti yang diilustrasikan sebelumnya.
  2. Saat aplikasi berpindah ke latar belakang (saat sesi sedang berlangsung), aplikasi mungkin tidak lagi menerima laporan rentang. Namun, sesi UWB akan terus dipertahankan di lapisan bawah. Saat aplikasi kembali ke latar depan, laporan rentang akan dilanjutkan.

Contoh kode

Aplikasi contoh

Untuk contoh menyeluruh tentang cara menggunakan library Jetpack UWB, lihat aplikasi contoh kami di GitHub. Aplikasi contoh ini mencakup validasi kompatibilitas UWB pada perangkat Android, memungkinkan proses penemuan menggunakan mekanisme OOB, dan menyiapkan UWB yang berkisar antara dua perangkat yang mendukung UWB. Contoh ini juga mencakup kasus penggunaan kontrol perangkat dan berbagi media.

Rentang UWB

Contoh kode ini memulai dan menghentikan rentang UWB untuk Controlee:

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

Dukungan RxJava3

Dukungan Rxjava3 kini tersedia untuk membantu mencapai interoperabilitas dengan klien Java. Library ini menyediakan cara untuk mendapatkan hasil mulai sebagai aliran Observable atau Flowable, dan untuk mengambil UwbClientSessionScope sebagai objek Tunggal.

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

Dukungan ekosistem

Berikut adalah perangkat partner dan SDK pihak ketiga yang didukung.

Perangkat seluler yang mendukung UWB

Mulai Maret 2024, perangkat berikut mendukung library Jetpack Android UWB:

Vendor Model Perangkat
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 pihak ketiga

Mulai April 2023, solusi partner ini kompatibel dengan library Jetpack saat ini.

Masalah umum: urutan byte dibalik untuk kolom alamat MAC dan ID vendor STS statis

Di Android 13 dan yang lebih lama, stack Android UWB salah membalik urutan byte untuk kolom berikut:

  • Alamat MAC perangkat
  • Alamat MAC tujuan
  • ID vendor STS statis

Pembalikan urutan byte terjadi karena stack Android memperlakukan kolom ini sebagai nilai, bukan array. Kami bekerja sama dengan FiRa untuk memperbarui spesifikasi UCI (CR-1112) agar secara eksplisit menyatakan bahwa kolom ini harus diperlakukan sebagai array.

Masalah ini akan diperbaiki melalui update GMS Core dalam rilis 2320XXXX. Agar sesuai dengan perangkat Android sejak saat itu, vendor IOT harus mengubah implementasi Anda untuk menghindari membalikkan urutan byte kolom ini.