use crate::AddressType;
use std::collections::HashMap;
use crate::management::interface::ControllerInfoExt;
use crate::util::BufExt;
use super::*;
pub async fn get_mgmt_version(
socket: &mut ManagementStream,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ManagementVersion> {
let (_, param) = exec_command(
socket,
Command::ReadVersionInfo,
Controller::none(),
None,
event_tx,
)
.await?;
let mut param = param.ok_or(Error::NoData)?;
Ok(ManagementVersion {
version: param.get_u8(),
revision: param.get_u16_le(),
})
}
pub async fn get_controller_list(
socket: &mut ManagementStream,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<Vec<Controller>> {
let (_, param) = exec_command(
socket,
Command::ReadControllerIndexList,
Controller::none(),
None,
event_tx,
)
.await?;
let mut param = param.unwrap();
let count = param.get_u16_le() as usize;
let mut controllers = vec![Controller::none(); count];
for i in 0..count {
controllers[i] = Controller(param.get_u16_le());
}
Ok(controllers)
}
pub async fn get_controller_info(
socket: &mut ManagementStream,
controller: Controller,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerInfo> {
let (_, param) = exec_command(
socket,
Command::ReadControllerInfo,
controller,
None,
event_tx,
)
.await?;
let mut param = param.ok_or(Error::NoData)?;
Ok(ControllerInfo {
address: param.get_address(),
bluetooth_version: param.get_u8(),
manufacturer: param.get_u16_le(),
supported_settings: param.get_flags_u32_le(),
current_settings: param.get_flags_u32_le(),
class_of_device: device_class_from_bytes(param.split_to(3)),
name: param.split_to(249).get_c_string(),
short_name: param.get_c_string(),
})
}
pub async fn get_connections(
socket: &mut ManagementStream,
controller: Controller,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<Vec<(Address, AddressType)>> {
let (_, param) =
exec_command(socket, Command::GetConnections, controller, None, event_tx).await?;
let mut param = param.ok_or(Error::NoData)?;
let count = param.get_u16_le() as usize;
let mut connections = Vec::with_capacity(count);
for _ in 0..count {
connections.push((param.get_address(), param.get_primitive_u8()));
}
Ok(connections)
}
pub async fn get_connection_info(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
address_type: AddressType,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ConnectionInfo> {
let mut param = BytesMut::with_capacity(7);
param.put_slice(address.as_ref());
param.put_u8(address_type as u8);
let (_, param) = exec_command(
socket,
Command::GetConnectionInfo,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
let mut param = param.ok_or(Error::NoData)?;
Ok(ConnectionInfo {
address: param.get_address(),
address_type: param.get_primitive_u8(),
rssi: if param[0] != 127 {
Some(param.get_i8())
} else {
None
},
tx_power: if param[0] != 127 {
Some(param.get_i8())
} else {
None
},
max_tx_power: if param[0] != 127 {
Some(param.get_i8())
} else {
None
},
})
}
pub async fn get_clock_info(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
address_type: AddressType,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ClockInfo> {
let mut param = BytesMut::with_capacity(7);
param.put_slice(address.as_ref());
param.put_u8(address_type as u8);
let (_, param) = exec_command(
socket,
Command::GetClockInfo,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
let mut param = param.ok_or(Error::NoData)?;
let address = param.get_address();
let address_type = param.get_primitive_u8();
let local_clock = param.get_u32_le();
let mut piconet_clock = None;
let mut accuracy = None;
if address != Address::zero() {
piconet_clock = Some(param.get_u32_le());
let accuracy_tmp = param.get_u16_le();
if accuracy_tmp != 0xFFFF {
accuracy = Some(accuracy_tmp);
}
}
Ok(ClockInfo {
address,
address_type,
local_clock,
piconet_clock,
accuracy,
})
}
pub async fn get_unconfigured_controller_list(
socket: &mut ManagementStream,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<Vec<Controller>> {
let (_, param) = exec_command(
socket,
Command::ReadUnconfiguredControllerIndexList,
Controller::none(),
None,
event_tx,
)
.await?;
let mut param = param.ok_or(Error::NoData)?;
let count = param.get_u16_le() as usize;
let mut controllers = vec![Controller::none(); count];
for i in 0..count {
controllers[i] = Controller(param.get_u16_le());
}
Ok(controllers)
}
pub async fn get_controller_config_info(
socket: &mut ManagementStream,
controller: Controller,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerConfigInfo> {
let (_, param) = exec_command(
socket,
Command::ReadControllerConfigInfo,
controller,
None,
event_tx,
)
.await?;
let mut param = param.ok_or(Error::NoData)?;
Ok(ControllerConfigInfo {
manufacturer: param.get_u16_le(),
supported_options: param.get_flags_u32_le(),
missing_options: param.get_flags_u32_le(),
})
}
pub async fn get_ext_controller_list(
socket: &mut ManagementStream,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<Vec<(Controller, ControllerType, ControllerBus)>> {
let (_, param) = exec_command(
socket,
Command::ReadExtendedControllerIndexList,
Controller::none(),
None,
event_tx,
)
.await?;
let mut param = param.ok_or(Error::NoData)?;
let count = param.get_u16_le() as usize;
let mut index = Vec::with_capacity(count);
for _ in 0..count {
index.push((
Controller(param.get_u16_le()),
param.get_primitive_u8(),
param.get_primitive_u8(),
));
}
Ok(index)
}
pub async fn get_ext_controller_info(
socket: &mut ManagementStream,
controller: Controller,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerInfoExt> {
let (_, param) = exec_command(
socket,
Command::ReadExtendedControllerInfo,
controller,
None,
event_tx,
)
.await?;
let mut param = param.ok_or(Error::NoData)?;
Ok(ControllerInfoExt {
address: param.get_address(),
bluetooth_version: param.get_u8(),
manufacturer: param.get_u16_le(),
supported_settings: param.get_flags_u32_le(),
current_settings: param.get_flags_u32_le(),
eir_data: {
let len = param.get_u16_le();
param.split_to(len as usize)
},
})
}
pub async fn get_phy_config(
socket: &mut ManagementStream,
controller: Controller,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<PhyConfig> {
let (_, param) =
exec_command(socket, Command::GetPhyConfig, controller, None, event_tx).await?;
let mut param = param.ok_or(Error::NoData)?;
Ok(PhyConfig {
supported_phys: param.get_flags_u32_le(),
configurable_phys: param.get_flags_u32_le(),
selected_phys: param.get_flags_u32_le(),
})
}
pub async fn get_default_runtime_config(
socket: &mut ManagementStream,
controller: Controller,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<HashMap<RuntimeConfigParameterType, Vec<u8>>> {
let (_, param) = exec_command(
socket,
Command::ReadDefaultRuntimeConfig,
controller,
None,
event_tx,
)
.await?;
let mut param = param.ok_or(Error::NoData)?;
Ok(param.get_tlv_map())
}
pub async fn get_default_system_config(
socket: &mut ManagementStream,
controller: Controller,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<HashMap<SystemConfigParameterType, Vec<u8>>> {
let (_, param) = exec_command(
socket,
Command::ReadDefaultSystemConfig,
controller,
None,
event_tx,
)
.await?;
let mut param = param.ok_or(Error::NoData)?;
Ok(param.get_tlv_map())
}