การสื่อสารย่านความถี่กว้างยิ่งยวดเป็นเทคโนโลยีวิทยุที่มุ่งเน้นการวัดระยะทางที่แม่นยำ (วัดตำแหน่งด้วยความแม่นยำ 10 ซม.) ระหว่างอุปกรณ์ เทคโนโลยีวิทยุนี้สามารถใช้ความหนาแน่นพลังงานต่ำสำหรับการวัดระยะสั้น และส่งสัญญาณแบนด์วิดท์สูงผ่านคลื่นความถี่วิทยุส่วนใหญ่ แบนด์วิดท์ของ UWB มากกว่า 500 MHz (หรือมากกว่า 20% ของแบนด์วิดท์เศษ)
ตัวควบคุม/ผู้เริ่มเทียบกับอุปกรณ์ที่ควบคุม/ผู้ตอบ
การสื่อสาร UWB เกิดขึ้นระหว่างอุปกรณ์ 2 เครื่อง โดยอุปกรณ์หนึ่งเป็นอุปกรณ์ควบคุมและอีกเครื่องหนึ่งเป็นอุปกรณ์ควบคุม ตัวควบคุมจะกำหนดแชแนลที่ซับซ้อน (UwbComplexChannel
) ที่อุปกรณ์ 2 เครื่องจะแชร์ และเป็นอุปกรณ์ที่เริ่มต้น ในขณะที่ตัวควบคุมจะเป็นผู้ตอบ
ตัวควบคุมสามารถจัดการตัวควบคุมได้หลายตัว แต่ตัวควบคุมจะสมัครใช้บริการได้กับตัวควบคุมเพียงตัวเดียวเท่านั้น ระบบรองรับทั้งการกำหนดค่าตัวควบคุม/ผู้เริ่มและตัวควบคุม/ผู้ตอบ
พารามิเตอร์การวัดระยะ
ตัวควบคุมและอุปกรณ์ควบคุมต้องระบุตัวตนกันและสื่อสารพารามิเตอร์การกำหนดช่วงเพื่อเริ่มการกําหนดช่วง การรับส่งนี้ขึ้นอยู่กับแอปพลิเคชันที่จะนำไปใช้งานโดยใช้กลไกการสื่อสารนอกแบนด์ (OOB) ที่ปลอดภัยตามที่เลือก เช่น บลูทูธพลังงานต่ำ (BLE)
พารามิเตอร์การกําหนดช่วงได้แก่ ที่อยู่ภายใน แชแนลที่ซับซ้อน และคีย์เซสชัน และอื่นๆ โปรดทราบว่าพารามิเตอร์เหล่านี้อาจหมุนเวียนหรือเปลี่ยนแปลงหลังจากเซสชันการวัดระยะสิ้นสุดลง และจำเป็นต้องสื่อสารอีกครั้งเพื่อเริ่มการวัดระยะใหม่
การวัดระยะในเบื้องหลัง
แอปที่ทำงานอยู่เบื้องหลังสามารถเริ่มเซสชันการวัดระยะ UWB ได้หากอุปกรณ์รองรับ หากต้องการตรวจสอบความสามารถของอุปกรณ์ โปรดดูที่ RangingCapabilities
แอปจะไม่รับรายงานช่วงสัญญาณเมื่อทำงานอยู่เบื้องหลัง แต่จะได้รับรายงานช่วงสัญญาณเมื่อย้ายไปอยู่เบื้องหน้า
การกำหนดค่า STS
แอปหรือบริการจะจัดสรรคีย์เซสชันสำหรับแต่ละเซสชันโดยใช้ลำดับการประทับเวลาแบบสับ (STS) STS ที่เตรียมไว้จะปลอดภัยกว่าการกำหนดค่า STS แบบคงที่ อุปกรณ์ที่เปิดใช้ UWB ทั้งหมดที่ใช้ Android 14 ขึ้นไปจะรองรับ STS ที่เตรียมไว้
หมวดหมู่ภัยคุกคาม | STS แบบคงที่ | STS ที่กําหนดค่าไว้ |
---|---|---|
อากาศ: ผู้สังเกตการณ์แบบไม่โต้ตอบ | ลดลงแล้ว | ลดลงแล้ว |
อากาศ: การขยายสัญญาณ | ลดลงแล้ว | ลดลงแล้ว |
อากาศ: การโจมตีแบบเล่นซ้ำ/รีเลย์ | เสี่ยง | ลดลงแล้ว |
สำหรับ STS ที่จัดสรรแล้ว ให้ทำดังนี้
ใช้
uwbConfigType
ในRangingParameters
ที่รองรับ STS ที่เตรียมไว้ระบุคีย์ 16 ไบต์ในช่อง
sessionKeyInfo
สำหรับ STS แบบคงที่
ใช้
uwbConfigType
ในRangingParameters
ที่รองรับ STS แบบคงที่ระบุคีย์ 8 ไบต์ในช่อง
sessionKeyInfo
จำนวนก้าว
หากต้องการใช้ UWB API ให้ทำตามขั้นตอนต่อไปนี้
- ตรวจสอบว่าอุปกรณ์ Android ที่ใช้ Android 12 ขึ้นไปและรองรับ UWB โดยใช้
PackageManager#hasSystemFeature("android.hardware.uwb")
- หากทำการวัดระยะกับอุปกรณ์ IoT โปรดตรวจสอบว่าอุปกรณ์ดังกล่าวเป็นไปตามข้อกำหนด FiRa MAC 1.3
- ค้นหาอุปกรณ์ที่รองรับ UWB โดยใช้กลไก OOB ที่คุณเลือก เช่น
BluetoothLeScanner
- แลกเปลี่ยนพารามิเตอร์การวัดระยะโดยใช้กลไก OOB ที่ปลอดภัยซึ่งคุณเลือก เช่น
BluetoothGatt
- หากผู้ใช้ต้องการหยุดเซสชัน ให้ยกเลิกขอบเขตของเซสชัน
ข้อจำกัดการใช้งาน
ข้อจำกัดต่อไปนี้มีผลกับการใช้ UWB API
- แอปที่เริ่มเซสชันการวัดระยะ UWB ใหม่ต้องเป็นแอปหรือบริการที่ทำงานอยู่เบื้องหน้า เว้นแต่ว่าอุปกรณ์จะรองรับการวัดระยะในเบื้องหลังตามที่แสดงไว้ก่อนหน้านี้
- เมื่อแอปย้ายไปยังเบื้องหลัง (ขณะที่เซสชันยังดำเนินอยู่) แอปอาจไม่ได้รับการรายงานช่วงอีกต่อไป อย่างไรก็ตาม เซสชัน UWB จะยังคงได้รับการดูแลรักษาในเลเยอร์ล่าง เมื่อแอปกลับมาที่เบื้องหน้า รายงานช่วงสัญญาณจะกลับมาทำงานต่อ
ตัวอย่างโค้ด
แอปตัวอย่าง
ดูตัวอย่างการใช้งาน UWB Jetpack Library ตั้งแต่ต้นจนจบได้ที่แอปพลิเคชันตัวอย่างใน GitHub แอปตัวอย่างนี้ครอบคลุมการตรวจสอบความเข้ากันได้ของ UWB ในอุปกรณ์ Android, การเปิดใช้กระบวนการค้นหาโดยใช้กลไก OOB และการตั้งค่า UWB ระหว่างอุปกรณ์ 2 เครื่องที่รองรับ UWB ตัวอย่างนี้ยังครอบคลุม Use Case การควบคุมอุปกรณ์และการแชร์สื่อด้วย
การกำหนดระยะ UWB
โค้ดตัวอย่างนี้จะเริ่มต้นและสิ้นสุดการวัดระยะ UWB สำหรับอุปกรณ์ที่ควบคุม
// 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
ตอนนี้เรารองรับ Rxjava3 เพื่อช่วยในการทํางานร่วมกันกับไคลเอ็นต์ Java แล้ว ไลบรารีนี้ให้วิธีรับผลลัพธ์ช่วงเป็นสตรีม Observable หรือ Flowable และดึงข้อมูล UwbClientSessionScope เป็นออบเจ็กต์เดี่ยว
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();
การรองรับระบบนิเวศ
อุปกรณ์ของพาร์ทเนอร์และ SDK ของบุคคลที่สามที่รองรับมีดังนี้
อุปกรณ์เคลื่อนที่ที่เปิดใช้ UWB
อุปกรณ์ต่อไปนี้รองรับไลบรารี Jetpack UWB ของ Android ตั้งแต่เดือนมกราคม 2025
ตัวแทนจำหน่ายรายย่อย | รุ่นอุปกรณ์ |
---|---|
Pixel Pro (6 Pro ขึ้นไป), Fold, Tablet | |
Motorola | Edge 50 Ultra |
Samsung | Galaxy Note 20, Galaxy Plus และ Ultra (S21 ขึ้นไป), Galaxy Z Fold (Fold2 ขึ้นไป) |
หมายเหตุ: อุปกรณ์ทั้งหมดรองรับการวัดระยะ UWB เบื้องหลัง ยกเว้นอุปกรณ์ต่อไปนี้
- Pixel 6 Pro และ Pixel 7 Pro
- โทรศัพท์ Samsung ที่ใช้ Android 13 หรือต่ำกว่า
- โทรศัพท์ Samsung จีนที่ใช้ Android 14 หรือต่ำกว่า
SDK ของบุคคลที่สาม
ตั้งแต่เดือนเมษายน 2023 โซลูชันของพาร์ทเนอร์เหล่านี้จะใช้งานร่วมกับไลบรารี Jetpack ปัจจุบันได้
- ชุดพัฒนาซอฟต์แวร์ UWB ของ Estimote
- Mobile Knowledge MK UWB Kit Mobile Edition 2.0
ปัญหาที่ทราบ: ลำดับไบต์กลับกันสำหรับช่องที่อยู่ MAC และรหัสผู้ให้บริการ STS แบบคงที่
ใน Android 13 และต่ำกว่า สแต็ก UWB ของ Android จะกลับลําดับไบต์ของช่องต่อไปนี้อย่างไม่ถูกต้อง
- ที่อยู่ MAC ของอุปกรณ์
- ที่อยู่ MAC ปลายทาง
- รหัสผู้ให้บริการ STS แบบคงที่
การเปลี่ยนลำดับไบต์เกิดขึ้นเนื่องจากสแต็ก Android ถือว่าช่องเหล่านี้เป็นค่า ไม่ใช่อาร์เรย์ เรากำลังดำเนินการร่วมกับ FiRa เพื่ออัปเดตข้อกำหนด UCI (CR-1112) เพื่อระบุอย่างชัดเจนว่าควรถือว่าช่องเหล่านี้เป็นอาร์เรย์
ปัญหานี้จะได้รับการแก้ไขผ่านการอัปเดต GMS Core ในรุ่น 2320XXXX
ผู้ให้บริการ IOT จะต้องแก้ไขการใช้งานของคุณเพื่อไม่ให้การเรียงลำดับไบต์ของช่องเหล่านี้กลับกัน เพื่อให้เป็นไปตามข้อกำหนดของอุปกรณ์ Android นับจากจุดนั้นเป็นต้นไป