1 // Copyright 2022, The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 use std::collections::VecDeque; 16 use std::sync::{Arc, Mutex}; 17 use std::time::Duration; 18 19 use async_trait::async_trait; 20 use log::error; 21 use tokio::sync::{mpsc, Notify}; 22 use tokio::time::timeout; 23 24 use crate::error::{Error, Result}; 25 use crate::params::uci_packets::SessionId; 26 use crate::uci::command::UciCommand; 27 use crate::uci::uci_hal::{UciHal, UciHalPacket}; 28 29 /// The mock implementation of UciHal. 30 #[derive(Default, Clone)] 31 pub struct MockUciHal { 32 // Wrap inside Arc<Mutex<>> so that the MockUciHal.clone(s) refer to the same object. 33 packet_sender: Arc<Mutex<Option<mpsc::UnboundedSender<UciHalPacket>>>>, 34 expected_calls: Arc<Mutex<VecDeque<ExpectedCall>>>, 35 expect_call_consumed: Arc<Notify>, 36 } 37 38 impl MockUciHal { new() -> Self39 pub fn new() -> Self { 40 Default::default() 41 } 42 expected_open(&mut self, packets: Option<Vec<UciHalPacket>>, out: Result<()>)43 pub fn expected_open(&mut self, packets: Option<Vec<UciHalPacket>>, out: Result<()>) { 44 self.expected_calls.lock().unwrap().push_back(ExpectedCall::Open { packets, out }); 45 } 46 expected_close(&mut self, out: Result<()>)47 pub fn expected_close(&mut self, out: Result<()>) { 48 self.expected_calls.lock().unwrap().push_back(ExpectedCall::Close { out }); 49 } 50 expected_send_command( &mut self, expected_cmd: UciCommand, packets: Vec<UciHalPacket>, out: Result<()>, )51 pub fn expected_send_command( 52 &mut self, 53 expected_cmd: UciCommand, 54 packets: Vec<UciHalPacket>, 55 out: Result<()>, 56 ) { 57 self.expected_calls.lock().unwrap().push_back(ExpectedCall::SendCommand { 58 expected_cmd, 59 packets, 60 out, 61 }); 62 } 63 expected_send_packet( &mut self, expected_packet_tx: UciHalPacket, inject_packets_rx: Vec<UciHalPacket>, out: Result<()>, )64 pub fn expected_send_packet( 65 &mut self, 66 expected_packet_tx: UciHalPacket, 67 inject_packets_rx: Vec<UciHalPacket>, 68 out: Result<()>, 69 ) { 70 self.expected_calls.lock().unwrap().push_back(ExpectedCall::SendPacket { 71 expected_packet_tx, 72 inject_packets_rx, 73 out, 74 }); 75 } 76 expected_notify_session_initialized( &mut self, expected_session_id: SessionId, out: Result<()>, )77 pub fn expected_notify_session_initialized( 78 &mut self, 79 expected_session_id: SessionId, 80 out: Result<()>, 81 ) { 82 self.expected_calls 83 .lock() 84 .unwrap() 85 .push_back(ExpectedCall::NotifySessionInitialized { expected_session_id, out }); 86 } 87 wait_expected_calls_done(&mut self) -> bool88 pub async fn wait_expected_calls_done(&mut self) -> bool { 89 while !self.expected_calls.lock().unwrap().is_empty() { 90 if timeout(Duration::from_secs(1), self.expect_call_consumed.notified()).await.is_err() 91 { 92 return false; 93 } 94 } 95 true 96 } 97 98 // Receive a UCI packet (eg: UCI DATA_MESSAGE_RCV), from UWBS to Host. receive_packet(&mut self, packet: UciHalPacket) -> Result<()>99 pub fn receive_packet(&mut self, packet: UciHalPacket) -> Result<()> { 100 if let Some(ref ps) = *self.packet_sender.lock().unwrap() { 101 match ps.send(packet) { 102 Ok(_) => Ok(()), 103 Err(_) => Err(Error::Unknown), 104 } 105 } else { 106 error!("MockUciHal unable to Rx packet from HAL as channel closed"); 107 Err(Error::MockUndefined) 108 } 109 } 110 } 111 112 #[async_trait] 113 impl UciHal for MockUciHal { open(&mut self, packet_sender: mpsc::UnboundedSender<UciHalPacket>) -> Result<()>114 async fn open(&mut self, packet_sender: mpsc::UnboundedSender<UciHalPacket>) -> Result<()> { 115 let mut expected_calls = self.expected_calls.lock().unwrap(); 116 match expected_calls.pop_front() { 117 Some(ExpectedCall::Open { packets, out }) => { 118 self.expect_call_consumed.notify_one(); 119 if let Some(packets) = packets { 120 for msg in packets.into_iter() { 121 let _ = packet_sender.send(msg); 122 } 123 } 124 if out.is_ok() { 125 self.packet_sender.lock().unwrap().replace(packet_sender); 126 } 127 out 128 } 129 Some(call) => { 130 expected_calls.push_front(call); 131 Err(Error::MockUndefined) 132 } 133 None => Err(Error::MockUndefined), 134 } 135 } 136 close(&mut self) -> Result<()>137 async fn close(&mut self) -> Result<()> { 138 let mut expected_calls = self.expected_calls.lock().unwrap(); 139 match expected_calls.pop_front() { 140 Some(ExpectedCall::Close { out }) => { 141 self.expect_call_consumed.notify_one(); 142 if out.is_ok() { 143 *self.packet_sender.lock().unwrap() = None; 144 } 145 out 146 } 147 Some(call) => { 148 expected_calls.push_front(call); 149 Err(Error::MockUndefined) 150 } 151 None => Err(Error::MockUndefined), 152 } 153 } 154 send_command(&mut self, cmd: UciCommand) -> Result<()>155 async fn send_command(&mut self, cmd: UciCommand) -> Result<()> { 156 let mut expected_calls = self.expected_calls.lock().unwrap(); 157 match expected_calls.pop_front() { 158 Some(ExpectedCall::SendCommand { expected_cmd, packets, out }) 159 if expected_cmd == cmd => 160 { 161 self.expect_call_consumed.notify_one(); 162 let mut packet_sender_opt = self.packet_sender.lock().unwrap(); 163 let packet_sender = packet_sender_opt.as_mut().unwrap(); 164 for msg in packets.into_iter() { 165 let _ = packet_sender.send(msg); 166 } 167 out 168 } 169 Some(call) => { 170 expected_calls.push_front(call); 171 Err(Error::MockUndefined) 172 } 173 None => Err(Error::MockUndefined), 174 } 175 } 176 send_packet(&mut self, packet_tx: UciHalPacket) -> Result<()>177 async fn send_packet(&mut self, packet_tx: UciHalPacket) -> Result<()> { 178 // send_packet() will be directly called for sending UCI Data packets. 179 let mut expected_calls = self.expected_calls.lock().unwrap(); 180 match expected_calls.pop_front() { 181 Some(ExpectedCall::SendPacket { expected_packet_tx, inject_packets_rx, out }) 182 if expected_packet_tx == packet_tx => 183 { 184 self.expect_call_consumed.notify_one(); 185 let mut packet_sender_opt = self.packet_sender.lock().unwrap(); 186 let packet_sender = packet_sender_opt.as_mut().unwrap(); 187 for msg in inject_packets_rx.into_iter() { 188 let _ = packet_sender.send(msg); 189 } 190 out 191 } 192 Some(call) => { 193 expected_calls.push_front(call); 194 Err(Error::MockUndefined) 195 } 196 None => Err(Error::MockUndefined), 197 } 198 } 199 notify_session_initialized(&mut self, session_id: SessionId) -> Result<()>200 async fn notify_session_initialized(&mut self, session_id: SessionId) -> Result<()> { 201 let mut expected_calls = self.expected_calls.lock().unwrap(); 202 match expected_calls.pop_front() { 203 Some(ExpectedCall::NotifySessionInitialized { expected_session_id, out }) 204 if expected_session_id == session_id => 205 { 206 self.expect_call_consumed.notify_one(); 207 out 208 } 209 Some(call) => { 210 expected_calls.push_front(call); 211 Err(Error::MockUndefined) 212 } 213 None => Err(Error::MockUndefined), 214 } 215 } 216 } 217 218 enum ExpectedCall { 219 Open { 220 packets: Option<Vec<UciHalPacket>>, 221 out: Result<()>, 222 }, 223 Close { 224 out: Result<()>, 225 }, 226 SendCommand { 227 expected_cmd: UciCommand, 228 packets: Vec<UciHalPacket>, 229 out: Result<()>, 230 }, 231 SendPacket { 232 expected_packet_tx: UciHalPacket, 233 inject_packets_rx: Vec<UciHalPacket>, 234 out: Result<()>, 235 }, 236 NotifySessionInitialized { 237 expected_session_id: SessionId, 238 out: Result<()>, 239 }, 240 } 241