blurmock/
fake_device.rs

1use core::ops::Deref;
2use fake_adapter::FakeBluetoothAdapter;
3use fake_service::FakeBluetoothGATTService;
4use hex;
5use std::collections::HashMap;
6use std::error::Error;
7use std::sync::{Arc, Mutex};
8
9#[derive(Clone, Debug)]
10pub struct FakeBluetoothDevice {
11    id: Arc<Mutex<String>>,
12    adapter: Arc<FakeBluetoothAdapter>,
13    address: Arc<Mutex<String>>,
14    appearance: Arc<Mutex<Option<u16>>>,
15    class: Arc<Mutex<u32>>,
16    gatt_services: Arc<Mutex<Vec<Arc<FakeBluetoothGATTService>>>>,
17    is_paired: Arc<Mutex<bool>>,
18    is_connectable: Arc<Mutex<bool>>,
19    is_connected: Arc<Mutex<bool>>,
20    is_trusted: Arc<Mutex<bool>>,
21    is_blocked: Arc<Mutex<bool>>,
22    is_legacy_pairing: Arc<Mutex<bool>>,
23    uuids: Arc<Mutex<Vec<String>>>,
24    name: Arc<Mutex<Option<String>>>,
25    icon: Arc<Mutex<String>>,
26    alias: Arc<Mutex<String>>,
27    product_version: Arc<Mutex<u32>>,
28    rssi: Arc<Mutex<Option<i16>>>,
29    tx_power: Arc<Mutex<Option<i16>>>,
30    modalias: Arc<Mutex<String>>,
31    manufacturer_data: Arc<Mutex<Option<HashMap<u16, Vec<u8>>>>>,
32    service_data: Arc<Mutex<Option<HashMap<String, Vec<u8>>>>>,
33}
34
35impl FakeBluetoothDevice {
36    pub fn new(id: String,
37               adapter: Arc<FakeBluetoothAdapter>,
38               address: String,
39               appearance: Option<u16>,
40               class: u32,
41               gatt_services: Vec<Arc<FakeBluetoothGATTService>>,
42               is_paired: bool,
43               is_connectable: bool,
44               is_connected: bool,
45               is_trusted: bool,
46               is_blocked: bool,
47               is_legacy_pairing: bool,
48               uuids: Vec<String>,
49               name: Option<String>,
50               icon: String,
51               alias: String,
52               product_version: u32,
53               rssi: Option<i16>,
54               tx_power: Option<i16>,
55               modalias: String,
56               manufacturer_data: Option<HashMap<u16, Vec<u8>>>,
57               service_data: Option<HashMap<String, Vec<u8>>>)
58               -> Arc<FakeBluetoothDevice> {
59        if let Ok(existing_device) = adapter.get_device(id.clone()) {
60            return existing_device;
61        }
62        let device = Arc::new(FakeBluetoothDevice{
63            id: Arc::new(Mutex::new(id)),
64            adapter: adapter.clone(),
65            address: Arc::new(Mutex::new(address)),
66            appearance: Arc::new(Mutex::new(appearance)),
67            class: Arc::new(Mutex::new(class)),
68            gatt_services: Arc::new(Mutex::new(gatt_services)),
69            is_paired: Arc::new(Mutex::new(is_paired)),
70            is_connectable: Arc::new(Mutex::new(is_connectable)),
71            is_connected: Arc::new(Mutex::new(is_connected)),
72            is_trusted: Arc::new(Mutex::new(is_trusted)),
73            is_blocked: Arc::new(Mutex::new(is_blocked)),
74            is_legacy_pairing: Arc::new(Mutex::new(is_legacy_pairing)),
75            uuids: Arc::new(Mutex::new(uuids)),
76            name: Arc::new(Mutex::new(name)),
77            icon: Arc::new(Mutex::new(icon)),
78            alias: Arc::new(Mutex::new(alias)),
79            product_version: Arc::new(Mutex::new(product_version)),
80            rssi: Arc::new(Mutex::new(rssi)),
81            tx_power: Arc::new(Mutex::new(tx_power)),
82            modalias: Arc::new(Mutex::new(modalias)),
83            manufacturer_data: Arc::new(Mutex::new(manufacturer_data)),
84            service_data: Arc::new(Mutex::new(service_data)),
85        });
86        let _ = adapter.add_device(device.clone());
87        device
88    }
89
90    pub fn new_empty(adapter: Arc<FakeBluetoothAdapter>, device_id: String)
91            -> Arc<FakeBluetoothDevice> {
92        FakeBluetoothDevice::new(
93            /*id*/ device_id,
94            /*adapter*/ adapter,
95            /*address*/ String::new(),
96            /*appearance*/ None,
97            /*class*/ 0,
98            /*gatt_services*/ vec!(),
99            /*is_paired*/ false,
100            /*is_connectable*/ false,
101            /*is_connected*/ false,
102            /*is_trusted*/ false,
103            /*is_blocked*/ false,
104            /*is_legacy_pairing*/ false,
105            /*uuids*/ vec!(),
106            /*name*/ None,
107            /*icon*/ String::new(),
108            /*alias*/ String::new(),
109            /*product_version*/ 0,
110            /*rssi*/ None,
111            /*tx_power*/ None,
112            /*modalias*/ String::new(),
113            /*manufacturer_data*/ None,
114            /*service_data*/ None,
115        )
116    }
117
118    make_getter!(get_id, id);
119
120    make_setter!(set_id, id);
121
122    make_getter!(get_address, address, String);
123
124    make_setter!(set_address, address, String);
125
126    make_option_getter!(get_name, name, String);
127
128    make_setter!(set_name, name, Option<String>);
129
130    make_getter!(get_icon, icon, String);
131
132    make_setter!(set_icon, icon, String);
133
134    make_getter!(get_class, class, u32);
135
136    make_setter!(set_class, class, u32);
137
138    make_option_getter!(get_appearance, appearance, u16);
139
140    make_setter!(set_appearance, appearance, Option<u16>);
141
142    make_getter!(get_uuids, uuids, Vec<String>);
143
144    make_setter!(set_uuids, uuids, Vec<String>);
145
146    make_getter!(is_paired);
147
148    make_setter!(set_paired, is_paired, bool);
149
150    make_getter!(is_connectable);
151
152    make_setter!(set_connectable, is_connectable, bool);
153
154    make_getter!(is_connected);
155
156    make_setter!(set_connected, is_connected, bool);
157
158    make_getter!(is_trusted);
159
160    make_setter!(set_trusted, is_trusted, bool);
161
162    make_getter!(is_blocked);
163
164    make_setter!(set_blocked, is_blocked, bool);
165
166    make_getter!(get_alias, alias, String);
167
168    make_setter!(set_alias, alias, String);
169
170    make_getter!(is_legacy_pairing);
171
172    make_setter!(set_legacy_pairing, is_legacy_pairing, bool);
173
174    make_setter!(set_modalias, modalias, String);
175
176    make_option_getter!(get_rssi, rssi, i16);
177
178    make_setter!(set_rssi, rssi, Option<i16>);
179
180    make_option_getter!(get_tx_power, tx_power, i16);
181
182    make_setter!(set_tx_power, tx_power, Option<i16>);
183
184    make_option_getter!(get_manufacturer_data, manufacturer_data, HashMap<u16, Vec<u8>>);
185
186    make_setter!(set_manufacturer_data, manufacturer_data, Option<HashMap<u16, Vec<u8>>>);
187
188    make_option_getter!(get_service_data, service_data, HashMap<String, Vec<u8>>);
189
190    make_setter!(set_service_data, service_data, Option<HashMap<String, Vec<u8>>>);
191
192    pub fn get_adapter(&self) -> Result<Arc<FakeBluetoothAdapter>, Box<Error>> {
193        Ok(self.adapter.clone())
194    }
195
196    pub fn pair(&self) -> Result<(), Box<Error>> {
197        self.set_paired(true)
198    }
199
200    pub fn cancel_pairing(&self) -> Result<(), Box<Error>> {
201        self.set_paired(false)
202    }
203
204    pub fn get_modalias(&self) ->  Result<(String, u32, u32, u32), Box<Error>> {
205        let cloned = self.modalias.clone();
206        let modalias = match cloned.lock() {
207            Ok(guard) => guard.deref().clone(),
208            Err(_) => return Err(Box::from("Could not get the value.")),
209        };
210
211        let ids: Vec<&str> = modalias.split(":").collect();
212        let source = String::from(ids[0]);
213        let vendor = hex::decode(&ids[1][1..5]).unwrap();
214        let product = hex::decode(&ids[1][6..10]).unwrap();
215        let device = hex::decode(&ids[1][11..15]).unwrap();
216
217        Ok((source,
218        (vendor[0] as u32) * 16 * 16 + (vendor[1] as u32),
219        (product[0] as u32) * 16 * 16 + (product[1] as u32),
220        (device[0] as u32) * 16 * 16 + (device[1] as u32)))
221    }
222
223    pub fn get_vendor_id_source(&self) -> Result<String, Box<Error>> {
224        let (vendor_id_source,_,_,_) = try!(self.get_modalias());
225        Ok(vendor_id_source)
226    }
227
228    pub fn get_vendor_id(&self) -> Result<u32, Box<Error>> {
229        let (_,vendor_id,_,_) = try!(self.get_modalias());
230        Ok(vendor_id)
231    }
232
233    pub fn get_product_id(&self) -> Result<u32, Box<Error>> {
234        let (_,_,product_id,_) = try!(self.get_modalias());
235        Ok(product_id)
236    }
237
238    pub fn get_device_id(&self) -> Result<u32, Box<Error>> {
239        let (_,_,_,device_id) = try!(self.get_modalias());
240        Ok(device_id)
241    }
242
243    pub fn get_gatt_services(&self) -> Result<Vec<String>, Box<Error>> {
244        if !(try!(self.is_connected())) {
245            return Err(Box::from("Device not connected."));
246        }
247
248        let cloned = self.gatt_services.clone();
249        let gatt_services = match cloned.lock() {
250            Ok(guard) => guard.deref().clone(),
251            Err(_) => return Err(Box::from("Could not get the value.")),
252        };
253        Ok(gatt_services.into_iter().map(|s| s.get_id()).collect())
254    }
255
256    pub fn get_gatt_service_structs(&self) -> Result<Vec<Arc<FakeBluetoothGATTService>>, Box<Error>> {
257        if !(try!(self.is_connected())) {
258            return Err(Box::from("Device not connected."));
259        }
260
261        let cloned = self.gatt_services.clone();
262        let gatt_services = match cloned.lock() {
263            Ok(guard) => guard.deref().clone(),
264            Err(_) => return Err(Box::from("Could not get the value.")),
265        };
266        Ok(gatt_services)
267    }
268
269    pub fn get_gatt_service(&self, id: String) -> Result<Arc<FakeBluetoothGATTService>, Box<Error>> {
270        let services = try!(self.get_gatt_service_structs());
271        for service in services {
272            let service_id = service.get_id();
273            if service_id == id {
274                return Ok(service);
275            }
276        }
277        Err(Box::from("No service exists with the given id."))
278    }
279
280    pub fn add_service(&self, service: Arc<FakeBluetoothGATTService>) -> Result<(), Box<Error>> {
281        let cloned = self.gatt_services.clone();
282        let mut gatt_services = match cloned.lock() {
283            Ok(guard) => guard,
284            Err(_) => return Err(Box::from("Could not get the value.")),
285        };
286        Ok(gatt_services.push(service))
287    }
288
289    pub fn remove_service(&self, id: String) -> Result<(), Box<Error>> {
290        let cloned = self.gatt_services.clone();
291        let mut gatt_services = match cloned.lock() {
292            Ok(guard) => guard,
293            Err(_) => return Err(Box::from("Could not get the value.")),
294        };
295        Ok(gatt_services.retain(|s| s.get_id() != id))
296    }
297
298    pub fn connect_profile(&self, _uuid: String) -> Result<(), Box<Error>> {
299        unimplemented!();
300    }
301
302    pub fn disconnect_profile(&self, _uuid: String) -> Result<(), Box<Error>> {
303        unimplemented!();
304    }
305
306    pub fn connect(&self) -> Result<(), Box<Error>> {
307        let is_connectable = try!(self.is_connectable());
308        let is_connected = try!(self.is_connected());
309
310        if is_connected {
311            return Ok(());
312        }
313        if is_connectable {
314            return self.set_connected(true);
315        }
316        return Err(Box::from("Could not connect to the device."));
317    }
318
319    pub fn disconnect(&self) -> Result<(), Box<Error>>{
320        let is_connected = try!(self.is_connected());
321
322        if is_connected {
323            return self.set_connected(false);
324        }
325        return Err(Box::from("The device is not connected."));
326    }
327}