Komunikasi ultra-wideband (UWB)

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

Pengontrol/Inisiator vs. Kontrol/Responden

Komunikasi UWB terjadi antara dua perangkat, di mana satu adalah Pengontrol, dan satu lagi adalah {i>Controlee<i}. Pengontrol menentukan saluran yang kompleks (UwbComplexChannel) yang kedua perangkat akan berbagi dan merupakan inisiator, sedangkan Controlee adalah responden.

{i>Controller<i} dapat menangani beberapa {i>Controlee<i}, tetapi {i>Controlee<i} hanya dapat berlangganan ke satu Pengontrol. Pengontrol/Inisiator dan Controlee/Responder jika tidak didukung.

Menentukan rentang parameter

Pengontrol dan Pengendali perlu mengidentifikasi satu sama lain dan berkomunikasi range untuk memulai penyortiran. Pertukaran ini diserahkan ke aplikasi untuk menerapkan mekanisme menggunakan mekanisme out-of-band (OOB) yang aman pilihan mereka, seperti Bluetooth Hemat Energi (BLE).

Parameter rentang menyertakan alamat lokal, saluran kompleks, kunci sesi, dan sebagainya. Catatan parameter ini dapat berotasi atau berubah setelah sesi rentang berakhir dan perlu 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, lihat RangingCapabilities.

Aplikasi tidak menerima laporan jarak 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 metode Scrambled Urutan Stempel Waktu (STS). STS yang disediakan lebih aman daripada STS statis konfigurasi Anda. STS yang disediakan didukung di semua perangkat yang mendukung UWB yang berjalan Android 14 atau yang lebih baru.

Kategori ancaman STS Statis STS yang dilarang
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. Berikan 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 baru dan perangkat tersebut mendukung UWB menggunakan PackageManager#hasSystemFeature("android.hardware.uwb").
  2. Jika berkisar antara perangkat IoT, pastikan perangkat tersebut adalah FiRa MAC 1.3 mematuhi kebijakan.
  3. Temukan perangkat peer yang mendukung UWB menggunakan mekanisme OOB pilihan Anda, seperti BluetoothLeScanner
  4. Tukar parameter rentang menggunakan mekanisme OOB yang 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 berada di latar depan aplikasi atau layanan, kecuali jika rentang latar belakang didukung seperti yang digambarkan 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 UWB Jetpack, lihat contoh aplikasi di GitHub. Aplikasi contoh ini mencakup validasi kompatibilitas UWB di perangkat Android, mengaktifkan proses penemuan menggunakan mekanisme OOB, dan menyiapkan UWB di antara dua perangkat yang mendukung UWB. Contoh ini juga mencakup kasus penggunaan kontrol perangkat dan berbagi media.

Kisaran UWB

Contoh kode ini memulai dan mengakhiri UWB ranging 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 Java dengan klien besar. Library ini menyediakan cara untuk mendapatkan hasil rentang sebagai 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 SDK pihak ketiga dan perangkat partner yang didukung.

Perangkat seluler yang mendukung UWB

Mulai Maret 2024, perangkat ini 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 terbalik untuk kolom alamat MAC dan ID vendor STS statis

Di Android 13 dan yang lebih rendah, stack UWB Android salah membalik byte urutan 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) untuk menyatakan secara eksplisit bahwa kolom- kolom ini harus diperlakukan sebagai array.

Masalah ini akan diperbaiki melalui update GMS Core dalam rilis 2320XXXX. Agar sesuai dengan perangkat Android mulai saat itu, vendor IOT perlu memodifikasi implementasi Anda untuk menghindari pembatalan urutan byte pada kolom-kolom ini.