use bytes::{Buf, BufMut, BytesMut};
use enumflags2::BitFlags;
use crate::management::interface::Command;
use crate::management::interface::{Controller, ControllerSettings};
use crate::management::Result;
use crate::Address;
use super::*;
use crate::util::BufExt;
pub async fn set_local_name(
socket: &mut ManagementStream,
controller: Controller,
name: &str,
short_name: Option<&str>,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<(CString, CString)> {
if name.len() > 248 {
return Err(Error::NameTooLong {
name: name.to_owned(),
max_len: 248,
});
}
if let Some(short_name) = short_name {
if short_name.len() > 10 {
return Err(Error::NameTooLong {
name: short_name.to_owned(),
max_len: 10,
});
}
}
let short_name = short_name.unwrap_or("");
let mut param = BytesMut::with_capacity(260);
param.resize(260, 0);
CString::new(name)?
.as_bytes_with_nul()
.copy_to_slice(&mut param[..=name.len()]);
CString::new(short_name)?
.as_bytes_with_nul()
.copy_to_slice(&mut param[249..][..=short_name.len()]);
let (_, param) = exec_command(
socket,
Command::SetLocalName,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
let mut param = param.ok_or(Error::NoData)?;
Ok((param.split_to(249).get_c_string(), param.get_c_string()))
}
pub async fn set_powered(
socket: &mut ManagementStream,
controller: Controller,
powered: bool,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(1);
param.put_u8(powered as u8);
let (_, param) = exec_command(
socket,
Command::SetPowered,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_discoverable(
socket: &mut ManagementStream,
controller: Controller,
discoverability: DiscoverableMode,
timeout: Option<u16>,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(3);
param.put_u8(discoverability as u8);
if let Some(timeout) = timeout {
param.put_u16_le(timeout);
}
let (_, param) = exec_command(
socket,
Command::SetDiscoverable,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_connectable(
socket: &mut ManagementStream,
controller: Controller,
connectable: bool,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(1);
param.put_u8(connectable as u8);
let (_, param) = exec_command(
socket,
Command::SetConnectable,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_fast_connectable(
socket: &mut ManagementStream,
controller: Controller,
fast_connectable: bool,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(1);
param.put_u8(fast_connectable as u8);
let (_, param) = exec_command(
socket,
Command::SetFastConnectable,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_bondable(
socket: &mut ManagementStream,
controller: Controller,
bondable: bool,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(1);
param.put_u8(bondable as u8);
let (_, param) = exec_command(
socket,
Command::SetPairable,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_link_security(
socket: &mut ManagementStream,
controller: Controller,
link_security: bool,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(1);
param.put_u8(link_security as u8);
let (_, param) = exec_command(
socket,
Command::SetLinkSecurity,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_ssp(
socket: &mut ManagementStream,
controller: Controller,
ssp: bool,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(1);
param.put_u8(ssp as u8);
let (_, param) = exec_command(
socket,
Command::SetSecureSimplePairing,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_high_speed(
socket: &mut ManagementStream,
controller: Controller,
high_speed: bool,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(1);
param.put_u8(high_speed as u8);
let (_, param) = exec_command(
socket,
Command::SetHighSpeed,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_le(
socket: &mut ManagementStream,
controller: Controller,
le: bool,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(1);
param.put_u8(le as u8);
let (_, param) = exec_command(
socket,
Command::SetLowEnergy,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_advertising(
socket: &mut ManagementStream,
controller: Controller,
mode: LeAdvertisingMode,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(1);
param.put_u8(mode as u8);
let (_, param) = exec_command(
socket,
Command::SetAdvertising,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_bredr(
socket: &mut ManagementStream,
controller: Controller,
enabled: bool,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(1);
param.put_u8(enabled as u8);
let (_, param) = exec_command(
socket,
Command::SetBREDR,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_io_capability(
socket: &mut ManagementStream,
controller: Controller,
io_capability: IoCapability,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<()> {
let mut param = BytesMut::with_capacity(1);
param.put_u8(io_capability as u8);
let (_, _param) = exec_command(
socket,
Command::SetIOCapability,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(())
}
pub async fn set_device_id(
socket: &mut ManagementStream,
controller: Controller,
source: u16,
vendor: u16,
product: u16,
version: u16,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<()> {
let mut param = BytesMut::with_capacity(8);
param.put_u16_le(source);
param.put_u16_le(vendor);
param.put_u16_le(product);
param.put_u16_le(version);
let (_, _param) = exec_command(
socket,
Command::SetDeviceID,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(())
}
pub async fn set_scan_parameters(
socket: &mut ManagementStream,
controller: Controller,
interval: u16,
window: u16,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<()> {
let mut param = BytesMut::with_capacity(4);
param.put_u16_le(interval);
param.put_u16_le(window);
let (_, _param) = exec_command(
socket,
Command::SetScanParameters,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(())
}
pub async fn set_static_address(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let param = BytesMut::from(address.as_ref());
let (_, param) = exec_command(
socket,
Command::SetStaticAddress,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_secure_connections_mode(
socket: &mut ManagementStream,
controller: Controller,
mode: SecureConnectionsMode,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(1);
param.put_u8(mode as u8);
let (_, param) = exec_command(
socket,
Command::SetSecureConnections,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_debug_mode(
socket: &mut ManagementStream,
controller: Controller,
mode: DebugKeysMode,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(1);
param.put_u8(mode as u8);
let (_, param) = exec_command(
socket,
Command::SetDebugKeys,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_privacy_mode(
socket: &mut ManagementStream,
controller: Controller,
mode: PrivacyMode,
identity_resolving_key: [u8; 16],
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(17);
param.put_u8(mode as u8);
param.put_slice(&identity_resolving_key[..]);
let (_, param) = exec_command(
socket,
Command::SetPrivacy,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_external_config(
socket: &mut ManagementStream,
controller: Controller,
config: bool,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let param = BytesMut::from([config as u8].as_ref() as &[u8]);
let (_, param) = exec_command(
socket,
Command::SetExternalConfig,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_public_address(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let param = BytesMut::from(address.as_ref());
let (_, param) = exec_command(
socket,
Command::SetPublicAddress,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_appearance(
socket: &mut ManagementStream,
controller: Controller,
appearance: u16,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<()> {
let mut param = BytesMut::with_capacity(2);
param.put_u16_le(appearance);
let (_, _param) = exec_command(
socket,
Command::SetAppearance,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(())
}
pub async fn set_phy_config(
socket: &mut ManagementStream,
controller: Controller,
selected_phys: BitFlags<PhyFlag>,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<()> {
let mut param = BytesMut::with_capacity(4);
param.put_u32_le(selected_phys.bits());
let (_, _param) = exec_command(
socket,
Command::SetPhyConfig,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(())
}
pub async fn set_wideband_speech(
socket: &mut ManagementStream,
controller: Controller,
enabled: bool,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<ControllerSettings> {
let mut param = BytesMut::with_capacity(1);
param.put_u8(enabled as u8);
let (_, param) = exec_command(
socket,
Command::SetWidebandSpeech,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(param.ok_or(Error::NoData)?.get_flags_u32_le())
}
pub async fn set_default_runtime_config(
socket: &mut ManagementStream,
controller: Controller,
params: &[(RuntimeConfigParameterType, Vec<u8>)],
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<()> {
let size = params
.iter()
.fold(0, |acc, (_, value)| acc + 3 + value.len());
let mut param = BytesMut::with_capacity(size);
#[allow(unreachable_code, unused_variables)]
for (parameter_type, value) in params {
param.put_u16_le(unimplemented!("*parameter_type as u16"));
param.put_u8(value.len() as u8);
param.put_slice(value);
}
let (_, _param) = exec_command(
socket,
Command::SetDefaultSystemConfig,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(())
}
pub async fn set_default_system_config(
socket: &mut ManagementStream,
controller: Controller,
params: &[(SystemConfigParameterType, Vec<u8>)],
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<()> {
let size = params
.iter()
.fold(0, |acc, (_, value)| acc + 3 + value.len());
let mut param = BytesMut::with_capacity(size);
for (parameter_type, value) in params {
param.put_u16_le(*parameter_type as u16);
param.put_u8(value.len() as u8);
param.put_slice(value);
}
let (_, _param) = exec_command(
socket,
Command::SetDefaultSystemConfig,
controller,
Some(param.freeze()),
event_tx,
)
.await?;
Ok(())
}