From f4f89c3e82440d0dfd3e94d2671aac9750763d9b Mon Sep 17 00:00:00 2001 From: Leslie Watkins Date: Wed, 15 Jun 2022 08:10:39 -0700 Subject: Update get_hal_service to take a chip_id and return the correct IUwbChip implementation based on the chip name. Include chip_id in jni and uci callbacks. Bug: 205605642 Test: atest libuwb_core_tests Test: atest libuwb_uci_packet_tests Test: atest libuwb_uci_rust_tests Change-Id: I2a7053b2eed26e71a580b2b72f15c67b5dfd2458 Merged-In: I2a7053b2eed26e71a580b2b72f15c67b5dfd2458 --- src/rust/uci/mod.rs | 244 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 156 insertions(+), 88 deletions(-) (limited to 'src/rust/uci/mod.rs') diff --git a/src/rust/uci/mod.rs b/src/rust/uci/mod.rs index 7b6d0c7..6f56b66 100644 --- a/src/rust/uci/mod.rs +++ b/src/rust/uci/mod.rs @@ -151,12 +151,17 @@ impl Retryer { self.failed.notify_one() } - fn send_with_retry(self, adaptation: SyncUwbAdaptation, cmd: UciCommandPacket) { + fn send_with_retry( + self, + adaptation: SyncUwbAdaptation, + cmd: UciCommandPacket, + chip_id: String, + ) { tokio::task::spawn(async move { let mut received_response = false; for retry in 0..MAX_RETRIES { - adaptation.send_uci_message(cmd.clone()).await.unwrap_or_else(|e| { - error!("Sending UCI message failed: {:?}", e); + adaptation.send_uci_message(cmd.clone(), &chip_id).await.unwrap_or_else(|e| { + error!("Sending UCI message to chip {} failed: {:?}", chip_id, e); }); select! { _ = tokio::time::sleep(tokio::time::Duration::from_millis(RETRY_DELAY_MS)) => warn!("UWB chip did not respond within {}ms deadline. Retrying (#{})...", RETRY_DELAY_MS, retry + 1), @@ -168,9 +173,9 @@ impl Retryer { } } if !received_response { - error!("After {} retries, no response from UWB chip", MAX_RETRIES); - adaptation.core_initialization().await.unwrap_or_else(|e| { - error!("Resetting chip due to no responses failed: {:?}", e); + error!("After {} retries, no response from UWB chip {}", MAX_RETRIES, chip_id); + adaptation.core_initialization(&chip_id).await.unwrap_or_else(|e| { + error!("Resetting chip {} due to no responses failed: {:?}", chip_id, e); }); self.failed(); } @@ -190,8 +195,8 @@ async fn option_future>(mf: Option) -> Option { struct Driver { adaptation: SyncUwbAdaptation, event_manager: T, - cmd_receiver: mpsc::UnboundedReceiver<(JNICommand, Option)>, - rsp_receiver: mpsc::UnboundedReceiver, + cmd_receiver: mpsc::UnboundedReceiver<(JNICommand, Option, String)>, + rsp_receiver: mpsc::UnboundedReceiver<(HalCallback, String)>, response_channel: Option<(UciResponseHandle, Retryer)>, state: UwbState, } @@ -200,8 +205,8 @@ struct Driver { async fn drive( adaptation: SyncUwbAdaptation, event_manager: T, - cmd_receiver: mpsc::UnboundedReceiver<(JNICommand, Option)>, - rsp_receiver: mpsc::UnboundedReceiver, + cmd_receiver: mpsc::UnboundedReceiver<(JNICommand, Option, String)>, + rsp_receiver: mpsc::UnboundedReceiver<(HalCallback, String)>, ) -> Result<()> { Driver::new(adaptation, event_manager, cmd_receiver, rsp_receiver).await.drive().await } @@ -213,8 +218,8 @@ impl Driver { async fn new( adaptation: SyncUwbAdaptation, event_manager: T, - cmd_receiver: mpsc::UnboundedReceiver<(JNICommand, Option)>, - rsp_receiver: mpsc::UnboundedReceiver, + cmd_receiver: mpsc::UnboundedReceiver<(JNICommand, Option, String)>, + rsp_receiver: mpsc::UnboundedReceiver<(HalCallback, String)>, ) -> Self { Self { adaptation, @@ -241,6 +246,7 @@ impl Driver { &mut self, tx: oneshot::Sender, cmd: JNICommand, + chip_id: String, ) -> Result<()> { log::debug!("Received blocking cmd {:?}", cmd); let command: UciCommandPacket = match cmd { @@ -307,24 +313,28 @@ impl Driver { let retryer = Retryer::new(); self.response_channel = Some((tx, retryer.clone())); - retryer.send_with_retry(self.adaptation.clone(), command); + retryer.send_with_retry(self.adaptation.clone(), command, chip_id); self.set_state(UwbState::W4UciResp); Ok(()) } - async fn handle_non_blocking_jni_cmd(&mut self, cmd: JNICommand) -> Result<()> { + async fn handle_non_blocking_jni_cmd( + &mut self, + cmd: JNICommand, + chip_id: String, + ) -> Result<()> { log::debug!("Received non blocking cmd {:?}", cmd); match cmd { JNICommand::Enable => { - self.adaptation.hal_open().await?; - self.adaptation.core_initialization().await?; + self.adaptation.hal_open(&chip_id).await?; + self.adaptation.core_initialization(&chip_id).await?; self.set_state(UwbState::W4HalOpen); } - JNICommand::Disable(_graceful) => match self.adaptation.hal_close().await { + JNICommand::Disable(_graceful) => match self.adaptation.hal_close(&chip_id).await { Ok(()) => self.set_state(UwbState::W4HalClose), Err(e) => { error!("Recevied HAL close failure: {:?}", e); - self.set_state(UwbState::None); + self.set_state(UwbState::None); // TODO(b/239965873): state should be per-chip return Err(UwbErr::Exit); } }, @@ -333,7 +343,11 @@ impl Driver { Ok(()) } - async fn handle_hal_notification(&self, response: uci_hrcv::UciNotification) -> Result<()> { + async fn handle_hal_notification( + &self, + response: uci_hrcv::UciNotification, + chip_id: String, + ) -> Result<()> { log::debug!("Received hal notification {:?}", response); match response { uci_hrcv::UciNotification::DeviceStatusNtf(response) => { @@ -348,7 +362,7 @@ impl Driver { self.event_manager.core_generic_error_notification_received(response)?; } uci_hrcv::UciNotification::SessionStatusNtf(response) => { - self.invoke_hal_session_init_if_necessary(&response).await; + self.invoke_hal_session_init_if_necessary(&response, chip_id).await; self.event_manager.session_status_notification_received(response)?; } uci_hrcv::UciNotification::ShortMacTwoWayRangeDataNtf(response) => { @@ -379,17 +393,17 @@ impl Driver { } // Note: If a blocking command is awaiting a response, any non-blocking commands are not // dequeued until the blocking cmd's response is received. - Some((cmd, tx)) = self.cmd_receiver.recv(), if self.can_process_cmd() => { + Some((cmd, tx, chip_id)) = self.cmd_receiver.recv(), if self.can_process_cmd() => { match tx { Some(tx) => { // Blocking JNI commands processing. - self.handle_blocking_jni_cmd(tx, cmd).await?; + self.handle_blocking_jni_cmd(tx, cmd, chip_id).await?; }, None => { // Non Blocking JNI commands processing. - self.handle_non_blocking_jni_cmd(cmd).await?; + self.handle_non_blocking_jni_cmd(cmd, chip_id).await?; } } } - Some(rsp) = self.rsp_receiver.recv() => { + Some((rsp, chip_id)) = self.rsp_receiver.recv() => { match rsp { HalCallback::Event{event, event_status} => { log::info!("Received HAL event: {:?} with status: {:?}", event, event_status); @@ -423,7 +437,7 @@ impl Driver { } }, HalCallback::UciNtf(response) => { - self.handle_hal_notification(response).await?; + self.handle_hal_notification(response, chip_id).await?; } } } @@ -432,7 +446,11 @@ impl Driver { } // Triggers the session init HAL API, if a new session is initialized. - async fn invoke_hal_session_init_if_necessary(&self, response: &SessionStatusNtfPacket) { + async fn invoke_hal_session_init_if_necessary( + &self, + response: &SessionStatusNtfPacket, + chip_id: String, + ) { if let SessionState::SessionStateInit = response.get_session_state() { info!( "Session {:?} initialized, invoking session init HAL API", @@ -440,7 +458,7 @@ impl Driver { ); self.adaptation // HAL API accepts signed int, so cast received session_id as i32. - .session_initialization(response.get_session_id() as i32) + .session_initialization(response.get_session_id() as i32, &chip_id) .await .unwrap_or_else(|e| error!("Error invoking session init HAL API : {:?}", e)); } @@ -457,8 +475,8 @@ impl Driver { } pub trait Dispatcher { - fn send_jni_command(&self, cmd: JNICommand) -> Result<()>; - fn block_on_jni_command(&self, cmd: JNICommand) -> Result; + fn send_jni_command(&self, cmd: JNICommand, chip_id: String) -> Result<()>; + fn block_on_jni_command(&self, cmd: JNICommand, chip_id: String) -> Result; fn wait_for_exit(&mut self) -> Result<()>; fn get_device_info(&self) -> &Option; fn set_device_info(&mut self, device_info: Option); @@ -466,18 +484,23 @@ pub trait Dispatcher { // Controller for sending tasks for the native thread to handle. pub struct DispatcherImpl { - cmd_sender: mpsc::UnboundedSender<(JNICommand, Option)>, + cmd_sender: mpsc::UnboundedSender<(JNICommand, Option, String)>, join_handle: task::JoinHandle>, runtime: Runtime, device_info: Option, } impl DispatcherImpl { - pub fn new(event_manager: T) -> Result { - let (rsp_sender, rsp_receiver) = mpsc::unbounded_channel::(); + pub fn new( + event_manager: T, + chip_ids: Vec, + ) -> Result { + let (rsp_sender, rsp_receiver) = mpsc::unbounded_channel::<(HalCallback, String)>(); // TODO when simplifying constructors, avoid spare runtime let adaptation: SyncUwbAdaptation = Arc::new( - Builder::new_current_thread().build()?.block_on(UwbAdaptationImpl::new(rsp_sender))?, + Builder::new_current_thread() + .build()? + .block_on(UwbAdaptationImpl::new(rsp_sender, &chip_ids))?, ); Self::new_with_args(event_manager, adaptation, rsp_receiver) @@ -486,7 +509,7 @@ impl DispatcherImpl { pub fn new_for_testing( event_manager: T, adaptation: SyncUwbAdaptation, - rsp_receiver: mpsc::UnboundedReceiver, + rsp_receiver: mpsc::UnboundedReceiver<(HalCallback, String)>, ) -> Result { Self::new_with_args(event_manager, adaptation, rsp_receiver) } @@ -494,11 +517,11 @@ impl DispatcherImpl { fn new_with_args( event_manager: T, adaptation: SyncUwbAdaptation, - rsp_receiver: mpsc::UnboundedReceiver, + rsp_receiver: mpsc::UnboundedReceiver<(HalCallback, String)>, ) -> Result { info!("initializing dispatcher"); let (cmd_sender, cmd_receiver) = - mpsc::unbounded_channel::<(JNICommand, Option)>(); + mpsc::unbounded_channel::<(JNICommand, Option, String)>(); // We create a new thread here both to avoid reusing the Java service thread and because // binder threads will call into this. @@ -507,6 +530,7 @@ impl DispatcherImpl { .thread_name("uwb-uci-handler") .enable_all() .build()?; + let join_handle = runtime.spawn(drive(adaptation, event_manager, cmd_receiver, rsp_receiver)); Ok(DispatcherImpl { cmd_sender, join_handle, runtime, device_info: None }) @@ -514,16 +538,16 @@ impl DispatcherImpl { } impl Dispatcher for DispatcherImpl { - fn send_jni_command(&self, cmd: JNICommand) -> Result<()> { - self.cmd_sender.send((cmd, None))?; + fn send_jni_command(&self, cmd: JNICommand, chip_id: String) -> Result<()> { + self.cmd_sender.send((cmd, None, chip_id))?; Ok(()) } // TODO: Consider implementing these separate for different commands so we can have more // specific return types. - fn block_on_jni_command(&self, cmd: JNICommand) -> Result { + fn block_on_jni_command(&self, cmd: JNICommand, chip_id: String) -> Result { let (tx, rx) = oneshot::channel(); - self.cmd_sender.send((cmd, Some(tx)))?; + self.cmd_sender.send((cmd, Some(tx), chip_id))?; let ret = self.runtime.block_on(rx)?; log::trace!("{:?}", ret); Ok(ret) @@ -566,13 +590,13 @@ mod tests { fn setup_dispatcher_and_return_hal_cb_sender( config_fn: fn(&mut Arc, &mut MockEventManager), - ) -> (DispatcherImpl, mpsc::UnboundedSender) { + ) -> (DispatcherImpl, mpsc::UnboundedSender<(HalCallback, String)>) { // TODO: Remove this once we call it somewhere real. logger::init( logger::Config::default().with_tag_on_device("uwb").with_min_level(log::Level::Debug), ); - let (rsp_sender, rsp_receiver) = mpsc::unbounded_channel::(); + let (rsp_sender, rsp_receiver) = mpsc::unbounded_channel::<(HalCallback, String)>(); let mut mock_adaptation = Arc::new(MockUwbAdaptation::new(rsp_sender.clone())); let mut mock_event_manager = MockEventManager::new(); @@ -612,7 +636,7 @@ mod tests { mock_adaptation.expect_core_initialization(Ok(())); }); - dispatcher.send_jni_command(JNICommand::Enable).unwrap(); + dispatcher.send_jni_command(JNICommand::Enable, String::from("chip_id")).unwrap(); } #[test] @@ -623,10 +647,14 @@ mod tests { mock_adaptation.expect_core_initialization(Ok(())); mock_event_manager.expect_device_status_notification_received(Ok(())); }); + let chip_id = String::from("chip_id"); - dispatcher.send_jni_command(JNICommand::Enable).unwrap(); + dispatcher.send_jni_command(JNICommand::Enable, chip_id.clone()).unwrap(); hal_sender - .send(HalCallback::Event { event: UwbEvent::ERROR, event_status: UwbStatus::FAILED }) + .send(( + HalCallback::Event { event: UwbEvent::ERROR, event_status: UwbStatus::FAILED }, + chip_id, + )) .unwrap(); } @@ -636,10 +664,14 @@ mod tests { setup_dispatcher_and_return_hal_cb_sender(|mock_adaptation, _mock_event_manager| { mock_adaptation.expect_hal_close(Ok(())); }); + let chip_id = String::from("chip_id"); - dispatcher.send_jni_command(JNICommand::Disable(true)).unwrap(); + dispatcher.send_jni_command(JNICommand::Disable(true), chip_id.clone()).unwrap(); hal_sender - .send(HalCallback::Event { event: UwbEvent::CLOSE_CPLT, event_status: UwbStatus::OK }) + .send(( + HalCallback::Event { event: UwbEvent::CLOSE_CPLT, event_status: UwbStatus::OK }, + chip_id, + )) .unwrap(); dispatcher.wait_for_exit().unwrap(); } @@ -657,7 +689,9 @@ mod tests { ); }); - dispatcher.block_on_jni_command(JNICommand::UciGetDeviceInfo).unwrap(); + dispatcher + .block_on_jni_command(JNICommand::UciGetDeviceInfo, String::from("chip_id")) + .unwrap(); } #[test] @@ -677,7 +711,9 @@ mod tests { ); }); - dispatcher.block_on_jni_command(JNICommand::UciGetDeviceInfo).unwrap(); + dispatcher + .block_on_jni_command(JNICommand::UciGetDeviceInfo, String::from("chip_id")) + .unwrap(); } #[test] @@ -694,7 +730,7 @@ mod tests { }); dispatcher - .block_on_jni_command(JNICommand::UciGetDeviceInfo) + .block_on_jni_command(JNICommand::UciGetDeviceInfo, String::from("chip_id")) .expect_err("This method should fail."); } @@ -713,7 +749,9 @@ mod tests { mock_event_manager.expect_device_status_notification_received(Ok(())); }); - dispatcher.block_on_jni_command(JNICommand::UciGetDeviceInfo).unwrap(); + dispatcher + .block_on_jni_command(JNICommand::UciGetDeviceInfo, String::from("chip_id")) + .unwrap(); } #[test] @@ -732,7 +770,9 @@ mod tests { ); }); - dispatcher.block_on_jni_command(JNICommand::UciGetCapsInfo).unwrap(); + dispatcher + .block_on_jni_command(JNICommand::UciGetCapsInfo, String::from("chip_id")) + .unwrap(); } #[test] @@ -754,10 +794,10 @@ mod tests { }); dispatcher - .block_on_jni_command(JNICommand::UciSessionInit( - 1, - SessionType::FiraRangingSession.to_u8().unwrap(), - )) + .block_on_jni_command( + JNICommand::UciSessionInit(1, SessionType::FiraRangingSession.to_u8().unwrap()), + String::from("chip_id"), + ) .unwrap(); } @@ -775,7 +815,9 @@ mod tests { ); }); - dispatcher.block_on_jni_command(JNICommand::UciSessionDeinit(1)).unwrap(); + dispatcher + .block_on_jni_command(JNICommand::UciSessionDeinit(1), String::from("chip_id")) + .unwrap(); } #[test] @@ -794,7 +836,9 @@ mod tests { ); }); - dispatcher.block_on_jni_command(JNICommand::UciSessionGetCount).unwrap(); + dispatcher + .block_on_jni_command(JNICommand::UciSessionGetCount, String::from("chip_id")) + .unwrap(); } #[test] @@ -811,7 +855,9 @@ mod tests { ); }); - dispatcher.block_on_jni_command(JNICommand::UciStartRange(5)).unwrap(); + dispatcher + .block_on_jni_command(JNICommand::UciStartRange(5), String::from("chip_id")) + .unwrap(); } #[test] @@ -828,7 +874,9 @@ mod tests { ); }); - dispatcher.block_on_jni_command(JNICommand::UciStopRange(5)).unwrap(); + dispatcher + .block_on_jni_command(JNICommand::UciStopRange(5), String::from("chip_id")) + .unwrap(); } #[test] @@ -849,7 +897,9 @@ mod tests { ); }); - dispatcher.block_on_jni_command(JNICommand::UciGetSessionState(5)).unwrap(); + dispatcher + .block_on_jni_command(JNICommand::UciGetSessionState(5), String::from("chip_id")) + .unwrap(); } #[test] @@ -875,13 +925,16 @@ mod tests { }); dispatcher - .block_on_jni_command(JNICommand::UciSessionUpdateMulticastList { - session_id: 5, - action: UpdateMulticastListAction::AddControlee.to_u8().unwrap(), - no_of_controlee: 0, - address_list: Vec::new(), - sub_session_id_list: Vec::new(), - }) + .block_on_jni_command( + JNICommand::UciSessionUpdateMulticastList { + session_id: 5, + action: UpdateMulticastListAction::AddControlee.to_u8().unwrap(), + no_of_controlee: 0, + address_list: Vec::new(), + sub_session_id_list: Vec::new(), + }, + String::from("chip_id"), + ) .unwrap(); } @@ -901,7 +954,10 @@ mod tests { }); dispatcher - .block_on_jni_command(JNICommand::UciSetCountryCode { code: vec![45, 34] }) + .block_on_jni_command( + JNICommand::UciSetCountryCode { code: vec![45, 34] }, + String::from("chip_id"), + ) .unwrap(); } @@ -924,12 +980,15 @@ mod tests { }); dispatcher - .block_on_jni_command(JNICommand::UciSetAppConfig { - session_id: 5, - no_of_params: 0, - app_config_param_len: 0, - app_configs: Vec::new(), - }) + .block_on_jni_command( + JNICommand::UciSetAppConfig { + session_id: 5, + no_of_params: 0, + app_config_param_len: 0, + app_configs: Vec::new(), + }, + String::from("chip_id"), + ) .unwrap(); } @@ -953,12 +1012,15 @@ mod tests { }); dispatcher - .block_on_jni_command(JNICommand::UciGetAppConfig { - session_id: 5, - no_of_params: 0, - app_config_param_len: 0, - app_configs: Vec::new(), - }) + .block_on_jni_command( + JNICommand::UciGetAppConfig { + session_id: 5, + no_of_params: 0, + app_config_param_len: 0, + app_configs: Vec::new(), + }, + String::from("chip_id"), + ) .unwrap(); } @@ -977,11 +1039,10 @@ mod tests { }); dispatcher - .block_on_jni_command(JNICommand::UciRawVendorCmd { - gid: 9, - oid: 5, - payload: Vec::new(), - }) + .block_on_jni_command( + JNICommand::UciRawVendorCmd { gid: 9, oid: 5, payload: Vec::new() }, + String::from("chip_id"), + ) .unwrap(); } @@ -999,7 +1060,12 @@ mod tests { ); }); - dispatcher.block_on_jni_command(JNICommand::UciDeviceReset { reset_config: 0 }).unwrap(); + dispatcher + .block_on_jni_command( + JNICommand::UciDeviceReset { reset_config: 0 }, + String::from("chip_id"), + ) + .unwrap(); } #[test] @@ -1025,6 +1091,8 @@ mod tests { ); }); - dispatcher.block_on_jni_command(JNICommand::UciGetPowerStats).unwrap(); + dispatcher + .block_on_jni_command(JNICommand::UciGetPowerStats, String::from("chip_id")) + .unwrap(); } } -- cgit v1.2.3