blob: ce4edf0365c254516790f1b046200401ed2ae87c [file] [log] [blame]
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::bluetooth::{BeaconChip, BEACON_CHIPS};
use crate::devices::chip::{ChipIdentifier, FacadeIdentifier};
use crate::devices::device::{AddChipResult, DeviceIdentifier};
use ::protobuf::MessageField;
use lazy_static::lazy_static;
use log::info;
use netsim_proto::config::Bluetooth as BluetoothConfig;
use netsim_proto::configuration::Controller as RootcanalController;
use netsim_proto::model::chip::{BleBeacon, Bluetooth};
use netsim_proto::model::chip_create::Chip as Builtin;
use netsim_proto::model::{ChipCreate, DeviceCreate};
use std::sync::Mutex;
use std::sync::RwLock;
use std::{collections::HashMap, ptr::null};
lazy_static! {
static ref IDS: RwLock<FacadeIds> = RwLock::new(FacadeIds::new());
}
struct FacadeIds {
pub current_id: u32,
}
impl FacadeIds {
fn new() -> Self {
FacadeIds { current_id: 0 }
}
}
pub fn handle_bluetooth_request(facade_id: u32, packet_type: u8, packet: &Vec<u8>) {
info!("hci_reset({facade_id}, {packet_type}, {packet:?})");
}
pub fn bluetooth_reset(facade_id: u32) {
info!("hci_reset({facade_id})");
}
pub fn bluetooth_remove(facade_id: u32) {
info!("hci_remove({facade_id})");
}
pub fn bluetooth_patch(facade_id: u32, bluetooth: &Bluetooth) {
info!("hci_patch({facade_id}, {bluetooth:?})");
}
pub fn bluetooth_get(facade_id: u32) -> Bluetooth {
info!("hci_get({facade_id})");
Bluetooth::new()
}
// Returns facade_id
pub fn bluetooth_add(
device_id: u32,
_address: &str,
_bt_properties: &MessageField<RootcanalController>,
) -> u32 {
info!("hci_add({device_id})");
let mut resource = IDS.write().unwrap();
let facade_id = resource.current_id;
resource.current_id += 1;
facade_id
}
/// Starts the Bluetooth service.
pub fn bluetooth_start(
_config: &MessageField<BluetoothConfig>,
_instance_num: u16,
_disable_address_reuse: bool,
) {
info!("bluetooth service started");
}
/// Stops the Bluetooth service.
pub fn bluetooth_stop() {
info!("bluetooth service ended");
}
// Avoid crossing cxx boundary in tests
pub fn ble_beacon_add(
device_id: DeviceIdentifier,
device_name: String,
chip_id: ChipIdentifier,
chip_proto: &ChipCreate,
) -> Result<FacadeIdentifier, String> {
let beacon_proto = match &chip_proto.chip {
Some(Builtin::BleBeacon(beacon_proto)) => beacon_proto,
_ => return Err(String::from("failed to create ble beacon: unexpected chip type")),
};
let beacon_chip = BeaconChip::from_proto(device_name, chip_id, beacon_proto)?;
if BEACON_CHIPS.write().unwrap().insert(chip_id, Mutex::new(beacon_chip)).is_some() {
return Err(format!(
"failed to create a bluetooth beacon chip with id {chip_id}: chip id already exists.",
));
}
let mut resource = crate::bluetooth::mocked::IDS.write().unwrap();
let facade_id = resource.current_id;
resource.current_id += 1;
Ok(facade_id)
}
pub fn ble_beacon_remove(
device_id: DeviceIdentifier,
chip_id: ChipIdentifier,
facade_id: FacadeIdentifier,
) -> Result<(), String> {
if BEACON_CHIPS.write().unwrap().remove(&chip_id).is_none() {
Err(format!("failed to delete ble beacon chip: chip with id {chip_id} does not exist"))
} else {
Ok(())
}
}