use std::cmp;
use crate::{
command::Command,
error::{Error, RequestError},
hid::Device,
packet,
transaction::Channel,
};
pub fn send(
device: &impl Device,
channel: Channel,
command: Command,
data: &[u8],
buffer: &mut [u8],
) -> Result<(), Error> {
let data_size_init = packet::data_size_init(device);
let data_size_cont = packet::data_size_cont(device);
if data.len() > data_size_init + 128 * data_size_cont {
return Err(Error::from(RequestError::DataTooLong));
}
let length = data.len() as u16;
let n = cmp::min(data_size_init, data.len());
let (data_init, data_cont) = data.split_at(n);
packet::send_init(device, channel, command, length, data_init, buffer)?;
for (sequence, data) in data_cont.chunks(data_size_cont).enumerate() {
packet::send_cont(device, channel, sequence as u8, data, buffer)?;
}
Ok(())
}
pub fn receive(
device: &impl Device,
channel: Channel,
command: Command,
buffer: &mut [u8],
) -> Result<Vec<u8>, Error> {
let (n, packet_data) = packet::receive_init(device, channel, command, buffer)?;
let n = usize::from(n);
let mut data: Vec<u8> = Vec::with_capacity(n);
let m = std::cmp::min(packet_data.len(), n);
data.extend_from_slice(&packet_data[..m]);
let mut sequence = 0;
while data.len() < n {
let packet_data = packet::receive_cont(device, channel, sequence, buffer)?;
let m = std::cmp::min(packet_data.len(), n - data.len());
data.extend_from_slice(&packet_data[..m]);
sequence += 1;
}
Ok(data)
}