1 // Copyright 2023 Google LLC
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 //     https://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 crate::bluetooth::{ble_beacon_add, ble_beacon_get, ble_beacon_patch, ble_beacon_remove};
16 use crate::devices::chip::{ChipIdentifier, FacadeIdentifier};
17 use crate::wireless::{WirelessAdaptor, WirelessAdaptorImpl};
18 
19 use bytes::Bytes;
20 use log::{error, info};
21 use netsim_proto::model::Chip as ProtoChip;
22 use netsim_proto::model::ChipCreate as ChipCreateProto;
23 use netsim_proto::stats::{netsim_radio_stats, NetsimRadioStats as ProtoRadioStats};
24 
25 #[cfg(not(test))]
26 use crate::ffi::ffi_bluetooth;
27 
28 /// Parameters for creating BleBeacon chips
29 pub struct CreateParams {
30     pub device_name: String,
31     pub chip_proto: ChipCreateProto,
32 }
33 
34 /// BleBeacon struct will keep track of facade_id
35 pub struct BleBeacon {
36     facade_id: FacadeIdentifier,
37     chip_id: ChipIdentifier,
38 }
39 
40 impl Drop for BleBeacon {
drop(&mut self)41     fn drop(&mut self) {
42         if let Err(err) = ble_beacon_remove(self.chip_id, self.facade_id) {
43             error!("{err:?}");
44         }
45     }
46 }
47 
48 impl WirelessAdaptor for BleBeacon {
handle_request(&self, packet: &Bytes)49     fn handle_request(&self, packet: &Bytes) {
50         #[cfg(not(test))]
51         ffi_bluetooth::handle_bt_request(self.facade_id.0, packet[0], &packet[1..].to_vec());
52         #[cfg(test)]
53         log::info!("BleBeacon::handle_request({packet:?})");
54     }
55 
reset(&self)56     fn reset(&self) {
57         #[cfg(not(test))]
58         ffi_bluetooth::bluetooth_reset(self.facade_id.0);
59         #[cfg(test)]
60         log::info!("BleBeacon::reset()");
61     }
62 
get(&self) -> ProtoChip63     fn get(&self) -> ProtoChip {
64         let mut chip_proto = ProtoChip::new();
65         match ble_beacon_get(self.chip_id, self.facade_id) {
66             Ok(beacon_proto) => chip_proto.mut_ble_beacon().clone_from(&beacon_proto),
67             Err(err) => error!("{err:?}"),
68         }
69         chip_proto
70     }
71 
patch(&self, chip: &ProtoChip)72     fn patch(&self, chip: &ProtoChip) {
73         if let Err(err) = ble_beacon_patch(self.facade_id, self.chip_id, chip.ble_beacon()) {
74             error!("{err:?}");
75         }
76     }
77 
get_stats(&self, duration_secs: u64) -> Vec<ProtoRadioStats>78     fn get_stats(&self, duration_secs: u64) -> Vec<ProtoRadioStats> {
79         let mut stats_proto = ProtoRadioStats::new();
80         stats_proto.set_duration_secs(duration_secs);
81         stats_proto.set_kind(netsim_radio_stats::Kind::BLE_BEACON);
82         let chip_proto = self.get();
83         if chip_proto.has_ble_beacon() {
84             stats_proto.set_tx_count(chip_proto.ble_beacon().bt.low_energy.tx_count);
85             stats_proto.set_rx_count(chip_proto.ble_beacon().bt.low_energy.rx_count);
86         }
87         vec![stats_proto]
88     }
89 }
90 
91 /// Create a new Emulated BleBeacon Chip
new(params: &CreateParams, chip_id: ChipIdentifier) -> WirelessAdaptorImpl92 pub fn new(params: &CreateParams, chip_id: ChipIdentifier) -> WirelessAdaptorImpl {
93     match ble_beacon_add(params.device_name.clone(), chip_id, &params.chip_proto) {
94         Ok(facade_id) => {
95             info!(
96                 "BleBeacon WirelessAdaptor created with facade_id: {facade_id} chip_id: {chip_id}"
97             );
98             Box::new(BleBeacon { facade_id, chip_id })
99         }
100         Err(err) => {
101             error!("{err:?}");
102             Box::new(BleBeacon {
103                 facade_id: FacadeIdentifier(u32::MAX),
104                 chip_id: ChipIdentifier(u32::MAX),
105             })
106         }
107     }
108 }
109