summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-09-08 13:50:34 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-09-08 13:50:34 +0000
commitb47c97252051f824925c1c87fde585c23fbbca7e (patch)
tree984aa600610ef38f9a3bbe5fdbf068db7adcc5d6
parent4ebcfc59b5055a1ce221f0153ee00a36b4771e9a (diff)
parent5e4b464efc8f0e27810e4db3dc1ecb907587b87b (diff)
downloaduwb-android13-mainline-go-sdkext-release.tar.gz
Snap for 8756029 from 5e4b464efc8f0e27810e4db3dc1ecb907587b87b to mainline-go-sdkext-releaseaml_go_sdk_330810000android13-mainline-go-sdkext-release
Change-Id: I8566b033051a91e255eaf1e49d4292aa9a2fd0ab
-rw-r--r--DIR_METADATA4
-rw-r--r--OWNERS3
-rw-r--r--OWNERS_chromeos6
-rw-r--r--src/fuzz/fuzzer.rs4
-rw-r--r--src/rust/adaptation/mod.rs3
-rw-r--r--src/rust/event_manager/mod.rs15
-rw-r--r--src/rust/uci_hal_android/uci_hal_android.rs26
-rw-r--r--src/rust/uwb_core/Cargo.toml9
-rw-r--r--src/rust/uwb_core/examples/main.rs88
-rw-r--r--src/rust/uwb_core/rustfmt.toml1
-rw-r--r--src/rust/uwb_core/src/service.rs5
-rw-r--r--src/rust/uwb_core/src/service/mock_uwb_service_callback.rs130
-rw-r--r--src/rust/uwb_core/src/service/uwb_service.rs376
-rw-r--r--src/rust/uwb_core/src/service/uwb_service_builder.rs60
-rw-r--r--src/rust/uwb_core/src/session/session_manager.rs99
-rw-r--r--src/rust/uwb_core/src/uci.rs2
-rw-r--r--src/rust/uwb_core/src/uci/mock_uci_manager.rs6
-rw-r--r--src/rust/uwb_core/src/uci/notification.rs24
-rw-r--r--src/rust/uwb_core/src/uci/response.rs4
-rw-r--r--src/rust/uwb_core/src/uci/uci_manager.rs4
-rw-r--r--src/rust/uwb_core/src/uci/uci_manager_sync.rs344
-rw-r--r--src/rust/uwb_uci_packets/Cargo.toml1
-rw-r--r--src/rust/uwb_uci_packets/uci_packets.pdl67
23 files changed, 300 insertions, 981 deletions
diff --git a/DIR_METADATA b/DIR_METADATA
deleted file mode 100644
index 6021b9b..0000000
--- a/DIR_METADATA
+++ /dev/null
@@ -1,4 +0,0 @@
-buganizer {
- component_id: 1042770 # Android > Android OS & Apps > Systems > UWB
-}
-team_email: "android-uwb-team@google.com"
diff --git a/OWNERS b/OWNERS
index d781032..4c4edca 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1 @@
include platform/packages/modules/Uwb:/OWNERS
-
-# This repo is shared with ChromeOS, so add the ChromeOS UWB team as the owners.
-include /OWNERS_chromeos
diff --git a/OWNERS_chromeos b/OWNERS_chromeos
deleted file mode 100644
index f95e0d2..0000000
--- a/OWNERS_chromeos
+++ /dev/null
@@ -1,6 +0,0 @@
-# ChromeOS UWB team
-akahuang@google.com
-alainmichaud@google.com
-phuleh@google.com
-ningyuan@google.com
-yanivt@google.com
diff --git a/src/fuzz/fuzzer.rs b/src/fuzz/fuzzer.rs
index a40346a..78b7748 100644
--- a/src/fuzz/fuzzer.rs
+++ b/src/fuzz/fuzzer.rs
@@ -84,7 +84,6 @@ struct ShortAddressMeasurement {
aoa_destination_elevation: u16,
aoa_destination_elevation_fom: u8,
slot_index: u8,
- rssi: u8,
}
impl ShortAddressMeasurement {
@@ -103,7 +102,6 @@ impl ShortAddressMeasurement {
aoa_destination_elevation: self.aoa_destination_elevation,
aoa_destination_elevation_fom: self.aoa_destination_elevation_fom,
slot_index: self.slot_index,
- rssi: self.rssi,
})
}
}
@@ -123,7 +121,6 @@ struct ExtendedAddressMeasurement {
aoa_destination_elevation: u16,
aoa_destination_elevation_fom: u8,
slot_index: u8,
- rssi: u8,
}
impl ExtendedAddressMeasurement {
@@ -142,7 +139,6 @@ impl ExtendedAddressMeasurement {
aoa_destination_elevation: self.aoa_destination_elevation,
aoa_destination_elevation_fom: self.aoa_destination_elevation_fom,
slot_index: self.slot_index,
- rssi: self.rssi,
})
}
}
diff --git a/src/rust/adaptation/mod.rs b/src/rust/adaptation/mod.rs
index 30728c3..0ffc014 100644
--- a/src/rust/adaptation/mod.rs
+++ b/src/rust/adaptation/mod.rs
@@ -86,8 +86,7 @@ impl IUwbClientCallbackAsyncServer for UwbClientCallback {
async fn get_hal_service() -> Result<Strong<dyn IUwbChipAsync<Tokio>>> {
let service_name: &str = "android.hardware.uwb.IUwb/default";
- let i_uwb: Strong<dyn IUwbAsync<Tokio>> =
- binder_tokio::wait_for_interface(service_name).await?;
+ let i_uwb: Strong<dyn IUwbAsync<Tokio>> = binder_tokio::get_interface(service_name).await?;
let chip_names = i_uwb.getChips().await?;
if chip_names.is_empty() {
return Err(UwbErr::UwbStatus(UwbStatus::FAILED));
diff --git a/src/rust/event_manager/mod.rs b/src/rust/event_manager/mod.rs
index 81ecde4..26633d1 100644
--- a/src/rust/event_manager/mod.rs
+++ b/src/rust/event_manager/mod.rs
@@ -243,7 +243,7 @@ impl EventManagerImpl {
) -> Result<JObject<'a>> {
env.new_object(
two_way_measurement_class,
- "([BIIIIIIIIIIIII)V",
+ "([BIIIIIIIIIIII)V",
&[
JValue::Object(JObject::from(mac_address_java)),
JValue::Int(0),
@@ -258,7 +258,6 @@ impl EventManagerImpl {
JValue::Int(0),
JValue::Int(0),
JValue::Int(0),
- JValue::Int(0),
],
)
}
@@ -279,7 +278,7 @@ impl EventManagerImpl {
env.set_byte_array_region(mac_address_java, 0, &mac_address_arr_i8)?;
env.new_object(
two_way_measurement_class,
- "([BIIIIIIIIIIIII)V",
+ "([BIIIIIIIIIIII)V",
&[
JValue::Object(JObject::from(mac_address_java)),
JValue::Int(two_way_measurement.status.to_i32().ok_or_else(|| {
@@ -340,10 +339,6 @@ impl EventManagerImpl {
error!("Failed converting slot index to i32");
Error::JniCall(JniError::Unknown)
})?),
- JValue::Int(two_way_measurement.rssi.to_i32().ok_or_else(|| {
- error!("Failed converting rssi to i32");
- Error::JniCall(JniError::Unknown)
- })?),
],
)
}
@@ -364,7 +359,7 @@ impl EventManagerImpl {
env.set_byte_array_region(mac_address_java, 0, &mac_address_arr_i8)?;
env.new_object(
two_way_measurement_class,
- "([BIIIIIIIIIIIII)V",
+ "([BIIIIIIIIIIII)V",
&[
JValue::Object(JObject::from(mac_address_java)),
JValue::Int(two_way_measurement.status.to_i32().ok_or_else(|| {
@@ -425,10 +420,6 @@ impl EventManagerImpl {
error!("Failed converting slot index to i32");
Error::JniCall(JniError::Unknown)
})?),
- JValue::Int(two_way_measurement.rssi.to_i32().ok_or_else(|| {
- error!("Failed converting rssi to i32");
- Error::JniCall(JniError::Unknown)
- })?),
],
)
}
diff --git a/src/rust/uci_hal_android/uci_hal_android.rs b/src/rust/uci_hal_android/uci_hal_android.rs
index 4c638a9..1b3d297 100644
--- a/src/rust/uci_hal_android/uci_hal_android.rs
+++ b/src/rust/uci_hal_android/uci_hal_android.rs
@@ -129,7 +129,7 @@ impl IUwbClientCallbackAsyncServer for RawUciCallback {
/// Implentation of UciHal trait for Android.
#[derive(Default)]
pub struct UciHalAndroid {
- // Has a copy of uci_rsp_ntf_sender via RawUciCallback.
+ // Has a copy of msg_sender via RawUciCallback.
hal_uci_recipient: Option<Strong<dyn IUwbChipAsync<Tokio>>>,
hal_death_recipient: Option<Arc<Mutex<DeathRecipient>>>,
hal_close_result_receiver: Option<mpsc::Receiver<Result<()>>>,
@@ -148,7 +148,7 @@ impl UciHal for UciHalAndroid {
/// Open the UCI HAL and power on the UWBS.
async fn open(
&mut self,
- uci_rsp_ntf_sender: mpsc::UnboundedSender<RawUciMessage>,
+ msg_sender: mpsc::UnboundedSender<RawUciMessage>,
) -> UwbCoreResult<()> {
// Returns error if UciHalAndroid is already open.
if self.hal_uci_recipient.is_some() {
@@ -157,9 +157,10 @@ impl UciHal for UciHalAndroid {
// Get hal service.
let service_name = "android.hardware.uwb.IUwb/default";
- let i_uwb: Strong<dyn IUwbAsync<Tokio>> = binder_tokio::wait_for_interface(service_name)
- .await
- .map_err(|e| UwbCoreError::from(Error::from(e)))?;
+ let i_uwb: Strong<dyn IUwbAsync<Tokio>> =
+ binder_tokio::get_interface(service_name)
+ .await
+ .map_err(|e| UwbCoreError::from(Error::from(e)))?;
let chip_names = i_uwb.getChips().await.map_err(|e| UwbCoreError::from(Error::from(e)))?;
let i_uwb_chip = i_uwb
.getChip(&chip_names[0])
@@ -169,9 +170,9 @@ impl UciHal for UciHalAndroid {
// If the binder object unexpectedly goes away (typically because its hosting process has
// been killed), then the `DeathRecipient`'s callback will be called.
- let uci_rsp_ntf_sender_clone = uci_rsp_ntf_sender.clone();
+ let msg_sender_clone = msg_sender.clone();
let mut bare_death_recipient = DeathRecipient::new(move || {
- send_device_state_error_notification(&uci_rsp_ntf_sender_clone).unwrap_or_else(|e| {
+ send_device_state_error_notification(&msg_sender_clone).unwrap_or_else(|e| {
error!("Error sending device state error notification: {:?}", e);
});
});
@@ -180,22 +181,15 @@ impl UciHal for UciHalAndroid {
.link_to_death(&mut bare_death_recipient)
.map_err(|e| UwbCoreError::from(Error::from(e)))?;
- // Connect callback to uci_rsp_ntf_sender.
+ // Connect callback to msg_sender.
let (hal_open_result_sender, mut hal_open_result_receiver) = mpsc::channel::<Result<()>>(1);
let (hal_close_result_sender, hal_close_result_receiver) = mpsc::channel::<Result<()>>(1);
let m_cback = BnUwbClientCallback::new_async_binder(
- RawUciCallback::new(
- uci_rsp_ntf_sender,
- hal_open_result_sender,
- hal_close_result_sender,
- ),
+ RawUciCallback::new(msg_sender, hal_open_result_sender, hal_close_result_sender),
TokioRuntime(Handle::current()),
BinderFeatures::default(),
);
i_uwb_chip.open(&m_cback).await.map_err(|e| UwbCoreError::from(Error::from(e)))?;
-
- // Initialize core and wait for POST_INIT_CPLT.
- i_uwb_chip.coreInit().await.map_err(|e| UwbCoreError::from(Error::from(e)))?;
match hal_open_result_receiver.recv().await {
Some(Ok(())) => {
self.hal_uci_recipient.replace(i_uwb_chip);
diff --git a/src/rust/uwb_core/Cargo.toml b/src/rust/uwb_core/Cargo.toml
index c9294f1..a22cd90 100644
--- a/src/rust/uwb_core/Cargo.toml
+++ b/src/rust/uwb_core/Cargo.toml
@@ -4,14 +4,15 @@ version = "0.0.1"
edition = "2018"
[dependencies]
-async-trait = "0.1.32"
+async-trait = "0.1.52"
bytes = "1.1.0"
+num-traits = "0.2.14"
log = "0.4.14"
-num-traits = "0.2.12"
thiserror = "1.0.30"
-tokio = { version = "1.14.0", features = ["macros", "rt", "rt-multi-thread", "sync", "time"] }
+tokio = {version = "1.14.0", features = ["sync", "rt", "macros", "time"]}
-uwb_uci_packets = { path = "../uwb_uci_packets" } # provided by ebuild
+uwb_uci_packets = { path = "../uwb_uci_packets"}
[dev-dependencies]
env_logger = "0.9.0"
+tokio = {version = "1.14.0", features = ["rt-multi-thread"]}
diff --git a/src/rust/uwb_core/examples/main.rs b/src/rust/uwb_core/examples/main.rs
index 4962820..2a49b71 100644
--- a/src/rust/uwb_core/examples/main.rs
+++ b/src/rust/uwb_core/examples/main.rs
@@ -19,9 +19,8 @@ use log::debug;
use tokio::sync::mpsc;
use uwb_core::error::{Error as UwbError, Result as UwbResult};
-use uwb_core::params::uci_packets::{DeviceState, ReasonCode, SessionId, SessionState};
-use uwb_core::service::{UwbServiceBuilder, UwbServiceCallback};
-use uwb_core::uci::{RawUciMessage, SessionRangeData, UciHal};
+use uwb_core::service::{UwbNotification, UwbServiceBuilder};
+use uwb_core::uci::{RawUciMessage, UciHal};
/// A placeholder implementation for UciHal.
struct UciHalImpl {}
@@ -41,50 +40,55 @@ impl UciHal for UciHalImpl {
}
}
-/// A placeholder implementation for UwbServiceCallback.
-struct UwbServiceCallbackImpl {}
-impl UwbServiceCallback for UwbServiceCallbackImpl {
- fn on_service_reset(&mut self, success: bool) {
- debug!("UwbService is reset, success: {}", success);
- }
-
- fn on_uci_device_status_changed(&mut self, state: DeviceState) {
- debug!("UCI device status: {:?}", state);
- }
-
- fn on_session_state_changed(
- &mut self,
- session_id: SessionId,
- session_state: SessionState,
- reason_code: ReasonCode,
- ) {
- debug!(
- "Session {:?}'s state is changed to {:?}, reason: {:?}",
- session_id, session_state, reason_code
- );
- }
-
- fn on_range_data_received(&mut self, session_id: SessionId, range_data: SessionRangeData) {
- debug!("Received range data {:?} from Session {:?}", range_data, session_id);
- }
+#[tokio::main]
+async fn main() {
+ let _ = env_logger::init();
- fn on_vendor_notification_received(&mut self, gid: u32, oid: u32, payload: Vec<u8>) {
- debug!("Received vendor notification: gid={}, oid={}, payload={:?}", gid, oid, payload);
- }
-}
+ // Initialize the UWB service.
+ let (notf_sender, mut notf_receiver) = mpsc::unbounded_channel();
+ let mut service =
+ UwbServiceBuilder::new().uci_hal(UciHalImpl {}).notf_sender(notf_sender).build().unwrap();
-fn main() {
- env_logger::init();
+ // Handle the notifications from UWB service at another tokio task.
+ tokio::spawn(async move {
+ while let Some(notf) = notf_receiver.recv().await {
+ // Enumerate the notification for backward-compatibility.
+ // WARNING: Modifying or removing the current fields are prohibited in general,
+ // unless we could confirm that there is no client using the modified field.
+ match notf {
+ UwbNotification::ServiceReset { success } => {
+ debug!("UwbService is reset, success: {}", success);
+ }
+ UwbNotification::UciDeviceStatus(state) => {
+ debug!("UCI device status: {:?}", state);
+ }
+ UwbNotification::SessionState { session_id, session_state, reason_code } => {
+ debug!(
+ "Session {:?}'s state is changed to {:?}, reason: {:?}",
+ session_id, session_state, reason_code
+ );
+ }
+ UwbNotification::RangeData { session_id, range_data } => {
+ debug!("Received range data {:?} from Session {:?}", range_data, session_id);
+ }
+ UwbNotification::VendorNotification { gid, oid, payload } => {
+ debug!(
+ "Received vendor notification: gid={}, oid={}, payload={:?}",
+ gid, oid, payload
+ );
+ }
- // Initialize the UWB service.
- let mut service = UwbServiceBuilder::new()
- .callback(UwbServiceCallbackImpl {})
- .uci_hal(UciHalImpl {})
- .build()
- .unwrap();
+ // UwbNotification is non_exhaustive so we need to add a wild branch here.
+ // With this wild branch, adding a new enum field doesn't break the build.
+ _ => {
+ debug!("Received unknown notifitication: {:?}", notf);
+ }
+ }
+ }
+ });
// Call the public methods of UWB service under tokio runtime.
- let result: UwbResult<()> = service.enable();
+ let result: UwbResult<()> = service.enable().await;
// Enumerate the error code for backward-compatibility.
// WARNING: Modifying or removing the current fields are prohibited in general,
diff --git a/src/rust/uwb_core/rustfmt.toml b/src/rust/uwb_core/rustfmt.toml
index 5831856..12c133b 100644
--- a/src/rust/uwb_core/rustfmt.toml
+++ b/src/rust/uwb_core/rustfmt.toml
@@ -1,4 +1,3 @@
edition = "2018"
use_small_heuristics = "Max"
newline_style = "Unix"
-max_width = 100 \ No newline at end of file
diff --git a/src/rust/uwb_core/src/service.rs b/src/rust/uwb_core/src/service.rs
index a929196..69cde94 100644
--- a/src/rust/uwb_core/src/service.rs
+++ b/src/rust/uwb_core/src/service.rs
@@ -17,9 +17,6 @@
pub mod uwb_service;
pub mod uwb_service_builder;
-#[cfg(test)]
-mod mock_uwb_service_callback;
-
// Re-export the public elements.
-pub use uwb_service::{UwbService, UwbServiceCallback};
+pub use uwb_service::{UwbNotification, UwbService};
pub use uwb_service_builder::UwbServiceBuilder;
diff --git a/src/rust/uwb_core/src/service/mock_uwb_service_callback.rs b/src/rust/uwb_core/src/service/mock_uwb_service_callback.rs
deleted file mode 100644
index 12f182f..0000000
--- a/src/rust/uwb_core/src/service/mock_uwb_service_callback.rs
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2022, The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-use std::collections::VecDeque;
-use std::sync::{Arc, Mutex};
-
-use tokio::sync::Notify;
-use tokio::time::{timeout, Duration};
-
-use crate::params::{DeviceState, ReasonCode, SessionId, SessionState};
-use crate::service::uwb_service::UwbServiceCallback;
-use crate::uci::SessionRangeData;
-
-#[derive(Clone, Default)]
-pub(crate) struct MockUwbServiceCallback {
- expected_calls: Arc<Mutex<VecDeque<ExpectedCall>>>,
- expect_call_consumed: Arc<Notify>,
-}
-
-impl MockUwbServiceCallback {
- pub fn new() -> Self {
- Default::default()
- }
-
- pub fn expect_on_service_reset(&mut self, success: bool) {
- self.push_expected_call(ExpectedCall::ServiceReset { success });
- }
-
- pub fn expect_on_uci_device_status_changed(&mut self, state: DeviceState) {
- self.push_expected_call(ExpectedCall::UciDeviceStatus { state });
- }
-
- pub fn expect_on_session_state_changed(
- &mut self,
- session_id: SessionId,
- session_state: SessionState,
- reason_code: ReasonCode,
- ) {
- self.push_expected_call(ExpectedCall::SessionState {
- session_id,
- session_state,
- reason_code,
- });
- }
-
- pub fn expect_on_range_data_received(
- &mut self,
- session_id: SessionId,
- range_data: SessionRangeData,
- ) {
- self.push_expected_call(ExpectedCall::RangeData { session_id, range_data });
- }
-
- pub fn expect_on_vendor_notification_received(&mut self, gid: u32, oid: u32, payload: Vec<u8>) {
- self.push_expected_call(ExpectedCall::VendorNotification { gid, oid, payload });
- }
-
- pub async fn wait_expected_calls_done(&mut self) -> bool {
- while !self.expected_calls.lock().unwrap().is_empty() {
- if timeout(Duration::from_secs(1), self.expect_call_consumed.notified()).await.is_err()
- {
- return false;
- }
- }
- true
- }
-
- fn push_expected_call(&mut self, call: ExpectedCall) {
- self.expected_calls.lock().unwrap().push_back(call);
- }
-
- fn pop_expected_call(&mut self) -> ExpectedCall {
- let call = self.expected_calls.lock().unwrap().pop_front().unwrap();
- self.expect_call_consumed.notify_one();
- call
- }
-}
-
-impl UwbServiceCallback for MockUwbServiceCallback {
- fn on_service_reset(&mut self, success: bool) {
- assert_eq!(self.pop_expected_call(), ExpectedCall::ServiceReset { success });
- }
-
- fn on_uci_device_status_changed(&mut self, state: DeviceState) {
- assert_eq!(self.pop_expected_call(), ExpectedCall::UciDeviceStatus { state });
- }
-
- fn on_session_state_changed(
- &mut self,
- session_id: SessionId,
- session_state: SessionState,
- reason_code: ReasonCode,
- ) {
- assert_eq!(
- self.pop_expected_call(),
- ExpectedCall::SessionState { session_id, session_state, reason_code }
- );
- }
-
- fn on_range_data_received(&mut self, session_id: SessionId, range_data: SessionRangeData) {
- assert_eq!(self.pop_expected_call(), ExpectedCall::RangeData { session_id, range_data });
- }
-
- fn on_vendor_notification_received(&mut self, gid: u32, oid: u32, payload: Vec<u8>) {
- assert_eq!(
- self.pop_expected_call(),
- ExpectedCall::VendorNotification { gid, oid, payload }
- );
- }
-}
-
-#[derive(PartialEq, Debug)]
-pub(crate) enum ExpectedCall {
- ServiceReset { success: bool },
- UciDeviceStatus { state: DeviceState },
- SessionState { session_id: SessionId, session_state: SessionState, reason_code: ReasonCode },
- RangeData { session_id: SessionId, range_data: SessionRangeData },
- VendorNotification { gid: u32, oid: u32, payload: Vec<u8> },
-}
diff --git a/src/rust/uwb_core/src/service/uwb_service.rs b/src/rust/uwb_core/src/service/uwb_service.rs
index 81cd52b..c790654 100644
--- a/src/rust/uwb_core/src/service/uwb_service.rs
+++ b/src/rust/uwb_core/src/service/uwb_service.rs
@@ -15,7 +15,6 @@
//! This module defines the UwbService and its related components.
use log::{debug, error, warn};
-use tokio::runtime::Runtime;
use tokio::sync::{mpsc, oneshot};
use crate::error::{Error, Result};
@@ -28,170 +27,173 @@ use crate::session::session_manager::{SessionManager, SessionNotification};
use crate::uci::notification::{CoreNotification, SessionRangeData};
use crate::uci::uci_manager::UciManager;
-/// The callback of the UwbService which is used to send the notification to UwbService's caller.
-pub trait UwbServiceCallback: 'static + Send {
+/// The notification that is sent from UwbService to its caller.
+#[non_exhaustive] // Adding new enum fields doesn't break the downstream build.
+#[derive(Debug, PartialEq)]
+pub enum UwbNotification {
/// Notify the UWB service has been reset due to internal error. All the sessions are closed.
- /// `success` indicates the reset is successful or not.
- fn on_service_reset(&mut self, success: bool);
-
+ ServiceReset {
+ /// Indicate the reset is successful or not.
+ success: bool,
+ },
/// Notify the status of the UCI device.
- fn on_uci_device_status_changed(&mut self, state: DeviceState);
-
+ UciDeviceStatus(DeviceState),
/// Notify the state of the session with the id |session_id| is changed.
- fn on_session_state_changed(
- &mut self,
+ SessionState {
+ /// The identifier of the session.
session_id: SessionId,
+ /// The current state of the session.
session_state: SessionState,
+ /// The reason of the state change.
reason_code: ReasonCode,
- );
-
+ },
/// Notify the ranging data of the session with the id |session_id| is received.
- fn on_range_data_received(&mut self, session_id: SessionId, range_data: SessionRangeData);
-
+ RangeData {
+ /// The identifier of the ranging session.
+ session_id: SessionId,
+ /// The received range data.
+ range_data: SessionRangeData,
+ },
/// Notify the vendor notification is received.
- fn on_vendor_notification_received(&mut self, gid: u32, oid: u32, payload: Vec<u8>);
+ VendorNotification {
+ /// The group id of the message.
+ gid: u32,
+ /// The opcode of the message.
+ oid: u32,
+ /// The payload of the message.
+ payload: Vec<u8>,
+ },
}
/// The entry class (a.k.a top shim) of the core library. The class accepts requests from the
/// client, and delegates the requests to other components. It should provide the
/// backward-compatible interface for the client of the library.
pub struct UwbService {
- runtime: Runtime,
cmd_sender: mpsc::UnboundedSender<(Command, ResponseSender)>,
}
impl UwbService {
/// Create a new UwbService instance.
- pub(super) fn new<C: UwbServiceCallback, U: UciManager>(
- runtime: Runtime,
- callback: C,
+ pub(super) fn new<U: UciManager>(
+ notf_sender: mpsc::UnboundedSender<UwbNotification>,
uci_manager: U,
) -> Self {
let (cmd_sender, cmd_receiver) = mpsc::unbounded_channel();
- let mut actor = runtime
- .block_on(async move { UwbServiceActor::new(cmd_receiver, callback, uci_manager) });
- runtime.spawn(async move { actor.run().await });
+ let mut actor = UwbServiceActor::new(cmd_receiver, notf_sender, uci_manager);
+ tokio::spawn(async move { actor.run().await });
- Self { runtime, cmd_sender }
+ Self { cmd_sender }
}
/// Enable the UWB service.
- pub fn enable(&mut self) -> Result<()> {
- self.block_on_cmd(Command::Enable)?;
+ pub async fn enable(&mut self) -> Result<()> {
+ self.send_cmd(Command::Enable).await?;
Ok(())
}
/// Disable the UWB service.
- pub fn disable(&mut self) -> Result<()> {
- self.block_on_cmd(Command::Disable)?;
+ pub async fn disable(&mut self) -> Result<()> {
+ self.send_cmd(Command::Disable).await?;
Ok(())
}
/// Initialize a new ranging session with the given parameters.
- pub fn init_session(
+ pub async fn init_session(
&mut self,
session_id: SessionId,
session_type: SessionType,
params: AppConfigParams,
) -> Result<()> {
- self.block_on_cmd(Command::InitSession { session_id, session_type, params })?;
+ self.send_cmd(Command::InitSession { session_id, session_type, params }).await?;
Ok(())
}
/// Destroy the session.
- pub fn deinit_session(&mut self, session_id: SessionId) -> Result<()> {
- self.block_on_cmd(Command::DeinitSession { session_id })?;
+ pub async fn deinit_session(&mut self, session_id: SessionId) -> Result<()> {
+ self.send_cmd(Command::DeinitSession { session_id }).await?;
Ok(())
}
/// Start ranging of the session.
- pub fn start_ranging(&mut self, session_id: SessionId) -> Result<AppConfigParams> {
- match self.block_on_cmd(Command::StartRanging { session_id })? {
+ pub async fn start_ranging(&mut self, session_id: SessionId) -> Result<AppConfigParams> {
+ match self.send_cmd(Command::StartRanging { session_id }).await? {
Response::AppConfigParams(params) => Ok(params),
_ => panic!("start_ranging() should return AppConfigParams"),
}
}
/// Stop ranging.
- pub fn stop_ranging(&mut self, session_id: SessionId) -> Result<()> {
- self.block_on_cmd(Command::StopRanging { session_id })?;
+ pub async fn stop_ranging(&mut self, session_id: SessionId) -> Result<()> {
+ self.send_cmd(Command::StopRanging { session_id }).await?;
Ok(())
}
/// Reconfigure the parameters of the session.
- pub fn reconfigure(&mut self, session_id: SessionId, params: AppConfigParams) -> Result<()> {
- self.block_on_cmd(Command::Reconfigure { session_id, params })?;
+ pub async fn reconfigure(
+ &mut self,
+ session_id: SessionId,
+ params: AppConfigParams,
+ ) -> Result<()> {
+ self.send_cmd(Command::Reconfigure { session_id, params }).await?;
Ok(())
}
/// Update the list of the controlees to the ongoing session.
- pub fn update_controller_multicast_list(
+ pub async fn update_controller_multicast_list(
&mut self,
session_id: SessionId,
action: UpdateMulticastListAction,
controlees: Vec<Controlee>,
) -> Result<()> {
- self.block_on_cmd(Command::UpdateControllerMulticastList {
- session_id,
- action,
- controlees,
- })?;
+ self.send_cmd(Command::UpdateControllerMulticastList { session_id, action, controlees })
+ .await?;
Ok(())
}
/// Set the country code. Android-specific method.
- pub fn android_set_country_code(&mut self, country_code: CountryCode) -> Result<()> {
- self.block_on_cmd(Command::AndroidSetCountryCode { country_code })?;
+ pub async fn android_set_country_code(&mut self, country_code: CountryCode) -> Result<()> {
+ self.send_cmd(Command::AndroidSetCountryCode { country_code }).await?;
Ok(())
}
/// Get the power statistics. Android-specific method.
- pub fn android_get_power_stats(&mut self) -> Result<PowerStats> {
- match self.block_on_cmd(Command::AndroidGetPowerStats)? {
+ pub async fn android_get_power_stats(&mut self) -> Result<PowerStats> {
+ match self.send_cmd(Command::AndroidGetPowerStats).await? {
Response::PowerStats(stats) => Ok(stats),
_ => panic!("android_get_power_stats() should return PowerStats"),
}
}
/// Send a vendor-specific UCI message.
- pub fn send_vendor_cmd(
+ pub async fn send_vendor_cmd(
&mut self,
gid: u32,
oid: u32,
payload: Vec<u8>,
) -> Result<RawVendorMessage> {
- match self.block_on_cmd(Command::SendVendorCmd { gid, oid, payload })? {
+ match self.send_cmd(Command::SendVendorCmd { gid, oid, payload }).await? {
Response::RawVendorMessage(msg) => Ok(msg),
_ => panic!("send_vendor_cmd() should return RawVendorMessage"),
}
}
- /// Send the |cmd| to UwbServiceActor and wait until receiving the response.
- fn block_on_cmd(&self, cmd: Command) -> Result<Response> {
+ /// Send the |cmd| to UwbServiceActor.
+ async fn send_cmd(&self, cmd: Command) -> Result<Response> {
let (result_sender, result_receiver) = oneshot::channel();
self.cmd_sender.send((cmd, result_sender)).map_err(|cmd| {
error!("Failed to send cmd: {:?}", cmd.0);
Error::Unknown
})?;
-
- self.runtime.block_on(async move {
- result_receiver.await.unwrap_or_else(|e| {
- error!("Failed to receive the result for cmd: {:?}", e);
- Err(Error::Unknown)
- })
+ result_receiver.await.unwrap_or_else(|e| {
+ error!("Failed to receive the result for cmd: {:?}", e);
+ Err(Error::Unknown)
})
}
-
- /// Run an future task on the runtime. This method is only exposed for the testing.
- #[cfg(test)]
- fn block_on_for_testing<F: std::future::Future>(&self, future: F) -> F::Output {
- self.runtime.block_on(future)
- }
}
-struct UwbServiceActor<C: UwbServiceCallback, U: UciManager> {
+struct UwbServiceActor<U: UciManager> {
cmd_receiver: mpsc::UnboundedReceiver<(Command, ResponseSender)>,
- callback: C,
+ notf_sender: mpsc::UnboundedSender<UwbNotification>,
uci_manager: U,
session_manager: Option<SessionManager>,
core_notf_receiver: mpsc::UnboundedReceiver<CoreNotification>,
@@ -199,15 +201,15 @@ struct UwbServiceActor<C: UwbServiceCallback, U: UciManager> {
vendor_notf_receiver: mpsc::UnboundedReceiver<RawVendorMessage>,
}
-impl<C: UwbServiceCallback, U: UciManager> UwbServiceActor<C, U> {
+impl<U: UciManager> UwbServiceActor<U> {
fn new(
cmd_receiver: mpsc::UnboundedReceiver<(Command, ResponseSender)>,
- callback: C,
+ notf_sender: mpsc::UnboundedSender<UwbNotification>,
uci_manager: U,
) -> Self {
Self {
cmd_receiver,
- callback,
+ notf_sender,
uci_manager,
session_manager: None,
core_notf_receiver: mpsc::unbounded_channel().1,
@@ -342,7 +344,7 @@ impl<C: UwbServiceCallback, U: UciManager> UwbServiceActor<C, U> {
warn!("Received DeviceStateError notification, reset the service");
self.reset_service().await;
} else {
- self.callback.on_uci_device_status_changed(state);
+ let _ = self.notf_sender.send(UwbNotification::UciDeviceStatus(state));
}
}
CoreNotification::GenericError(_status) => {}
@@ -352,16 +354,25 @@ impl<C: UwbServiceCallback, U: UciManager> UwbServiceActor<C, U> {
async fn handle_session_notification(&mut self, notf: SessionNotification) {
match notf {
SessionNotification::SessionState { session_id, session_state, reason_code } => {
- self.callback.on_session_state_changed(session_id, session_state, reason_code);
+ let _ = self.notf_sender.send(UwbNotification::SessionState {
+ session_id,
+ session_state,
+ reason_code,
+ });
}
SessionNotification::RangeData { session_id, range_data } => {
- self.callback.on_range_data_received(session_id, range_data);
+ let _ =
+ self.notf_sender.send(UwbNotification::RangeData { session_id, range_data });
}
}
}
async fn handle_vendor_notification(&mut self, notf: RawVendorMessage) {
- self.callback.on_vendor_notification_received(notf.gid, notf.oid, notf.payload);
+ let _ = self.notf_sender.send(UwbNotification::VendorNotification {
+ gid: notf.gid,
+ oid: notf.oid,
+ payload: notf.payload,
+ });
}
async fn enable_service(&mut self) -> Result<()> {
@@ -405,7 +416,7 @@ impl<C: UwbServiceCallback, U: UciManager> UwbServiceActor<C, U> {
if result.is_err() {
error!("Failed to reset the service.");
}
- self.callback.on_service_reset(result.is_ok());
+ let _ = self.notf_sender.send(UwbNotification::ServiceReset { success: result.is_ok() });
}
}
@@ -460,35 +471,27 @@ type ResponseSender = oneshot::Sender<Result<Response>>;
mod tests {
use super::*;
use crate::params::uci_packets::{SessionState, SetAppConfigResponse, StatusCode};
- use crate::service::mock_uwb_service_callback::MockUwbServiceCallback;
- use crate::service::uwb_service_builder::default_runtime;
use crate::session::session_manager::test_utils::{
generate_params, range_data_notf, session_range_data, session_status_notf,
};
use crate::uci::mock_uci_manager::MockUciManager;
use crate::uci::notification::UciNotification;
- fn setup_uwb_service(uci_manager: MockUciManager) -> (UwbService, MockUwbServiceCallback) {
- let callback = MockUwbServiceCallback::new();
- let service = UwbService::new(default_runtime().unwrap(), callback.clone(), uci_manager);
- (service, callback)
- }
-
- #[test]
- fn test_open_close_uci() {
+ #[tokio::test]
+ async fn test_open_close_uci() {
let mut uci_manager = MockUciManager::new();
uci_manager.expect_open_hal(vec![], Ok(()));
uci_manager.expect_close_hal(false, Ok(()));
- let (mut service, _) = setup_uwb_service(uci_manager);
+ let mut service = UwbService::new(mpsc::unbounded_channel().0, uci_manager);
- let result = service.enable();
+ let result = service.enable().await;
assert!(result.is_ok());
- let result = service.disable();
+ let result = service.disable().await;
assert!(result.is_ok());
}
- #[test]
- fn test_session_e2e() {
+ #[tokio::test]
+ async fn test_session_e2e() {
let session_id = 0x123;
let session_type = SessionType::FiraRangingSession;
let params = generate_params();
@@ -528,61 +531,78 @@ mod tests {
Ok(()),
);
- let (mut service, mut callback) = setup_uwb_service(uci_manager.clone());
- service.enable().unwrap();
+ let (notf_sender, mut notf_receiver) = mpsc::unbounded_channel();
+ let mut service = UwbService::new(notf_sender, uci_manager.clone());
+ service.enable().await.unwrap();
// Initialize a normal session.
- callback.expect_on_session_state_changed(
- session_id,
- SessionState::SessionStateInit,
- ReasonCode::StateChangeWithSessionManagementCommands,
+ let result = service.init_session(session_id, session_type, params.clone()).await;
+ assert!(result.is_ok());
+ let session_notf = notf_receiver.recv().await.unwrap();
+ assert_eq!(
+ session_notf,
+ UwbNotification::SessionState {
+ session_id,
+ session_state: SessionState::SessionStateInit,
+ reason_code: ReasonCode::StateChangeWithSessionManagementCommands
+ }
);
- callback.expect_on_session_state_changed(
- session_id,
- SessionState::SessionStateIdle,
- ReasonCode::StateChangeWithSessionManagementCommands,
+ let session_notf = notf_receiver.recv().await.unwrap();
+ assert_eq!(
+ session_notf,
+ UwbNotification::SessionState {
+ session_id,
+ session_state: SessionState::SessionStateIdle,
+ reason_code: ReasonCode::StateChangeWithSessionManagementCommands
+ }
);
- let result = service.init_session(session_id, session_type, params);
- assert!(result.is_ok());
- assert!(service.block_on_for_testing(callback.wait_expected_calls_done()));
// Start the ranging process, and should receive the range data.
- callback.expect_on_session_state_changed(
- session_id,
- SessionState::SessionStateActive,
- ReasonCode::StateChangeWithSessionManagementCommands,
- );
- callback.expect_on_range_data_received(session_id, range_data);
- let result = service.start_ranging(session_id);
+ let result = service.start_ranging(session_id).await;
assert!(result.is_ok());
- assert!(service.block_on_for_testing(callback.wait_expected_calls_done()));
+ let session_notf = notf_receiver.recv().await.unwrap();
+ assert_eq!(
+ session_notf,
+ UwbNotification::SessionState {
+ session_id,
+ session_state: SessionState::SessionStateActive,
+ reason_code: ReasonCode::StateChangeWithSessionManagementCommands
+ }
+ );
+ let session_notf = notf_receiver.recv().await.unwrap();
+ assert_eq!(session_notf, UwbNotification::RangeData { session_id, range_data });
// Stop the ranging process.
- callback.expect_on_session_state_changed(
- session_id,
- SessionState::SessionStateIdle,
- ReasonCode::StateChangeWithSessionManagementCommands,
- );
- let result = service.stop_ranging(session_id);
+ let result = service.stop_ranging(session_id).await;
assert!(result.is_ok());
- assert!(service.block_on_for_testing(callback.wait_expected_calls_done()));
+ let session_notf = notf_receiver.recv().await.unwrap();
+ assert_eq!(
+ session_notf,
+ UwbNotification::SessionState {
+ session_id,
+ session_state: SessionState::SessionStateIdle,
+ reason_code: ReasonCode::StateChangeWithSessionManagementCommands
+ }
+ );
// Deinitialize the session, and should receive the deinitialized notification.
- callback.expect_on_session_state_changed(
- session_id,
- SessionState::SessionStateDeinit,
- ReasonCode::StateChangeWithSessionManagementCommands,
- );
- let result = service.deinit_session(session_id);
+ let result = service.deinit_session(session_id).await;
assert!(result.is_ok());
- assert!(service.block_on_for_testing(callback.wait_expected_calls_done()));
+ let session_notf = notf_receiver.recv().await.unwrap();
+ assert_eq!(
+ session_notf,
+ UwbNotification::SessionState {
+ session_id,
+ session_state: SessionState::SessionStateDeinit,
+ reason_code: ReasonCode::StateChangeWithSessionManagementCommands
+ }
+ );
- // Verify if all of the expected uci_manager method are called.
- assert!(service.block_on_for_testing(uci_manager.wait_expected_calls_done()));
+ assert!(uci_manager.wait_expected_calls_done().await);
}
- #[test]
- fn test_session_api_without_enabled() {
+ #[tokio::test]
+ async fn test_session_api_without_enabled() {
let session_id = 0x123;
let session_type = SessionType::FiraRangingSession;
let params = generate_params();
@@ -590,35 +610,35 @@ mod tests {
let controlees = vec![Controlee { short_address: 0x13, subsession_id: 0x24 }];
let uci_manager = MockUciManager::new();
- let (mut service, _) = setup_uwb_service(uci_manager);
+ let mut service = UwbService::new(mpsc::unbounded_channel().0, uci_manager);
- let result = service.init_session(session_id, session_type, params.clone());
+ let result = service.init_session(session_id, session_type, params.clone()).await;
assert!(result.is_err());
- let result = service.deinit_session(session_id);
+ let result = service.deinit_session(session_id).await;
assert!(result.is_err());
- let result = service.start_ranging(session_id);
+ let result = service.start_ranging(session_id).await;
assert!(result.is_err());
- let result = service.stop_ranging(session_id);
+ let result = service.stop_ranging(session_id).await;
assert!(result.is_err());
- let result = service.reconfigure(session_id, params);
+ let result = service.reconfigure(session_id, params).await;
assert!(result.is_err());
- let result = service.update_controller_multicast_list(session_id, action, controlees);
+ let result = service.update_controller_multicast_list(session_id, action, controlees).await;
assert!(result.is_err());
}
- #[test]
- fn test_android_set_country_code() {
+ #[tokio::test]
+ async fn test_android_set_country_code() {
let country_code = CountryCode::new(b"US").unwrap();
let mut uci_manager = MockUciManager::new();
uci_manager.expect_android_set_country_code(country_code.clone(), Ok(()));
- let (mut service, _) = setup_uwb_service(uci_manager);
+ let mut service = UwbService::new(mpsc::unbounded_channel().0, uci_manager);
- let result = service.android_set_country_code(country_code);
+ let result = service.android_set_country_code(country_code).await;
assert!(result.is_ok());
}
- #[test]
- fn test_android_get_power_stats() {
+ #[tokio::test]
+ async fn test_android_get_power_stats() {
let stats = PowerStats {
status: StatusCode::UciStatusOk,
idle_time_ms: 123,
@@ -628,14 +648,14 @@ mod tests {
};
let mut uci_manager = MockUciManager::new();
uci_manager.expect_android_get_power_stats(Ok(stats.clone()));
- let (mut service, _) = setup_uwb_service(uci_manager);
+ let mut service = UwbService::new(mpsc::unbounded_channel().0, uci_manager);
- let result = service.android_get_power_stats().unwrap();
+ let result = service.android_get_power_stats().await.unwrap();
assert_eq!(result, stats);
}
- #[test]
- fn test_send_vendor_cmd() {
+ #[tokio::test]
+ async fn test_send_vendor_cmd() {
let gid = 0x09;
let oid = 0x35;
let cmd_payload = vec![0x12, 0x34];
@@ -648,14 +668,14 @@ mod tests {
cmd_payload.clone(),
Ok(RawVendorMessage { gid, oid, payload: resp_payload.clone() }),
);
- let (mut service, _) = setup_uwb_service(uci_manager);
+ let mut service = UwbService::new(mpsc::unbounded_channel().0, uci_manager);
- let result = service.send_vendor_cmd(gid, oid, cmd_payload).unwrap();
+ let result = service.send_vendor_cmd(gid, oid, cmd_payload).await.unwrap();
assert_eq!(result, RawVendorMessage { gid, oid, payload: resp_payload });
}
- #[test]
- fn test_vendor_notification() {
+ #[tokio::test]
+ async fn test_vendor_notification() {
let gid = 5;
let oid = 7;
let payload = vec![0x13, 0x47];
@@ -665,15 +685,17 @@ mod tests {
vec![UciNotification::Vendor(RawVendorMessage { gid, oid, payload: payload.clone() })],
Ok(()),
);
- let (mut service, mut callback) = setup_uwb_service(uci_manager);
+ let (notf_sender, mut notf_receiver) = mpsc::unbounded_channel();
+ let mut service = UwbService::new(notf_sender, uci_manager);
+ service.enable().await.unwrap();
- callback.expect_on_vendor_notification_received(gid, oid, payload);
- service.enable().unwrap();
- assert!(service.block_on_for_testing(callback.wait_expected_calls_done()));
+ let expected_notf = UwbNotification::VendorNotification { gid, oid, payload };
+ let notf = notf_receiver.recv().await.unwrap();
+ assert_eq!(notf, expected_notf);
}
- #[test]
- fn test_core_device_status_notification() {
+ #[tokio::test]
+ async fn test_core_device_status_notification() {
let state = DeviceState::DeviceStateReady;
let mut uci_manager = MockUciManager::new();
@@ -681,32 +703,38 @@ mod tests {
vec![UciNotification::Core(CoreNotification::DeviceStatus(state))],
Ok(()),
);
- let (mut service, mut callback) = setup_uwb_service(uci_manager);
- callback.expect_on_uci_device_status_changed(state);
- service.enable().unwrap();
- assert!(service.block_on_for_testing(callback.wait_expected_calls_done()));
+ let (notf_sender, mut notf_receiver) = mpsc::unbounded_channel();
+ let mut service = UwbService::new(notf_sender, uci_manager);
+ service.enable().await.unwrap();
+
+ let expected_notf = UwbNotification::UciDeviceStatus(state);
+ let notf = notf_receiver.recv().await.unwrap();
+ assert_eq!(notf, expected_notf);
}
- #[test]
- fn test_reset_service_after_timeout() {
+ #[tokio::test]
+ async fn test_reset_service_after_timeout() {
let mut uci_manager = MockUciManager::new();
// The first open_hal() returns timeout.
uci_manager.expect_open_hal(vec![], Err(Error::Timeout));
// Then UwbService should close_hal() and open_hal() to reset the HAL.
uci_manager.expect_close_hal(true, Ok(()));
uci_manager.expect_open_hal(vec![], Ok(()));
- let (mut service, mut callback) = setup_uwb_service(uci_manager.clone());
+ let (notf_sender, mut notf_receiver) = mpsc::unbounded_channel();
+ let mut service = UwbService::new(notf_sender, uci_manager.clone());
- callback.expect_on_service_reset(true);
- let result = service.enable();
+ let result = service.enable().await;
assert_eq!(result, Err(Error::Timeout));
- assert!(service.block_on_for_testing(callback.wait_expected_calls_done()));
- assert!(service.block_on_for_testing(uci_manager.wait_expected_calls_done()));
+ let expected_notf = UwbNotification::ServiceReset { success: true };
+ let notf = notf_receiver.recv().await.unwrap();
+ assert_eq!(notf, expected_notf);
+
+ assert!(uci_manager.wait_expected_calls_done().await);
}
- #[test]
- fn test_reset_service_when_error_state() {
+ #[tokio::test]
+ async fn test_reset_service_when_error_state() {
let mut uci_manager = MockUciManager::new();
// The first open_hal() send DeviceStateError notification.
uci_manager.expect_open_hal(
@@ -718,12 +746,16 @@ mod tests {
// Then UwbService should close_hal() and open_hal() to reset the HAL.
uci_manager.expect_close_hal(true, Ok(()));
uci_manager.expect_open_hal(vec![], Ok(()));
- let (mut service, mut callback) = setup_uwb_service(uci_manager.clone());
+ let (notf_sender, mut notf_receiver) = mpsc::unbounded_channel();
+ let mut service = UwbService::new(notf_sender, uci_manager.clone());
- callback.expect_on_service_reset(true);
- let result = service.enable();
+ let result = service.enable().await;
assert_eq!(result, Ok(()));
- assert!(service.block_on_for_testing(callback.wait_expected_calls_done()));
- assert!(service.block_on_for_testing(uci_manager.wait_expected_calls_done()));
+
+ let expected_notf = UwbNotification::ServiceReset { success: true };
+ let notf = notf_receiver.recv().await.unwrap();
+ assert_eq!(notf, expected_notf);
+
+ assert!(uci_manager.wait_expected_calls_done().await);
}
}
diff --git a/src/rust/uwb_core/src/service/uwb_service_builder.rs b/src/rust/uwb_core/src/service/uwb_service_builder.rs
index 8b1eb80..d621a23 100644
--- a/src/rust/uwb_core/src/service/uwb_service_builder.rs
+++ b/src/rust/uwb_core/src/service/uwb_service_builder.rs
@@ -14,46 +14,29 @@
//! This module defines the UwbServiceBuilder, the builder of the UwbService.
-use tokio::runtime::Runtime;
+use tokio::sync::mpsc;
-use crate::service::uwb_service::{UwbService, UwbServiceCallback};
+use crate::service::uwb_service::{UwbNotification, UwbService};
use crate::uci::uci_hal::UciHal;
use crate::uci::uci_manager::UciManagerImpl;
-/// Create the default runtime for UwbService.
-pub fn default_runtime() -> Option<Runtime> {
- tokio::runtime::Builder::new_multi_thread().thread_name("UwbService").enable_all().build().ok()
-}
-
/// The builder of UwbService, used to keep the backward compatibility when adding new parameters
/// of creating a UwbService instance.
-pub struct UwbServiceBuilder<C: UwbServiceCallback, U: UciHal> {
- runtime: Option<Runtime>,
- callback: Option<C>,
+pub struct UwbServiceBuilder<U: UciHal> {
+ notf_sender: mpsc::UnboundedSender<UwbNotification>,
uci_hal: Option<U>,
}
-impl<C: UwbServiceCallback, U: UciHal> Default for UwbServiceBuilder<C, U> {
- fn default() -> Self {
- Self { runtime: None, callback: None, uci_hal: None }
- }
-}
-
-impl<C: UwbServiceCallback, U: UciHal> UwbServiceBuilder<C, U> {
+#[allow(clippy::new_without_default)]
+impl<U: UciHal> UwbServiceBuilder<U> {
/// Create a new builder.
pub fn new() -> Self {
- Default::default()
+ Self { notf_sender: mpsc::unbounded_channel().0, uci_hal: None }
}
- /// Set the runtime field.
- pub fn runtime(mut self, runtime: Runtime) -> Self {
- self.runtime = Some(runtime);
- self
- }
-
- /// Set the callback field.
- pub fn callback(mut self, callback: C) -> Self {
- self.callback = Some(callback);
+ /// Set the notf_sender field.
+ pub fn notf_sender(mut self, notf_sender: mpsc::UnboundedSender<UwbNotification>) -> Self {
+ self.notf_sender = notf_sender;
self
}
@@ -64,32 +47,23 @@ impl<C: UwbServiceCallback, U: UciHal> UwbServiceBuilder<C, U> {
}
/// Build the UwbService.
- pub fn build(mut self) -> Option<UwbService> {
- let runtime = self.runtime.take().or_else(default_runtime)?;
- let uci_hal = self.uci_hal.take()?;
- let uci_manager = runtime.block_on(async move { UciManagerImpl::new(uci_hal) });
- Some(UwbService::new(runtime, self.callback.take()?, uci_manager))
+ pub fn build(self) -> Option<UwbService> {
+ let uci_manager = UciManagerImpl::new(self.uci_hal?);
+ Some(UwbService::new(self.notf_sender, uci_manager))
}
}
#[cfg(test)]
mod tests {
use super::*;
- use crate::service::mock_uwb_service_callback::MockUwbServiceCallback;
use crate::uci::mock_uci_hal::MockUciHal;
- #[test]
- fn test_build_fail() {
- let result = UwbServiceBuilder::<MockUwbServiceCallback, MockUciHal>::new().build();
+ #[tokio::test]
+ async fn test_uci_hal() {
+ let result = UwbServiceBuilder::<MockUciHal>::new().build();
assert!(result.is_none());
- }
- #[test]
- fn test_build_ok() {
- let result = UwbServiceBuilder::new()
- .callback(MockUwbServiceCallback::new())
- .uci_hal(MockUciHal::new())
- .build();
+ let result = UwbServiceBuilder::new().uci_hal(MockUciHal::new()).build();
assert!(result.is_some());
}
}
diff --git a/src/rust/uwb_core/src/session/session_manager.rs b/src/rust/uwb_core/src/session/session_manager.rs
index f2280ad..1050916 100644
--- a/src/rust/uwb_core/src/session/session_manager.rs
+++ b/src/rust/uwb_core/src/session/session_manager.rs
@@ -424,7 +424,6 @@ pub(crate) mod test_utils {
aoa_destination_elevation: 11,
aoa_destination_elevation_fom: 12,
slot_index: 0,
- rssi: u8::MAX,
},
]),
}
@@ -481,7 +480,6 @@ mod tests {
SetAppConfigResponse, StatusCode,
};
use crate::params::utils::{u32_to_bytes, u64_to_bytes, u8_to_bytes};
- use crate::params::{FiraAppConfigParamsBuilder, KeyRotation};
use crate::uci::notification::UciNotification;
#[tokio::test]
@@ -890,101 +888,4 @@ mod tests {
assert!(mock_uci_manager.wait_expected_calls_done().await);
}
-
- #[tokio::test]
- async fn test_reconfigure_app_config() {
- let session_id = 0x123;
- let session_type = SessionType::FiraRangingSession;
-
- let initial_params = generate_params();
- let initial_tlvs = initial_params.generate_tlvs();
-
- let non_default_key_rotation_val = KeyRotation::Enable;
- let idle_params = FiraAppConfigParamsBuilder::from_params(&initial_params)
- .unwrap()
- .key_rotation(non_default_key_rotation_val)
- .build()
- .unwrap();
- let idle_tlvs = idle_params
- .generate_updated_tlvs(&initial_params, SessionState::SessionStateIdle)
- .unwrap();
-
- let non_default_block_stride_val = 2u8;
- let active_params = FiraAppConfigParamsBuilder::from_params(&idle_params)
- .unwrap()
- .block_stride_length(non_default_block_stride_val)
- .build()
- .unwrap();
- let active_tlvs = active_params
- .generate_updated_tlvs(&idle_params, SessionState::SessionStateIdle)
- .unwrap();
-
- let (mut session_manager, mut mock_uci_manager, _) =
- setup_session_manager(move |uci_manager| {
- uci_manager.expect_session_init(
- session_id,
- session_type,
- vec![session_status_notf(session_id, SessionState::SessionStateInit)],
- Ok(()),
- );
- uci_manager.expect_session_set_app_config(
- session_id,
- initial_tlvs,
- vec![session_status_notf(session_id, SessionState::SessionStateIdle)],
- Ok(SetAppConfigResponse {
- status: StatusCode::UciStatusOk,
- config_status: vec![],
- }),
- );
- uci_manager.expect_session_set_app_config(
- session_id,
- idle_tlvs,
- vec![],
- Ok(SetAppConfigResponse {
- status: StatusCode::UciStatusOk,
- config_status: vec![],
- }),
- );
- uci_manager.expect_range_start(
- session_id,
- vec![session_status_notf(session_id, SessionState::SessionStateActive)],
- Ok(()),
- );
- uci_manager.expect_session_set_app_config(
- session_id,
- active_tlvs,
- vec![],
- Ok(SetAppConfigResponse {
- status: StatusCode::UciStatusOk,
- config_status: vec![],
- }),
- );
- })
- .await;
-
- // Reconfiguring without first initing a session should fail.
- let result = session_manager.reconfigure(session_id, initial_params.clone()).await;
- assert_eq!(result, Err(Error::BadParameters));
-
- let result =
- session_manager.init_session(session_id, session_type, initial_params.clone()).await;
- assert_eq!(result, Ok(()));
-
- // Reconfiguring any parameters during idle state should succeed.
- let result = session_manager.reconfigure(session_id, idle_params.clone()).await;
- assert_eq!(result, Ok(()));
-
- let result = session_manager.start_ranging(session_id).await;
- assert_eq!(result, Ok(idle_params));
-
- // Reconfiguring most parameters during active state should fail.
- let result = session_manager.reconfigure(session_id, initial_params).await;
- assert_eq!(result, Err(Error::BadParameters));
-
- // Only some parameters are allowed to be reconfigured during active state.
- let result = session_manager.reconfigure(session_id, active_params).await;
- assert_eq!(result, Ok(()));
-
- assert!(mock_uci_manager.wait_expected_calls_done().await);
- }
}
diff --git a/src/rust/uwb_core/src/uci.rs b/src/rust/uwb_core/src/uci.rs
index 55fe794..0a3aefe 100644
--- a/src/rust/uwb_core/src/uci.rs
+++ b/src/rust/uwb_core/src/uci.rs
@@ -24,7 +24,6 @@ pub(crate) mod notification;
pub(crate) mod uci_manager;
pub mod uci_hal;
-pub mod uci_manager_sync;
#[cfg(test)]
pub(crate) mod mock_uci_hal;
@@ -32,5 +31,4 @@ pub(crate) mod mock_uci_hal;
pub(crate) mod mock_uci_manager;
// Re-export the public elements.
-pub use notification::{RangingMeasurements, SessionRangeData};
pub use uci_hal::{RawUciMessage, UciHal};
diff --git a/src/rust/uwb_core/src/uci/mock_uci_manager.rs b/src/rust/uwb_core/src/uci/mock_uci_manager.rs
index 6b9086d..9a9eaac 100644
--- a/src/rust/uwb_core/src/uci/mock_uci_manager.rs
+++ b/src/rust/uwb_core/src/uci/mock_uci_manager.rs
@@ -166,7 +166,7 @@ impl MockUciManager {
});
}
- pub fn expect_session_get_count(&mut self, out: Result<u8>) {
+ pub fn expect_session_get_count(&mut self, out: Result<usize>) {
self.expected_calls.lock().unwrap().push_back(ExpectedCall::SessionGetCount { out });
}
@@ -516,7 +516,7 @@ impl UciManager for MockUciManager {
}
}
- async fn session_get_count(&mut self) -> Result<u8> {
+ async fn session_get_count(&mut self) -> Result<usize> {
let mut expected_calls = self.expected_calls.lock().unwrap();
match expected_calls.pop_front() {
Some(ExpectedCall::SessionGetCount { out }) => {
@@ -742,7 +742,7 @@ enum ExpectedCall {
out: Result<Vec<AppConfigTlv>>,
},
SessionGetCount {
- out: Result<u8>,
+ out: Result<usize>,
},
SessionGetState {
expected_session_id: SessionId,
diff --git a/src/rust/uwb_core/src/uci/notification.rs b/src/rust/uwb_core/src/uci/notification.rs
index 79d382e..efd1705 100644
--- a/src/rust/uwb_core/src/uci/notification.rs
+++ b/src/rust/uwb_core/src/uci/notification.rs
@@ -25,20 +25,20 @@ use crate::params::uci_packets::{
};
#[derive(Debug, Clone, PartialEq)]
-pub enum UciNotification {
+pub(crate) enum UciNotification {
Core(CoreNotification),
Session(SessionNotification),
Vendor(RawVendorMessage),
}
#[derive(Debug, Clone, PartialEq)]
-pub enum CoreNotification {
+pub(crate) enum CoreNotification {
DeviceStatus(DeviceState),
GenericError(StatusCode),
}
#[derive(Debug, Clone, PartialEq)]
-pub enum SessionNotification {
+pub(crate) enum SessionNotification {
Status {
session_id: SessionId,
session_state: SessionState,
@@ -51,33 +51,18 @@ pub enum SessionNotification {
},
RangeData(SessionRangeData),
}
-
-/// The session range data.
#[derive(Debug, Clone, PartialEq)]
pub struct SessionRangeData {
- /// The sequence counter that starts with 0 when the session is started.
pub sequence_number: u32,
-
- /// The identifier of the session.
pub session_id: SessionId,
-
- /// The current ranging interval setting in the unit of ms.
pub current_ranging_interval_ms: u32,
-
- /// The ranging measurement type.
pub ranging_measurement_type: RangingMeasurementType,
-
- /// The ranging measurement data.
pub ranging_measurements: RangingMeasurements,
}
-/// The ranging measurements.
#[derive(Debug, Clone, PartialEq)]
pub enum RangingMeasurements {
- /// The measurement with short address.
Short(Vec<ShortAddressTwoWayRangingMeasurement>),
-
- /// The measurement with extended address.
Extended(Vec<ExtendedAddressTwoWayRangingMeasurement>),
}
@@ -299,7 +284,6 @@ mod tests {
aoa_destination_elevation: 11,
aoa_destination_elevation_fom: 12,
slot_index: 0,
- rssi: u8::MAX,
}]);
let extended_ranging_measurements_copy = extended_ranging_measurements.clone();
assert_eq!(extended_ranging_measurements, extended_ranging_measurements_copy);
@@ -358,7 +342,6 @@ mod tests {
aoa_destination_elevation: 11,
aoa_destination_elevation_fom: 12,
slot_index: 0,
- rssi: u8::MAX,
};
let extended_two_way_range_data_ntf =
uwb_uci_packets::ExtendedMacTwoWayRangeDataNtfBuilder {
@@ -403,7 +386,6 @@ mod tests {
aoa_destination_elevation: 11,
aoa_destination_elevation_fom: 12,
slot_index: 0,
- rssi: u8::MAX,
};
let short_two_way_range_data_ntf = uwb_uci_packets::ShortMacTwoWayRangeDataNtfBuilder {
sequence_number: 0x10,
diff --git a/src/rust/uwb_core/src/uci/response.rs b/src/rust/uwb_core/src/uci/response.rs
index efcf466..0037a0c 100644
--- a/src/rust/uwb_core/src/uci/response.rs
+++ b/src/rust/uwb_core/src/uci/response.rs
@@ -38,7 +38,7 @@ pub(super) enum UciResponse {
SessionDeinit(Result<()>),
SessionSetAppConfig(SetAppConfigResponse),
SessionGetAppConfig(Result<Vec<AppConfigTlv>>),
- SessionGetCount(Result<u8>),
+ SessionGetCount(Result<usize>),
SessionGetState(Result<SessionState>),
SessionUpdateControllerMulticastList(Result<()>),
RangeStart(Result<()>),
@@ -156,7 +156,7 @@ impl TryFrom<uwb_uci_packets::SessionResponsePacket> for UciResponse {
Ok(UciResponse::SessionDeinit(status_code_to_result(evt.get_status())))
}
SessionResponseChild::SessionGetCountRsp(evt) => Ok(UciResponse::SessionGetCount(
- status_code_to_result(evt.get_status()).map(|_| evt.get_session_count()),
+ status_code_to_result(evt.get_status()).map(|_| evt.get_session_count() as usize),
)),
SessionResponseChild::SessionGetStateRsp(evt) => Ok(UciResponse::SessionGetState(
status_code_to_result(evt.get_status()).map(|_| evt.get_session_state()),
diff --git a/src/rust/uwb_core/src/uci/uci_manager.rs b/src/rust/uwb_core/src/uci/uci_manager.rs
index b86f862..2a4d682 100644
--- a/src/rust/uwb_core/src/uci/uci_manager.rs
+++ b/src/rust/uwb_core/src/uci/uci_manager.rs
@@ -92,7 +92,7 @@ pub(crate) trait UciManager: 'static + Send + Clone {
session_id: SessionId,
config_ids: Vec<AppConfigTlvType>,
) -> Result<Vec<AppConfigTlv>>;
- async fn session_get_count(&mut self) -> Result<u8>;
+ async fn session_get_count(&mut self) -> Result<usize>;
async fn session_get_state(&mut self, session_id: SessionId) -> Result<SessionState>;
async fn session_update_controller_multicast_list(
&mut self,
@@ -285,7 +285,7 @@ impl UciManager for UciManagerImpl {
}
}
- async fn session_get_count(&mut self) -> Result<u8> {
+ async fn session_get_count(&mut self) -> Result<usize> {
let cmd = UciCommand::SessionGetCount;
match self.send_cmd(UciManagerCmd::SendUciCommand { cmd }).await {
Ok(UciResponse::SessionGetCount(resp)) => resp,
diff --git a/src/rust/uwb_core/src/uci/uci_manager_sync.rs b/src/rust/uwb_core/src/uci/uci_manager_sync.rs
deleted file mode 100644
index 027a98d..0000000
--- a/src/rust/uwb_core/src/uci/uci_manager_sync.rs
+++ /dev/null
@@ -1,344 +0,0 @@
-// Copyright 2022, The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//! This module offers a synchornized interface at UCI level.
-//!
-//! The module is designed with the replacement for Android UCI JNI adaptation in mind. The handling
-//! of UciNotifications is different in UciManager and UciManagerSync as the sync version has its
-//! behavior aligned with the Android JNI UCI, and routes the UciNotifications to NotificationManager.
-
-use log::{error, info};
-use tokio::runtime::Runtime;
-use tokio::sync::mpsc;
-
-use crate::error::Result;
-use crate::params::{
- AppConfigTlv, AppConfigTlvType, CapTlv, Controlee, CoreSetConfigResponse, CountryCode,
- DeviceConfigId, DeviceConfigTlv, GetDeviceInfoResponse, PowerStats, RawVendorMessage,
- ResetConfig, SessionId, SessionState, SessionType, SetAppConfigResponse,
- UpdateMulticastListAction,
-};
-use crate::uci::notification::{CoreNotification, SessionNotification};
-use crate::uci::uci_hal::UciHal;
-use crate::uci::uci_manager::{UciManager, UciManagerImpl};
-
-/// The NotificationManager trait is needed to process UciNotification relayed from UciManagerSync.
-///
-/// The UciManagerSync assumes the NotificationManager takes the responsibility to properly handle
-/// the notifications, including tracking the state of HAL. UciManagerSync and lower levels only
-/// redirect and categorize the notifications. The notifications are processed through callbacks.
-pub trait NotificationManager: 'static + Send {
- /// Callback for CoreNotification.
- fn on_core_notification(&mut self, core_notification: CoreNotification) -> Result<()>;
-
- /// Callback for SessionNotification.
- fn on_session_notification(&mut self, session_notification: SessionNotification) -> Result<()>;
-
- /// Callback for RawVendorMessage.
- fn on_vendor_notification(&mut self, vendor_notification: RawVendorMessage) -> Result<()>;
-}
-struct NotificationDriver<U: NotificationManager> {
- core_notification_receiver: mpsc::UnboundedReceiver<CoreNotification>,
- session_notification_receiver: mpsc::UnboundedReceiver<SessionNotification>,
- vendor_notification_receiver: mpsc::UnboundedReceiver<RawVendorMessage>,
- notification_manager: U,
-}
-impl<U: NotificationManager> NotificationDriver<U> {
- fn new(notification_manager: U) -> Self {
- Self {
- core_notification_receiver: mpsc::unbounded_channel::<CoreNotification>().1,
- session_notification_receiver: mpsc::unbounded_channel::<SessionNotification>().1,
- vendor_notification_receiver: mpsc::unbounded_channel::<RawVendorMessage>().1,
- notification_manager,
- }
- }
- fn set_core_notification_receiver(
- &mut self,
- core_notification_receiver: mpsc::UnboundedReceiver<CoreNotification>,
- ) {
- self.core_notification_receiver = core_notification_receiver;
- }
- fn set_session_notification_receiver(
- &mut self,
- session_notification_receiver: mpsc::UnboundedReceiver<SessionNotification>,
- ) {
- self.session_notification_receiver = session_notification_receiver;
- }
- fn set_vendor_notification_receiver(
- &mut self,
- vendor_notification_receiver: mpsc::UnboundedReceiver<RawVendorMessage>,
- ) {
- self.vendor_notification_receiver = vendor_notification_receiver;
- }
- async fn run(&mut self) {
- loop {
- tokio::select! {
- Some(ntf) = self.core_notification_receiver.recv() =>{
- self.notification_manager.on_core_notification(ntf).unwrap_or_else(|e|{
- error!("NotificationDriver: CoreNotification callback error: {:?}",e);
- });
- }
- Some(ntf) = self.session_notification_receiver.recv() =>{
- self.notification_manager.on_session_notification(ntf).unwrap_or_else(|e|{
- error!("NotificationDriver: SessionNotification callback error: {:?}",e);
- });
- }
- Some(ntf) = self.vendor_notification_receiver.recv() =>{
- self.notification_manager.on_vendor_notification(ntf).unwrap_or_else(|e|{
- error!("NotificationDriver: RawVendorMessage callback error: {:?}",e);
- });
- }
- else =>{
- info!("NotificationDriver dropping.");
- }
- }
- }
- }
-}
-/// The UciManagerSync provides a synchornized version of UciManager using the runtime supplied
-/// at its initialization.
-///
-/// Note the processing of UciNotification is different: they are handled by NotificationManager
-/// provided at construction, and the async version set_X_notification_sender methods are removed.
-pub struct UciManagerSync {
- runtime: Runtime,
- uci_manager_impl: UciManagerImpl,
-}
-impl UciManagerSync {
- /// UciHal and NotificationManager required at construction as they are required before open_hal
- /// called. runtime is taken with ownership for blocking on async steps only.
- pub fn new<T: UciHal, U: NotificationManager>(
- runtime: Runtime,
- hal: T,
- notification_manager: U,
- ) -> Self {
- // UciManagerImpl::new uses tokio::spawn, so it is called inside the runtime as async fn.
- let mut uci_manager_impl = runtime.block_on(async { UciManagerImpl::new(hal) });
- let mut notification_driver = NotificationDriver::new(notification_manager);
- runtime.block_on(async {
- let (core_notification_sender, core_notification_receiver) =
- mpsc::unbounded_channel::<CoreNotification>();
- uci_manager_impl.set_core_notification_sender(core_notification_sender).await;
- notification_driver.set_core_notification_receiver(core_notification_receiver);
- });
- runtime.block_on(async {
- let (session_notification_sender, session_notification_receiver) =
- mpsc::unbounded_channel::<SessionNotification>();
- uci_manager_impl.set_session_notification_sender(session_notification_sender).await;
- notification_driver.set_session_notification_receiver(session_notification_receiver);
- });
- runtime.block_on(async {
- let (vendor_notification_sender, vendor_notification_receiver) =
- mpsc::unbounded_channel::<RawVendorMessage>();
- uci_manager_impl.set_vendor_notification_sender(vendor_notification_sender).await;
- notification_driver.set_vendor_notification_receiver(vendor_notification_receiver);
- });
- runtime.spawn(async move { notification_driver.run().await });
- Self { runtime, uci_manager_impl }
- }
-
- /// Start UCI HAL and blocking until UCI commands can be sent.
- pub fn open_hal(&mut self) -> Result<()> {
- self.runtime.block_on(self.uci_manager_impl.open_hal())
- }
-
- /// Stop the UCI HAL.
- pub fn close_hal(&mut self, force: bool) -> Result<()> {
- self.runtime.block_on(self.uci_manager_impl.close_hal(force))
- }
-
- // Methods for sending UCI commands. Functions are blocked until UCI response is received.
- /// Send UCI command for device reset.
- pub fn device_reset(&mut self, reset_config: ResetConfig) -> Result<()> {
- self.runtime.block_on(self.uci_manager_impl.device_reset(reset_config))
- }
-
- /// Send UCI command for getting device info.
- pub fn core_get_device_info(&mut self) -> Result<GetDeviceInfoResponse> {
- self.runtime.block_on(self.uci_manager_impl.core_get_device_info())
- }
-
- /// Send UCI command for getting capability info
- pub fn core_get_caps_info(&mut self) -> Result<Vec<CapTlv>> {
- self.runtime.block_on(self.uci_manager_impl.core_get_caps_info())
- }
-
- /// Send UCI command for setting core configuration.
- pub fn core_set_config(
- &mut self,
- config_tlvs: Vec<DeviceConfigTlv>,
- ) -> Result<CoreSetConfigResponse> {
- self.runtime.block_on(self.uci_manager_impl.core_set_config(config_tlvs))
- }
-
- /// Send UCI command for getting core configuration.
- pub fn core_get_config(
- &mut self,
- config_ids: Vec<DeviceConfigId>,
- ) -> Result<Vec<DeviceConfigTlv>> {
- self.runtime.block_on(self.uci_manager_impl.core_get_config(config_ids))
- }
-
- /// Send UCI command for initiating session.
- pub fn session_init(&mut self, session_id: SessionId, session_type: SessionType) -> Result<()> {
- self.runtime.block_on(self.uci_manager_impl.session_init(session_id, session_type))
- }
-
- /// Send UCI command for deinitiating session.
- pub fn session_deinit(&mut self, session_id: SessionId) -> Result<()> {
- self.runtime.block_on(self.uci_manager_impl.session_deinit(session_id))
- }
-
- /// Send UCI command for setting app config.
- pub fn session_set_app_config(
- &mut self,
- session_id: SessionId,
- config_tlvs: Vec<AppConfigTlv>,
- ) -> Result<SetAppConfigResponse> {
- self.runtime.block_on(self.uci_manager_impl.session_set_app_config(session_id, config_tlvs))
- }
-
- /// Send UCI command for getting app config.
- pub fn session_get_app_config(
- &mut self,
- session_id: SessionId,
- config_ids: Vec<AppConfigTlvType>,
- ) -> Result<Vec<AppConfigTlv>> {
- self.runtime.block_on(self.uci_manager_impl.session_get_app_config(session_id, config_ids))
- }
-
- /// Send UCI command for getting count of sessions.
- pub fn session_get_count(&mut self) -> Result<u8> {
- self.runtime.block_on(self.uci_manager_impl.session_get_count())
- }
-
- /// Send UCI command for getting state of session.
- pub fn session_get_state(&mut self, session_id: SessionId) -> Result<SessionState> {
- self.runtime.block_on(self.uci_manager_impl.session_get_state(session_id))
- }
-
- /// Send UCI command for updating multicast list for multicast session.
- pub fn session_update_controller_multicast_list(
- &mut self,
- session_id: SessionId,
- action: UpdateMulticastListAction,
- controlees: Vec<Controlee>,
- ) -> Result<()> {
- self.runtime.block_on(
- self.uci_manager_impl
- .session_update_controller_multicast_list(session_id, action, controlees),
- )
- }
-
- /// Send UCI command for starting ranging of the session.
- pub fn range_start(&mut self, session_id: SessionId) -> Result<()> {
- self.runtime.block_on(self.uci_manager_impl.range_start(session_id))
- }
-
- /// Send UCI command for stopping ranging of the session.
- pub fn range_stop(&mut self, session_id: SessionId) -> Result<()> {
- self.runtime.block_on(self.uci_manager_impl.range_stop(session_id))
- }
-
- /// Send UCI command for getting ranging count.
- pub fn range_get_ranging_count(&mut self, session_id: SessionId) -> Result<usize> {
- self.runtime.block_on(self.uci_manager_impl.range_get_ranging_count(session_id))
- }
-
- /// Set the country code. Android-specific method.
- pub fn android_set_country_code(&mut self, country_code: CountryCode) -> Result<()> {
- self.runtime.block_on(self.uci_manager_impl.android_set_country_code(country_code))
- }
-
- /// Get the power statistics. Android-specific method.
- pub fn android_get_power_stats(&mut self) -> Result<PowerStats> {
- self.runtime.block_on(self.uci_manager_impl.android_get_power_stats())
- }
-
- /// Send UCI command for a vendor-specific message.
- pub fn raw_vendor_cmd(
- &mut self,
- gid: u32,
- oid: u32,
- payload: Vec<u8>,
- ) -> Result<RawVendorMessage> {
- self.runtime.block_on(self.uci_manager_impl.raw_vendor_cmd(gid, oid, payload))
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- use tokio::runtime::Builder;
- use uwb_uci_packets::DeviceState;
-
- use crate::error::Error;
- use crate::uci::mock_uci_hal::MockUciHal;
- use crate::uci::uci_hal::RawUciMessage;
-
- struct MockNotificationManager {
- device_state_sender: mpsc::UnboundedSender<DeviceState>,
- }
- impl MockNotificationManager {
- fn new(device_state_sender: mpsc::UnboundedSender<DeviceState>) -> Self {
- MockNotificationManager { device_state_sender }
- }
- }
- impl NotificationManager for MockNotificationManager {
- fn on_core_notification(&mut self, core_notification: CoreNotification) -> Result<()> {
- match core_notification {
- CoreNotification::DeviceStatus(device_state) => {
- self.device_state_sender.send(device_state).map_err(|_| Error::Unknown)?;
- }
- CoreNotification::GenericError(_) => {}
- };
- Ok(())
- }
- fn on_session_notification(
- &mut self,
- _session_notification: SessionNotification,
- ) -> Result<()> {
- Ok(())
- }
- fn on_vendor_notification(&mut self, _vendor_notification: RawVendorMessage) -> Result<()> {
- Ok(())
- }
- }
- fn into_raw_messages<T: Into<uwb_uci_packets::UciPacketPacket>>(
- builder: T,
- ) -> Vec<RawUciMessage> {
- let packets: Vec<uwb_uci_packets::UciPacketHalPacket> = builder.into().into();
- packets.into_iter().map(|packet| packet.into()).collect()
- }
- #[test]
- fn test_sync_uci_open_hal() {
- let mut hal = MockUciHal::new();
- let notf = into_raw_messages(uwb_uci_packets::DeviceStatusNtfBuilder {
- device_state: uwb_uci_packets::DeviceState::DeviceStateReady,
- });
- hal.expected_open(Some(notf), Ok(()));
- let test_rt = Builder::new_multi_thread().enable_all().build().unwrap();
- let (device_state_sender, mut device_state_receiver) =
- mpsc::unbounded_channel::<DeviceState>();
- let mut uci_manager_sync = UciManagerSync::new(
- Builder::new_multi_thread().enable_all().build().unwrap(),
- hal,
- MockNotificationManager::new(device_state_sender),
- );
- assert!(uci_manager_sync.open_hal().is_ok());
- let device_state = test_rt.block_on(async { device_state_receiver.recv().await });
- assert_eq!(device_state, Some(DeviceState::DeviceStateReady));
- }
-}
diff --git a/src/rust/uwb_uci_packets/Cargo.toml b/src/rust/uwb_uci_packets/Cargo.toml
index ae3c729..6743218 100644
--- a/src/rust/uwb_uci_packets/Cargo.toml
+++ b/src/rust/uwb_uci_packets/Cargo.toml
@@ -9,3 +9,4 @@ log = "*"
num-derive = "*"
num-traits = "*"
thiserror = "*"
+walkdir = "*"
diff --git a/src/rust/uwb_uci_packets/uci_packets.pdl b/src/rust/uwb_uci_packets/uci_packets.pdl
index 28263fb..3995c24 100644
--- a/src/rust/uwb_uci_packets/uci_packets.pdl
+++ b/src/rust/uwb_uci_packets/uci_packets.pdl
@@ -57,7 +57,6 @@ enum AppDataOpCode : 6 {
enum AndroidOpCode : 6 {
ANDROID_GET_POWER_STATS = 0x0,
ANDROID_SET_COUNTRY_CODE = 0x1,
- ANDROID_FIRA_RANGE_DIAGNOSTICS = 0x2,
}
enum StatusCode : 8 {
@@ -133,7 +132,6 @@ enum AppConfigTlvType : 8 {
RNG_DATA_NTF_PROXIMITY_FAR = 0x10,
DEVICE_ROLE = 0x11,
RFRAME_CONFIG = 0x12,
- RSSI_REPORTING = 0x13,
PREAMBLE_CODE_INDEX = 0x14,
SFD_ID = 0x15,
PSDU_DATA_RATE = 0x16,
@@ -141,8 +139,6 @@ enum AppConfigTlvType : 8 {
RANGING_TIME_STRUCT = 0x1A,
SLOTS_PER_RR = 0x1B,
TX_ADAPTIVE_PAYLOAD_POWER = 0x1C,
- // TODO: Ensure this value is correct in the final 2.0 specification.
- RNG_DATA_NTF_AOA_BOUND = 0x1D,
RESPONDER_SLOT_INDEX = 0x1E,
PRF_MODE = 0x1F,
SCHEDULED_MODE = 0x22,
@@ -178,15 +174,6 @@ enum AppConfigTlvType : 8 {
NB_OF_RANGE_MEASUREMENTS = 0xE3,
NB_OF_AZIMUTH_MEASUREMENTS = 0xE4,
NB_OF_ELEVATION_MEASUREMENTS = 0xE5,
-
- ENABLE_DIAGNOSTICS = 0xE8,
- DIAGRAMS_FRAME_REPORTS_FIELDS = 0xE9,
-}
-
-enum FrameReportTlvType : 8 {
- RSSI = 0x0,
- AOA = 0x1,
- CIR = 0x2,
}
enum CapTlvType : 8 {
@@ -209,8 +196,6 @@ enum CapTlvType : 8 {
SUPPORTED_AOA = 0x10,
SUPPORTED_EXTENDED_MAC_ADDRESS = 0x11,
SUPPORTED_AOA_RESULT_REQ_ANTENNA_INTERLEAVING = 0xE3,
- SUPPORTED_MIN_RANGING_INTERVAL_MS = 0xE4,
- SUPPORTED_RANGE_DATA_NTF_CONFIG = 0xE5,
// CCC specific
CCC_SUPPORTED_CHAPS_PER_SLOT = 0xA0,
@@ -707,8 +692,7 @@ struct ShortAddressTwoWayRangingMeasurement {
aoa_destination_elevation: 16,
aoa_destination_elevation_fom: 8,
slot_index: 8,
- rssi: 8,
- _reserved_: 88,
+ _reserved_: 96,
}
struct ExtendedAddressTwoWayRangingMeasurement {
@@ -725,8 +709,7 @@ struct ExtendedAddressTwoWayRangingMeasurement {
aoa_destination_elevation: 16,
aoa_destination_elevation_fom: 8,
slot_index: 8,
- rssi: 8,
- _reserved_: 40,
+ _reserved_: 48,
}
enum RangingMeasurementType : 8 {
@@ -837,52 +820,6 @@ test AndroidSetCountryCodeRsp {
"\x4c\x01\x00\x01\x00\x00\x00\x00",
}
-struct FrameReportTlv {
- t: FrameReportTlvType,
- length: 8,
- v: 8[],
-}
-
-packet AoaMeasurement {
- tdoa: 16,
- pdoa: 16,
- aoa: 16,
- fom: 8,
- t: 8,
-}
-
-packet Cir {
- first_path_index : 16,
- first_path_snr: 16,
- first_path_ns: 16,
- peak_path_index: 16,
- peak_path_snr: 16,
- peak_path_ns: 16,
- first_path_sample_offset: 8,
- sample_size: 8,
- samples_number: 8,
- sample_window: 8[],
-}
-
-struct FrameReport {
- uwb_msg_id: 8,
- action: 8,
- antenna_set: 8,
- _count_(frame_report_tlvs): 8,
- frame_report_tlvs: FrameReportTlv[],
-}
-
-packet AndroidFiraRangeDiagnosticsNtf : AndroidNotification (opcode = 0x2) { //QORVO_FIRA_RANGE_DIAGNOSTICS
- session_id: 32,
- sequence_number: 32,
- _count_(frame_reports): 8,
- frame_reports: FrameReport[],
-}
-
-test AndroidFiraRangeDiagnosticsNtf {
- "\x6c\x02\x00\x10\x00\x00\x00\x01\x01\x01\x01\x02\x02\x02\x02\x01\x00\x01\x02\x01\x00\x01\x00",
-}
-
packet UciVendor_9_Command : UciCommand (group_id = VENDOR_RESERVED_9) {
_payload_,
}