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::{BeaconChip, BEACON_CHIPS};
16 use crate::devices::chip::{ChipIdentifier, FacadeIdentifier};
17 use crate::devices::device::{AddChipResult, DeviceIdentifier};
18 use ::protobuf::MessageField;
19 use lazy_static::lazy_static;
20 use log::info;
21 use netsim_proto::config::Bluetooth as BluetoothConfig;
22 use netsim_proto::configuration::Controller as RootcanalController;
23 use netsim_proto::model::chip::{BleBeacon, Bluetooth};
24 use netsim_proto::model::chip_create::Chip as Builtin;
25 use netsim_proto::model::{ChipCreate, DeviceCreate};
26 use std::sync::atomic::{AtomicU32, Ordering};
27 use std::sync::Mutex;
28 use std::sync::RwLock;
29 use std::{collections::HashMap, ptr::null};
30
31 lazy_static! {
32 static ref IDS: AtomicU32 = AtomicU32::new(0);
33 }
34
next_id() -> FacadeIdentifier35 fn next_id() -> FacadeIdentifier {
36 FacadeIdentifier(IDS.fetch_add(1, Ordering::SeqCst))
37 }
38
39 // Avoid crossing cxx boundary in tests
ble_beacon_add( device_name: String, chip_id: ChipIdentifier, chip_proto: &ChipCreate, ) -> Result<FacadeIdentifier, String>40 pub fn ble_beacon_add(
41 device_name: String,
42 chip_id: ChipIdentifier,
43 chip_proto: &ChipCreate,
44 ) -> Result<FacadeIdentifier, String> {
45 let beacon_proto = match &chip_proto.chip {
46 Some(Builtin::BleBeacon(beacon_proto)) => beacon_proto,
47 _ => return Err(String::from("failed to create ble beacon: unexpected chip type")),
48 };
49
50 let beacon_chip = BeaconChip::from_proto(device_name, chip_id, beacon_proto)?;
51 if BEACON_CHIPS.write().unwrap().insert(chip_id, Mutex::new(beacon_chip)).is_some() {
52 return Err(format!(
53 "failed to create a bluetooth beacon chip with id {chip_id}: chip id already exists.",
54 ));
55 }
56
57 let facade_id = next_id();
58
59 info!("ble_beacon_add successful with chip_id: {chip_id}");
60 Ok(facade_id)
61 }
62
ble_beacon_remove( chip_id: ChipIdentifier, facade_id: FacadeIdentifier, ) -> Result<(), String>63 pub fn ble_beacon_remove(
64 chip_id: ChipIdentifier,
65 facade_id: FacadeIdentifier,
66 ) -> Result<(), String> {
67 info!("{:?}", BEACON_CHIPS.read().unwrap().keys());
68 if BEACON_CHIPS.write().unwrap().remove(&chip_id).is_none() {
69 Err(format!("failed to delete ble beacon chip: chip with id {chip_id} does not exist"))
70 } else {
71 Ok(())
72 }
73 }
74