xref: /aosp_15_r20/tools/netsim/rust/daemon/src/devices/device.rs (revision cf78ab8cffb8fc9207af348f23af247fb04370a6)
1*cf78ab8cSAndroid Build Coastguard Worker // Copyright 2023 Google LLC
2*cf78ab8cSAndroid Build Coastguard Worker //
3*cf78ab8cSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*cf78ab8cSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*cf78ab8cSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*cf78ab8cSAndroid Build Coastguard Worker //
7*cf78ab8cSAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*cf78ab8cSAndroid Build Coastguard Worker //
9*cf78ab8cSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*cf78ab8cSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*cf78ab8cSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*cf78ab8cSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*cf78ab8cSAndroid Build Coastguard Worker // limitations under the License.
14*cf78ab8cSAndroid Build Coastguard Worker 
15*cf78ab8cSAndroid Build Coastguard Worker // Device.rs
16*cf78ab8cSAndroid Build Coastguard Worker 
17*cf78ab8cSAndroid Build Coastguard Worker use crate::devices::chip;
18*cf78ab8cSAndroid Build Coastguard Worker use crate::devices::chip::Chip;
19*cf78ab8cSAndroid Build Coastguard Worker use crate::devices::chip::ChipIdentifier;
20*cf78ab8cSAndroid Build Coastguard Worker use crate::devices::devices_handler::PoseManager;
21*cf78ab8cSAndroid Build Coastguard Worker use crate::wireless::WirelessAdaptorImpl;
22*cf78ab8cSAndroid Build Coastguard Worker use netsim_proto::common::ChipKind as ProtoChipKind;
23*cf78ab8cSAndroid Build Coastguard Worker use netsim_proto::frontend::patch_device_request::PatchDeviceFields as ProtoPatchDeviceFields;
24*cf78ab8cSAndroid Build Coastguard Worker use netsim_proto::model::Device as ProtoDevice;
25*cf78ab8cSAndroid Build Coastguard Worker use netsim_proto::stats::NetsimRadioStats as ProtoRadioStats;
26*cf78ab8cSAndroid Build Coastguard Worker use std::collections::BTreeMap;
27*cf78ab8cSAndroid Build Coastguard Worker use std::fmt;
28*cf78ab8cSAndroid Build Coastguard Worker use std::sync::atomic::{AtomicBool, Ordering};
29*cf78ab8cSAndroid Build Coastguard Worker use std::sync::{Arc, RwLock};
30*cf78ab8cSAndroid Build Coastguard Worker 
31*cf78ab8cSAndroid Build Coastguard Worker #[derive(Clone, Copy, Default, Eq, Hash, Ord, PartialOrd, PartialEq)]
32*cf78ab8cSAndroid Build Coastguard Worker pub struct DeviceIdentifier(pub u32);
33*cf78ab8cSAndroid Build Coastguard Worker 
34*cf78ab8cSAndroid Build Coastguard Worker impl fmt::Display for DeviceIdentifier {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result35*cf78ab8cSAndroid Build Coastguard Worker     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36*cf78ab8cSAndroid Build Coastguard Worker         write!(f, "{}", self.0)
37*cf78ab8cSAndroid Build Coastguard Worker     }
38*cf78ab8cSAndroid Build Coastguard Worker }
39*cf78ab8cSAndroid Build Coastguard Worker 
40*cf78ab8cSAndroid Build Coastguard Worker impl fmt::Debug for DeviceIdentifier {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result41*cf78ab8cSAndroid Build Coastguard Worker     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42*cf78ab8cSAndroid Build Coastguard Worker         write!(f, "{}", self.0)
43*cf78ab8cSAndroid Build Coastguard Worker     }
44*cf78ab8cSAndroid Build Coastguard Worker }
45*cf78ab8cSAndroid Build Coastguard Worker 
46*cf78ab8cSAndroid Build Coastguard Worker pub struct Device {
47*cf78ab8cSAndroid Build Coastguard Worker     pub id: DeviceIdentifier,
48*cf78ab8cSAndroid Build Coastguard Worker     pub guid: String,
49*cf78ab8cSAndroid Build Coastguard Worker     pub name: String,
50*cf78ab8cSAndroid Build Coastguard Worker     pub visible: AtomicBool,
51*cf78ab8cSAndroid Build Coastguard Worker     pub chips: RwLock<BTreeMap<ChipIdentifier, Arc<Chip>>>,
52*cf78ab8cSAndroid Build Coastguard Worker     pub builtin: bool,
53*cf78ab8cSAndroid Build Coastguard Worker }
54*cf78ab8cSAndroid Build Coastguard Worker impl Device {
new( id: DeviceIdentifier, guid: impl Into<String>, name: impl Into<String>, builtin: bool, ) -> Self55*cf78ab8cSAndroid Build Coastguard Worker     pub fn new(
56*cf78ab8cSAndroid Build Coastguard Worker         id: DeviceIdentifier,
57*cf78ab8cSAndroid Build Coastguard Worker         guid: impl Into<String>,
58*cf78ab8cSAndroid Build Coastguard Worker         name: impl Into<String>,
59*cf78ab8cSAndroid Build Coastguard Worker         builtin: bool,
60*cf78ab8cSAndroid Build Coastguard Worker     ) -> Self {
61*cf78ab8cSAndroid Build Coastguard Worker         Device {
62*cf78ab8cSAndroid Build Coastguard Worker             id,
63*cf78ab8cSAndroid Build Coastguard Worker             guid: guid.into(),
64*cf78ab8cSAndroid Build Coastguard Worker             name: name.into(),
65*cf78ab8cSAndroid Build Coastguard Worker             visible: AtomicBool::new(true),
66*cf78ab8cSAndroid Build Coastguard Worker             chips: RwLock::new(BTreeMap::new()),
67*cf78ab8cSAndroid Build Coastguard Worker             builtin,
68*cf78ab8cSAndroid Build Coastguard Worker         }
69*cf78ab8cSAndroid Build Coastguard Worker     }
70*cf78ab8cSAndroid Build Coastguard Worker }
71*cf78ab8cSAndroid Build Coastguard Worker 
72*cf78ab8cSAndroid Build Coastguard Worker #[derive(Debug, Clone)]
73*cf78ab8cSAndroid Build Coastguard Worker pub struct AddChipResult {
74*cf78ab8cSAndroid Build Coastguard Worker     pub device_id: DeviceIdentifier,
75*cf78ab8cSAndroid Build Coastguard Worker     pub chip_id: ChipIdentifier,
76*cf78ab8cSAndroid Build Coastguard Worker }
77*cf78ab8cSAndroid Build Coastguard Worker 
78*cf78ab8cSAndroid Build Coastguard Worker impl Device {
get(&self, pose_manager: Arc<PoseManager>) -> Result<ProtoDevice, String>79*cf78ab8cSAndroid Build Coastguard Worker     pub fn get(&self, pose_manager: Arc<PoseManager>) -> Result<ProtoDevice, String> {
80*cf78ab8cSAndroid Build Coastguard Worker         let mut device = ProtoDevice::new();
81*cf78ab8cSAndroid Build Coastguard Worker         device.id = self.id.0;
82*cf78ab8cSAndroid Build Coastguard Worker         device.name.clone_from(&self.name);
83*cf78ab8cSAndroid Build Coastguard Worker         device.visible = Some(self.visible.load(Ordering::SeqCst));
84*cf78ab8cSAndroid Build Coastguard Worker         device.position = protobuf::MessageField::from(pose_manager.get_position(&self.id));
85*cf78ab8cSAndroid Build Coastguard Worker         device.orientation = protobuf::MessageField::from(pose_manager.get_orientation(&self.id));
86*cf78ab8cSAndroid Build Coastguard Worker         for chip in self.chips.read().unwrap().values() {
87*cf78ab8cSAndroid Build Coastguard Worker             device.chips.push(chip.get()?);
88*cf78ab8cSAndroid Build Coastguard Worker         }
89*cf78ab8cSAndroid Build Coastguard Worker         Ok(device)
90*cf78ab8cSAndroid Build Coastguard Worker     }
91*cf78ab8cSAndroid Build Coastguard Worker 
92*cf78ab8cSAndroid Build Coastguard Worker     /// Patch a device and its chips.
patch( &self, patch: &ProtoPatchDeviceFields, pose_manager: Arc<PoseManager>, ) -> Result<(), String>93*cf78ab8cSAndroid Build Coastguard Worker     pub fn patch(
94*cf78ab8cSAndroid Build Coastguard Worker         &self,
95*cf78ab8cSAndroid Build Coastguard Worker         patch: &ProtoPatchDeviceFields,
96*cf78ab8cSAndroid Build Coastguard Worker         pose_manager: Arc<PoseManager>,
97*cf78ab8cSAndroid Build Coastguard Worker     ) -> Result<(), String> {
98*cf78ab8cSAndroid Build Coastguard Worker         if patch.visible.is_some() {
99*cf78ab8cSAndroid Build Coastguard Worker             self.visible.store(patch.visible.unwrap(), Ordering::SeqCst);
100*cf78ab8cSAndroid Build Coastguard Worker         }
101*cf78ab8cSAndroid Build Coastguard Worker         if patch.position.is_some() {
102*cf78ab8cSAndroid Build Coastguard Worker             pose_manager.set_position(self.id, &patch.position);
103*cf78ab8cSAndroid Build Coastguard Worker         }
104*cf78ab8cSAndroid Build Coastguard Worker         if patch.orientation.is_some() {
105*cf78ab8cSAndroid Build Coastguard Worker             pose_manager.set_orientation(self.id, &patch.orientation);
106*cf78ab8cSAndroid Build Coastguard Worker         }
107*cf78ab8cSAndroid Build Coastguard Worker         // iterate over patched ProtoChip entries and patch matching chip
108*cf78ab8cSAndroid Build Coastguard Worker         for patch_chip in patch.chips.iter() {
109*cf78ab8cSAndroid Build Coastguard Worker             let mut patch_chip_kind = patch_chip.kind.enum_value_or_default();
110*cf78ab8cSAndroid Build Coastguard Worker             // Check if chip is given when kind is not given.
111*cf78ab8cSAndroid Build Coastguard Worker             // TODO: Fix patch device request body in CLI to include ChipKind, and remove if block below.
112*cf78ab8cSAndroid Build Coastguard Worker             if patch_chip_kind == ProtoChipKind::UNSPECIFIED {
113*cf78ab8cSAndroid Build Coastguard Worker                 if patch_chip.has_bt() {
114*cf78ab8cSAndroid Build Coastguard Worker                     patch_chip_kind = ProtoChipKind::BLUETOOTH;
115*cf78ab8cSAndroid Build Coastguard Worker                 } else if patch_chip.has_ble_beacon() {
116*cf78ab8cSAndroid Build Coastguard Worker                     patch_chip_kind = ProtoChipKind::BLUETOOTH_BEACON;
117*cf78ab8cSAndroid Build Coastguard Worker                 } else if patch_chip.has_wifi() {
118*cf78ab8cSAndroid Build Coastguard Worker                     patch_chip_kind = ProtoChipKind::WIFI;
119*cf78ab8cSAndroid Build Coastguard Worker                 } else if patch_chip.has_uwb() {
120*cf78ab8cSAndroid Build Coastguard Worker                     patch_chip_kind = ProtoChipKind::UWB;
121*cf78ab8cSAndroid Build Coastguard Worker                 } else {
122*cf78ab8cSAndroid Build Coastguard Worker                     break;
123*cf78ab8cSAndroid Build Coastguard Worker                 }
124*cf78ab8cSAndroid Build Coastguard Worker             }
125*cf78ab8cSAndroid Build Coastguard Worker             let patch_chip_name = &patch_chip.name;
126*cf78ab8cSAndroid Build Coastguard Worker             // Find the matching chip and patch the proto chip
127*cf78ab8cSAndroid Build Coastguard Worker             let target = self.match_target_chip(patch_chip_kind, patch_chip_name)?;
128*cf78ab8cSAndroid Build Coastguard Worker             match target {
129*cf78ab8cSAndroid Build Coastguard Worker                 Some(chip) => chip.patch(patch_chip)?,
130*cf78ab8cSAndroid Build Coastguard Worker                 None => {
131*cf78ab8cSAndroid Build Coastguard Worker                     return Err(format!(
132*cf78ab8cSAndroid Build Coastguard Worker                         "Chip {} not found in device {}",
133*cf78ab8cSAndroid Build Coastguard Worker                         patch_chip_name, self.name
134*cf78ab8cSAndroid Build Coastguard Worker                     ))
135*cf78ab8cSAndroid Build Coastguard Worker                 }
136*cf78ab8cSAndroid Build Coastguard Worker             }
137*cf78ab8cSAndroid Build Coastguard Worker         }
138*cf78ab8cSAndroid Build Coastguard Worker         Ok(())
139*cf78ab8cSAndroid Build Coastguard Worker     }
140*cf78ab8cSAndroid Build Coastguard Worker 
match_target_chip( &self, patch_chip_kind: ProtoChipKind, patch_chip_name: &str, ) -> Result<Option<Arc<Chip>>, String>141*cf78ab8cSAndroid Build Coastguard Worker     fn match_target_chip(
142*cf78ab8cSAndroid Build Coastguard Worker         &self,
143*cf78ab8cSAndroid Build Coastguard Worker         patch_chip_kind: ProtoChipKind,
144*cf78ab8cSAndroid Build Coastguard Worker         patch_chip_name: &str,
145*cf78ab8cSAndroid Build Coastguard Worker     ) -> Result<Option<Arc<Chip>>, String> {
146*cf78ab8cSAndroid Build Coastguard Worker         let mut multiple_matches = false;
147*cf78ab8cSAndroid Build Coastguard Worker         let mut target: Option<Arc<Chip>> = None;
148*cf78ab8cSAndroid Build Coastguard Worker         for chip in self.chips.read().unwrap().values() {
149*cf78ab8cSAndroid Build Coastguard Worker             // Check for specified chip kind and matching chip name
150*cf78ab8cSAndroid Build Coastguard Worker             if chip.kind == patch_chip_kind && chip.name.contains(patch_chip_name) {
151*cf78ab8cSAndroid Build Coastguard Worker                 // Check for exact match
152*cf78ab8cSAndroid Build Coastguard Worker                 if chip.name == patch_chip_name {
153*cf78ab8cSAndroid Build Coastguard Worker                     multiple_matches = false;
154*cf78ab8cSAndroid Build Coastguard Worker                     target = Some(Arc::clone(chip));
155*cf78ab8cSAndroid Build Coastguard Worker                     break;
156*cf78ab8cSAndroid Build Coastguard Worker                 }
157*cf78ab8cSAndroid Build Coastguard Worker                 // Check for ambiguous match
158*cf78ab8cSAndroid Build Coastguard Worker                 if target.is_none() {
159*cf78ab8cSAndroid Build Coastguard Worker                     target = Some(Arc::clone(chip));
160*cf78ab8cSAndroid Build Coastguard Worker                 } else {
161*cf78ab8cSAndroid Build Coastguard Worker                     // Return if no chip name is supplied but multiple chips of specified kind exist
162*cf78ab8cSAndroid Build Coastguard Worker                     if patch_chip_name.is_empty() {
163*cf78ab8cSAndroid Build Coastguard Worker                         return Err(format!(
164*cf78ab8cSAndroid Build Coastguard Worker                             "No chip name is supplied but multiple chips of chip kind {:?} exist.",
165*cf78ab8cSAndroid Build Coastguard Worker                             chip.kind
166*cf78ab8cSAndroid Build Coastguard Worker                         ));
167*cf78ab8cSAndroid Build Coastguard Worker                     }
168*cf78ab8cSAndroid Build Coastguard Worker                     // Multiple matches were found - continue to look for possible exact match
169*cf78ab8cSAndroid Build Coastguard Worker                     multiple_matches = true;
170*cf78ab8cSAndroid Build Coastguard Worker                 }
171*cf78ab8cSAndroid Build Coastguard Worker             }
172*cf78ab8cSAndroid Build Coastguard Worker         }
173*cf78ab8cSAndroid Build Coastguard Worker         if multiple_matches {
174*cf78ab8cSAndroid Build Coastguard Worker             return Err(format!(
175*cf78ab8cSAndroid Build Coastguard Worker                 "Multiple ambiguous matches were found with chip name {}",
176*cf78ab8cSAndroid Build Coastguard Worker                 patch_chip_name
177*cf78ab8cSAndroid Build Coastguard Worker             ));
178*cf78ab8cSAndroid Build Coastguard Worker         }
179*cf78ab8cSAndroid Build Coastguard Worker         Ok(target)
180*cf78ab8cSAndroid Build Coastguard Worker     }
181*cf78ab8cSAndroid Build Coastguard Worker 
182*cf78ab8cSAndroid Build Coastguard Worker     /// Remove a chip from a device.
remove_chip(&self, chip_id: &ChipIdentifier) -> Result<Vec<ProtoRadioStats>, String>183*cf78ab8cSAndroid Build Coastguard Worker     pub fn remove_chip(&self, chip_id: &ChipIdentifier) -> Result<Vec<ProtoRadioStats>, String> {
184*cf78ab8cSAndroid Build Coastguard Worker         let radio_stats = self
185*cf78ab8cSAndroid Build Coastguard Worker             .chips
186*cf78ab8cSAndroid Build Coastguard Worker             .read()
187*cf78ab8cSAndroid Build Coastguard Worker             .unwrap()
188*cf78ab8cSAndroid Build Coastguard Worker             .get(chip_id)
189*cf78ab8cSAndroid Build Coastguard Worker             .ok_or(format!("RemoveChip chip id {chip_id} not found"))?
190*cf78ab8cSAndroid Build Coastguard Worker             .get_stats();
191*cf78ab8cSAndroid Build Coastguard Worker         // Chip and emulated chip will be dropped
192*cf78ab8cSAndroid Build Coastguard Worker         self.chips.write().unwrap().remove(chip_id);
193*cf78ab8cSAndroid Build Coastguard Worker         chip::remove_chip(chip_id);
194*cf78ab8cSAndroid Build Coastguard Worker         Ok(radio_stats)
195*cf78ab8cSAndroid Build Coastguard Worker     }
196*cf78ab8cSAndroid Build Coastguard Worker 
add_chip( &mut self, chip_create_params: &chip::CreateParams, chip_id: ChipIdentifier, wireless_adaptor: WirelessAdaptorImpl, ) -> Result<(DeviceIdentifier, ChipIdentifier), String>197*cf78ab8cSAndroid Build Coastguard Worker     pub fn add_chip(
198*cf78ab8cSAndroid Build Coastguard Worker         &mut self,
199*cf78ab8cSAndroid Build Coastguard Worker         chip_create_params: &chip::CreateParams,
200*cf78ab8cSAndroid Build Coastguard Worker         chip_id: ChipIdentifier,
201*cf78ab8cSAndroid Build Coastguard Worker         wireless_adaptor: WirelessAdaptorImpl,
202*cf78ab8cSAndroid Build Coastguard Worker     ) -> Result<(DeviceIdentifier, ChipIdentifier), String> {
203*cf78ab8cSAndroid Build Coastguard Worker         for chip in self.chips.read().unwrap().values() {
204*cf78ab8cSAndroid Build Coastguard Worker             if chip.kind == chip_create_params.kind
205*cf78ab8cSAndroid Build Coastguard Worker                 && chip_create_params.name.clone().is_some_and(|name| name == chip.name)
206*cf78ab8cSAndroid Build Coastguard Worker             {
207*cf78ab8cSAndroid Build Coastguard Worker                 return Err(format!("Device::AddChip - duplicate at id {}, skipping.", chip.id));
208*cf78ab8cSAndroid Build Coastguard Worker             }
209*cf78ab8cSAndroid Build Coastguard Worker         }
210*cf78ab8cSAndroid Build Coastguard Worker         let device_id = self.id;
211*cf78ab8cSAndroid Build Coastguard Worker         let chip = chip::new(chip_id, device_id, &self.name, chip_create_params, wireless_adaptor)?;
212*cf78ab8cSAndroid Build Coastguard Worker         self.chips.write().unwrap().insert(chip_id, chip);
213*cf78ab8cSAndroid Build Coastguard Worker 
214*cf78ab8cSAndroid Build Coastguard Worker         Ok((device_id, chip_id))
215*cf78ab8cSAndroid Build Coastguard Worker     }
216*cf78ab8cSAndroid Build Coastguard Worker 
217*cf78ab8cSAndroid Build Coastguard Worker     /// Reset a device to its default state.
reset(&self) -> Result<(), String>218*cf78ab8cSAndroid Build Coastguard Worker     pub fn reset(&self) -> Result<(), String> {
219*cf78ab8cSAndroid Build Coastguard Worker         self.visible.store(true, Ordering::SeqCst);
220*cf78ab8cSAndroid Build Coastguard Worker         for chip in self.chips.read().unwrap().values() {
221*cf78ab8cSAndroid Build Coastguard Worker             chip.reset()?;
222*cf78ab8cSAndroid Build Coastguard Worker         }
223*cf78ab8cSAndroid Build Coastguard Worker         Ok(())
224*cf78ab8cSAndroid Build Coastguard Worker     }
225*cf78ab8cSAndroid Build Coastguard Worker }
226*cf78ab8cSAndroid Build Coastguard Worker 
227*cf78ab8cSAndroid Build Coastguard Worker #[cfg(test)]
228*cf78ab8cSAndroid Build Coastguard Worker mod tests {
229*cf78ab8cSAndroid Build Coastguard Worker     use super::*;
230*cf78ab8cSAndroid Build Coastguard Worker     use crate::wireless::mocked;
231*cf78ab8cSAndroid Build Coastguard Worker     use std::sync::atomic::{AtomicU32, Ordering};
232*cf78ab8cSAndroid Build Coastguard Worker     static PATCH_CHIP_KIND: ProtoChipKind = ProtoChipKind::BLUETOOTH;
233*cf78ab8cSAndroid Build Coastguard Worker     static TEST_DEVICE_NAME: &str = "test_device";
234*cf78ab8cSAndroid Build Coastguard Worker     static TEST_CHIP_NAME_1: &str = "test-bt-chip-1";
235*cf78ab8cSAndroid Build Coastguard Worker     static TEST_CHIP_NAME_2: &str = "test-bt-chip-2";
236*cf78ab8cSAndroid Build Coastguard Worker     static IDS: AtomicU32 = AtomicU32::new(1000);
237*cf78ab8cSAndroid Build Coastguard Worker 
create_test_device() -> Result<Device, String>238*cf78ab8cSAndroid Build Coastguard Worker     fn create_test_device() -> Result<Device, String> {
239*cf78ab8cSAndroid Build Coastguard Worker         let mut device = Device::new(DeviceIdentifier(0), "0", TEST_DEVICE_NAME, false);
240*cf78ab8cSAndroid Build Coastguard Worker         let chip_id_1 = ChipIdentifier(IDS.fetch_add(1, Ordering::SeqCst));
241*cf78ab8cSAndroid Build Coastguard Worker         let chip_id_2 = ChipIdentifier(IDS.fetch_add(1, Ordering::SeqCst));
242*cf78ab8cSAndroid Build Coastguard Worker         device.add_chip(
243*cf78ab8cSAndroid Build Coastguard Worker             &chip::CreateParams {
244*cf78ab8cSAndroid Build Coastguard Worker                 kind: ProtoChipKind::BLUETOOTH,
245*cf78ab8cSAndroid Build Coastguard Worker                 address: "".to_string(),
246*cf78ab8cSAndroid Build Coastguard Worker                 name: Some(TEST_CHIP_NAME_1.to_string()),
247*cf78ab8cSAndroid Build Coastguard Worker                 manufacturer: "test_manufacturer".to_string(),
248*cf78ab8cSAndroid Build Coastguard Worker                 product_name: "test_product_name".to_string(),
249*cf78ab8cSAndroid Build Coastguard Worker             },
250*cf78ab8cSAndroid Build Coastguard Worker             chip_id_1,
251*cf78ab8cSAndroid Build Coastguard Worker             mocked::new(&mocked::CreateParams { chip_kind: ProtoChipKind::UNSPECIFIED }, chip_id_1),
252*cf78ab8cSAndroid Build Coastguard Worker         )?;
253*cf78ab8cSAndroid Build Coastguard Worker         device.add_chip(
254*cf78ab8cSAndroid Build Coastguard Worker             &chip::CreateParams {
255*cf78ab8cSAndroid Build Coastguard Worker                 kind: ProtoChipKind::BLUETOOTH,
256*cf78ab8cSAndroid Build Coastguard Worker                 address: "".to_string(),
257*cf78ab8cSAndroid Build Coastguard Worker                 name: Some(TEST_CHIP_NAME_2.to_string()),
258*cf78ab8cSAndroid Build Coastguard Worker                 manufacturer: "test_manufacturer".to_string(),
259*cf78ab8cSAndroid Build Coastguard Worker                 product_name: "test_product_name".to_string(),
260*cf78ab8cSAndroid Build Coastguard Worker             },
261*cf78ab8cSAndroid Build Coastguard Worker             chip_id_2,
262*cf78ab8cSAndroid Build Coastguard Worker             mocked::new(&mocked::CreateParams { chip_kind: ProtoChipKind::UNSPECIFIED }, chip_id_1),
263*cf78ab8cSAndroid Build Coastguard Worker         )?;
264*cf78ab8cSAndroid Build Coastguard Worker         Ok(device)
265*cf78ab8cSAndroid Build Coastguard Worker     }
266*cf78ab8cSAndroid Build Coastguard Worker 
267*cf78ab8cSAndroid Build Coastguard Worker     #[ignore = "TODO: include thread_id in names and ids"]
268*cf78ab8cSAndroid Build Coastguard Worker     #[test]
test_exact_target_match()269*cf78ab8cSAndroid Build Coastguard Worker     fn test_exact_target_match() {
270*cf78ab8cSAndroid Build Coastguard Worker         let device = create_test_device().unwrap();
271*cf78ab8cSAndroid Build Coastguard Worker         let result = device.match_target_chip(PATCH_CHIP_KIND, TEST_CHIP_NAME_1);
272*cf78ab8cSAndroid Build Coastguard Worker         assert!(result.is_ok());
273*cf78ab8cSAndroid Build Coastguard Worker         let target = result.unwrap();
274*cf78ab8cSAndroid Build Coastguard Worker         assert!(target.is_some());
275*cf78ab8cSAndroid Build Coastguard Worker         assert_eq!(target.unwrap().name, TEST_CHIP_NAME_1);
276*cf78ab8cSAndroid Build Coastguard Worker         assert_eq!(device.name, TEST_DEVICE_NAME);
277*cf78ab8cSAndroid Build Coastguard Worker     }
278*cf78ab8cSAndroid Build Coastguard Worker 
279*cf78ab8cSAndroid Build Coastguard Worker     #[ignore = "TODO: include thread_id in names and ids"]
280*cf78ab8cSAndroid Build Coastguard Worker     #[test]
test_substring_target_match()281*cf78ab8cSAndroid Build Coastguard Worker     fn test_substring_target_match() {
282*cf78ab8cSAndroid Build Coastguard Worker         let device = create_test_device().unwrap();
283*cf78ab8cSAndroid Build Coastguard Worker         let result = device.match_target_chip(PATCH_CHIP_KIND, "chip-1");
284*cf78ab8cSAndroid Build Coastguard Worker         assert!(result.is_ok());
285*cf78ab8cSAndroid Build Coastguard Worker         let target = result.unwrap();
286*cf78ab8cSAndroid Build Coastguard Worker         assert!(target.is_some());
287*cf78ab8cSAndroid Build Coastguard Worker         assert_eq!(target.unwrap().name, TEST_CHIP_NAME_1);
288*cf78ab8cSAndroid Build Coastguard Worker         assert_eq!(device.name, TEST_DEVICE_NAME);
289*cf78ab8cSAndroid Build Coastguard Worker     }
290*cf78ab8cSAndroid Build Coastguard Worker 
291*cf78ab8cSAndroid Build Coastguard Worker     #[ignore = "TODO: include thread_id in names and ids"]
292*cf78ab8cSAndroid Build Coastguard Worker     #[test]
test_ambiguous_target_match()293*cf78ab8cSAndroid Build Coastguard Worker     fn test_ambiguous_target_match() {
294*cf78ab8cSAndroid Build Coastguard Worker         let device = create_test_device().unwrap();
295*cf78ab8cSAndroid Build Coastguard Worker         let result = device.match_target_chip(PATCH_CHIP_KIND, "chip");
296*cf78ab8cSAndroid Build Coastguard Worker         assert!(result.is_err());
297*cf78ab8cSAndroid Build Coastguard Worker         assert_eq!(
298*cf78ab8cSAndroid Build Coastguard Worker             result.err(),
299*cf78ab8cSAndroid Build Coastguard Worker             Some("Multiple ambiguous matches were found with chip name chip".to_string())
300*cf78ab8cSAndroid Build Coastguard Worker         );
301*cf78ab8cSAndroid Build Coastguard Worker     }
302*cf78ab8cSAndroid Build Coastguard Worker 
303*cf78ab8cSAndroid Build Coastguard Worker     #[ignore = "TODO: include thread_id in names and ids"]
304*cf78ab8cSAndroid Build Coastguard Worker     #[test]
test_ambiguous_empty_target_match()305*cf78ab8cSAndroid Build Coastguard Worker     fn test_ambiguous_empty_target_match() {
306*cf78ab8cSAndroid Build Coastguard Worker         let device = create_test_device().unwrap();
307*cf78ab8cSAndroid Build Coastguard Worker         let result = device.match_target_chip(PATCH_CHIP_KIND, "");
308*cf78ab8cSAndroid Build Coastguard Worker         assert!(result.is_err());
309*cf78ab8cSAndroid Build Coastguard Worker         assert_eq!(
310*cf78ab8cSAndroid Build Coastguard Worker             result.err(),
311*cf78ab8cSAndroid Build Coastguard Worker             Some(format!(
312*cf78ab8cSAndroid Build Coastguard Worker                 "No chip name is supplied but multiple chips of chip kind {:?} exist.",
313*cf78ab8cSAndroid Build Coastguard Worker                 PATCH_CHIP_KIND
314*cf78ab8cSAndroid Build Coastguard Worker             ))
315*cf78ab8cSAndroid Build Coastguard Worker         );
316*cf78ab8cSAndroid Build Coastguard Worker     }
317*cf78ab8cSAndroid Build Coastguard Worker 
318*cf78ab8cSAndroid Build Coastguard Worker     #[ignore = "TODO: include thread_id in names and ids"]
319*cf78ab8cSAndroid Build Coastguard Worker     #[test]
test_no_target_match()320*cf78ab8cSAndroid Build Coastguard Worker     fn test_no_target_match() {
321*cf78ab8cSAndroid Build Coastguard Worker         let device = create_test_device().unwrap();
322*cf78ab8cSAndroid Build Coastguard Worker         let invalid_chip_name = "invalid-chip";
323*cf78ab8cSAndroid Build Coastguard Worker         let result = device.match_target_chip(PATCH_CHIP_KIND, invalid_chip_name);
324*cf78ab8cSAndroid Build Coastguard Worker         assert!(result.is_ok());
325*cf78ab8cSAndroid Build Coastguard Worker         let target = result.unwrap();
326*cf78ab8cSAndroid Build Coastguard Worker         assert!(target.is_none());
327*cf78ab8cSAndroid Build Coastguard Worker     }
328*cf78ab8cSAndroid Build Coastguard Worker }
329