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, ¶ms.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