Giao tiếp băng tần siêu rộng (UWB)

Giao tiếp băng tần siêu rộng là một công nghệ vô tuyến tập trung vào việc xác định phạm vi chính xác (đo lường vị trí với độ chính xác 10 cm) giữa các thiết bị. Công nghệ vô tuyến này có thể sử dụng mật độ năng lượng thấp để đo lường phạm vi ngắn và thực hiện tín hiệu băng thông cao trên phần lớn phổ tần số vô tuyến. Băng thông của UWB lớn hơn 500 MHz (hoặc vượt quá 20% băng thông phân đoạn).

Đơn vị kiểm soát/Người tạo so với Người được kiểm soát/Người trả lời

Hoạt động giao tiếp UWB diễn ra giữa 2 thiết bị, trong đó một thiết bị là Đơn vị kiểm soát và thiết bị còn lại là Đơn vị kiểm soát. Đơn vị kiểm soát xác định kênh phức tạp (UwbComplexChannel) mà hai thiết bị sẽ chia sẻ và là trình khởi tạo, còn Người kiểm soát là người trả lời.

Một Đơn vị kiểm soát có thể xử lý nhiều Đơn vị kiểm soát, nhưng một Đơn vị kiểm soát chỉ có thể đăng ký một Đơn vị kiểm soát. Cả cấu hình Bộ điều khiển/Người khởi tạo và Người kiểm soát/Người trả lời đều được hỗ trợ.

Thông số khác nhau

Đơn vị kiểm soát và Đơn vị kiểm soát cần phải xác định nhau và truyền đạt các tham số có phạm vi để bắt đầu xác định phạm vi. Việc trao đổi này để các ứng dụng triển khai bằng cách sử dụng cơ chế ngoài băng tần (OOB) an toàn theo lựa chọn của họ, chẳng hạn như Bluetooth năng lượng thấp (BLE).

Các tham số có phạm vi bao gồm địa chỉ cục bộ, kênh phức tạp và khoá phiên, v.v. Xin lưu ý rằng các tham số này có thể xoay vòng hoặc thay đổi sau khi phiên phạm vi kết thúc và cần được giao tiếp lại để bắt đầu lại phạm vi.

Phạm vi nền

Ứng dụng chạy ở chế độ nền có thể bắt đầu một phiên ở phạm vi UWB nếu được thiết bị hỗ trợ. Để kiểm tra các chức năng của thiết bị, hãy xem RangingCapabilities.

Ứng dụng không nhận được phạm vi báo cáo khi chạy ở chế độ nền; ứng dụng sẽ nhận được nhiều loại báo cáo khi chuyển sang nền trước.

Cấu hình STS

Ứng dụng hoặc dịch vụ cung cấp khoá phiên cho mỗi phiên bằng cách sử dụng Trình tự dấu thời gian đã xáo trộn (STS). STS được cấp phép bảo mật hơn so với cấu hình STS tĩnh. STS được cấp phép được hỗ trợ trên tất cả các thiết bị hỗ trợ UWB và chạy Android 14 trở lên.

Danh mục mối đe doạ STS tĩnh STS được cung cấp
Không khí: Người quan sát thụ động Đã giảm nhẹ Đã giảm nhẹ
Không khí: Khuếch đại tín hiệu Đã giảm nhẹ Đã giảm nhẹ
Không khí: Tấn công chuyển tiếp/phát lại Dễ bị nhiễm Đã giảm nhẹ

Đối với STS được cấp phép:

  1. Sử dụng uwbConfigType trong RangingParameters có hỗ trợ STS được cấp phép.

  2. Cung cấp khoá 16 byte vào trường sessionKeyInfo.

Đối với STS tĩnh:

  1. Sử dụng uwbConfigType trong RangingParameters có hỗ trợ STS tĩnh.

  2. Cung cấp khoá 8 byte vào trường sessionKeyInfo.

Các bước

Để sử dụng API UWB, hãy làm theo các bước sau:

  1. Đảm bảo các thiết bị Android đang chạy Android 12 trở lên và hỗ trợ UWB bằng PackageManager#hasSystemFeature("android.hardware.uwb").
  2. Nếu bạn sử dụng các thiết bị IoT, hãy đảm bảo rằng các thiết bị đó tương thích với FiRa MAC 1.3.
  3. Khám phá các thiết bị ngang hàng có khả năng UWB bằng cơ chế OOB do bạn chọn, chẳng hạn như BluetoothLeScanner.
  4. Trao đổi nhiều tham số bằng cơ chế OOB bảo mật mà bạn chọn, chẳng hạn như BluetoothGatt.
  5. Nếu người dùng muốn dừng phiên, hãy huỷ phạm vi của phiên đó.

Giới hạn mức sử dụng

Các hạn chế sau đây sẽ áp dụng cho việc sử dụng UWB API:

  1. Ứng dụng khởi tạo các phiên mới ở phạm vi UWB phải là ứng dụng hoặc dịch vụ trên nền trước, trừ phi phạm vi nền được hỗ trợ như hình minh hoạ trước đó.
  2. Khi ứng dụng chuyển sang chạy ở chế độ nền (trong khi phiên đang diễn ra), ứng dụng có thể không nhận được các báo cáo khác nhau nữa. Tuy nhiên, phiên UWB sẽ tiếp tục được duy trì ở các lớp thấp hơn. Khi ứng dụng quay lại nền trước, các báo cáo khác nhau sẽ tiếp tục.

Mã mẫu

Ứng dụng mẫu

Để xem ví dụ toàn diện về cách sử dụng thư viện UWB Jetpack, hãy xem ứng dụng mẫu trên GitHub của chúng tôi. Ứng dụng mẫu này hướng dẫn cách xác thực khả năng tương thích với UWB trên một thiết bị Android, bật quá trình khám phá bằng cơ chế OOB, cũng như cách thiết lập UWB giữa 2 thiết bị hỗ trợ UWB. Tài liệu này cũng đề cập đến các trường hợp sử dụng tính năng điều khiển thiết bị và chia sẻ nội dung nghe nhìn.

Phạm vi UWB

Mã mẫu này sẽ bắt đầu và chấm dứt dải UWB cho một Người được kiểm soát:

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

Hỗ trợ RxJava3

Hiện đã có dịch vụ hỗ trợ Rxjava3 để giúp đạt được khả năng tương tác với các ứng dụng Java. Thư viện này cung cấp cách nhận các kết quả dưới dạng luồng Quan sát được hoặc Luồng có thể chạy (Flowable), đồng thời truy xuất UwbClientSessionScope dưới dạng một đối tượng Đơn (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();

Hỗ trợ hệ sinh thái

Sau đây là các thiết bị của đối tác và SDK của bên thứ ba được hỗ trợ.

Thiết bị di động có hỗ trợ UWB (băng tần siêu rộng)

Kể từ tháng 3 năm 2024, các thiết bị sau đây hỗ trợ thư viện Android UWB Jetpack:

Nhà cung cấp Mẫu thiết bị
Google Pixel 6 Pro, 7 Pro, 8 Pro, Fold, Máy tính bảng
Samsung Galaxy Note 20, S21+, S22+, S23+, S24+ Z Fold 2, 3, 4, 5

SDK của bên thứ ba

Kể từ tháng 4 năm 2023, các giải pháp dành cho đối tác này tương thích với thư viện Jetpack hiện tại.

Vấn đề đã biết: thứ tự byte bị đảo ngược cho các trường địa chỉ MAC và mã nhà cung cấp STS tĩnh

Trên Android 13 trở xuống, ngăn xếp UWB Android đảo ngược không chính xác thứ tự byte cho các trường sau:

  • Địa chỉ MAC của thiết bị
  • Địa chỉ MAC đích
  • Mã nhà cung cấp STS tĩnh

Sự đảo ngược thứ tự byte xảy ra vì ngăn xếp Android coi các trường này là giá trị chứ không phải mảng. Chúng tôi đang làm việc với FiRa để cập nhật thông số kỹ thuật của UCI (CR-1112) để tuyên bố rõ rằng các trường này nên được coi là mảng.

Vấn đề này sẽ được khắc phục thông qua bản cập nhật GMS Core trong bản phát hành 2320XXXX. Để tương thích với các thiết bị Android từ thời điểm đó trở đi, các nhà cung cấp IOT cần sửa đổi cách triển khai của bạn để tránh đảo ngược thứ tự byte của các trường này.