use super::*;
use crate::util::BufExt;
use crate::AddressType;
#[inline]
pub(crate) fn get_address(param: Option<Bytes>) -> Result<(Address, AddressType)> {
let mut param = param.ok_or(Error::NoData)?;
Ok((param.get_address(), param.get_primitive_u8()))
}
pub(crate) fn address_bytes(address: Address, address_type: AddressType) -> Bytes {
let mut param = BytesMut::with_capacity(7);
param.put_slice(address.as_ref());
param.put_u8(address_type as u8);
param.freeze()
}
pub(crate) fn address_bytes_with_u8(
address: Address,
address_type: AddressType,
extra: u8,
) -> Bytes {
let mut param = BytesMut::with_capacity(8);
param.put_slice(address.as_ref());
param.put_u8(address_type as u8);
param.put_u8(extra);
param.freeze()
}
pub async fn confirm_name(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
address_type: AddressType,
name_known: bool,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<(Address, AddressType)> {
let (_, param) = exec_command(
socket,
Command::ConfirmName,
controller,
Some(address_bytes_with_u8(
address,
address_type,
name_known as u8,
)),
event_tx,
)
.await?;
get_address(param)
}
pub async fn block_device(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
address_type: AddressType,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<(Address, AddressType)> {
let (_, param) = exec_command(
socket,
Command::BlockDevice,
controller,
Some(address_bytes(address, address_type)),
event_tx,
)
.await?;
get_address(param)
}
pub async fn unblock_device(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
address_type: AddressType,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<(Address, AddressType)> {
let (_, param) = exec_command(
socket,
Command::UnblockDevice,
controller,
Some(address_bytes(address, address_type)),
event_tx,
)
.await?;
get_address(param)
}
pub async fn disconnect(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
address_type: AddressType,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<(Address, AddressType)> {
let (_, param) = exec_command(
socket,
Command::Disconnect,
controller,
Some(address_bytes(address, address_type)),
event_tx,
)
.await?;
get_address(param)
}
pub async fn pin_code_reply(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
address_type: AddressType,
pin_code: Option<Vec<u8>>,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<(Address, AddressType)> {
let mut param;
let opcode;
if let Some(pin_code) = pin_code {
opcode = Command::PinCodeReply;
param = BytesMut::with_capacity(24);
param.put_slice(address.as_ref());
param.put_u8(address_type as u8);
param.put_u8(pin_code.len() as u8);
param.put_slice(&pin_code[..]);
param.resize(24, 0);
} else {
opcode = Command::PinCodeNegativeReply;
param = BytesMut::with_capacity(7);
param.put_slice(address.as_ref());
param.put_u8(address_type as u8);
}
let (_, param) =
exec_command(socket, opcode, controller, Some(param.freeze()), event_tx).await?;
get_address(param)
}
pub async fn pair_device(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
address_type: AddressType,
io_capability: IoCapability,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<(Address, AddressType)> {
let (_, param) = exec_command(
socket,
Command::PairDevice,
controller,
Some(address_bytes_with_u8(
address,
address_type,
io_capability as u8,
)),
event_tx,
)
.await?;
get_address(param)
}
pub async fn cancel_pair_device(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
address_type: AddressType,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<(Address, AddressType)> {
let (_, param) = exec_command(
socket,
Command::CancelPairDevice,
controller,
Some(address_bytes(address, address_type)),
event_tx,
)
.await?;
get_address(param)
}
pub async fn unpair_device(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
address_type: AddressType,
disconnect: bool,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<(Address, AddressType)> {
let (_, param) = exec_command(
socket,
Command::UnpairDevice,
controller,
Some(address_bytes_with_u8(
address,
address_type,
disconnect as u8,
)),
event_tx,
)
.await?;
get_address(param)
}
pub async fn user_confirmation_reply(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
address_type: AddressType,
reply: bool,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<(Address, AddressType)> {
let (_, param) = exec_command(
socket,
if reply {
Command::UserConfirmationReply
} else {
Command::UserConfirmationNegativeReply
},
controller,
Some(address_bytes(address, address_type)),
event_tx,
)
.await?;
get_address(param)
}
pub async fn user_passkey_reply(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
address_type: AddressType,
passkey: Option<u32>,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<(Address, AddressType)> {
let opcode;
let mut param;
if let Some(passkey) = passkey {
opcode = Command::UserPasskeyReply;
param = BytesMut::with_capacity(11);
param.put_slice(address.as_ref());
param.put_u8(address_type as u8);
param.put_u32_le(passkey);
} else {
opcode = Command::UserPasskeyNegativeReply;
param = BytesMut::with_capacity(7);
param.put_slice(address.as_ref());
param.put_u8(address_type as u8);
}
let (_, param) =
exec_command(socket, opcode, controller, Some(param.freeze()), event_tx).await?;
get_address(param)
}
pub async fn add_device(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
address_type: AddressType,
action: AddDeviceAction,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<(Address, AddressType)> {
let (_, param) = exec_command(
socket,
Command::AddDevice,
controller,
Some(address_bytes_with_u8(address, address_type, action as u8)),
event_tx,
)
.await?;
get_address(param)
}
pub async fn remove_device(
socket: &mut ManagementStream,
controller: Controller,
address: Address,
address_type: AddressType,
event_tx: Option<mpsc::Sender<Response>>,
) -> Result<(Address, AddressType)> {
let (_, param) = exec_command(
socket,
Command::RemoveDevice,
controller,
Some(address_bytes(address, address_type)),
event_tx,
)
.await?;
get_address(param)
}