use crate::endpoint::*;
use std::fmt;
use std::io;
use std::io::Write;
use std::io::{Error, ErrorKind};
pub(crate) type Deallocate = Box<dyn Fn(*mut u8, usize) + 'static>;
pub struct ControlTransfer {
pub buffer: *mut u8,
pub(crate) buffer_length: u16,
pub(crate) buffer_capacity: u16,
pub(crate) actual_length: u16,
deallocate: Deallocate,
}
impl fmt::Display for ControlTransfer {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"|Control|{}|{}|{}|",
self.buffer_length, self.actual_length, self.buffer_capacity
)
}
}
impl ControlTransfer {
pub(crate) fn new<DEALOC>(
buffer: *mut u8,
buffer_capacity: u16,
buffer_length: u16,
deallocate: DEALOC,
) -> Self
where
DEALOC: Fn(*mut u8, usize) + 'static,
{
Self {
buffer,
buffer_length,
buffer_capacity,
actual_length: 0,
deallocate: Box::new(deallocate),
}
}
}
impl Drop for ControlTransfer {
fn drop(&mut self) {
if !self.buffer.is_null() {
(self.deallocate)(self.buffer, self.buffer_capacity as usize);
}
}
}
impl Write for ControlTransfer {
fn write(&mut self, inbuf: &[u8]) -> io::Result<usize> {
let buf = unsafe {
let buf = self.buffer;
std::slice::from_raw_parts_mut(
buf.offset(self.buffer_length as isize),
self.buffer_capacity as usize - self.buffer_length as usize,
)
};
for (i, byte) in inbuf.iter().enumerate() {
buf[i] = *byte;
self.buffer_length += 1;
}
Ok(inbuf.len())
}
fn flush(&mut self) -> io::Result<()> {
self.actual_length = 0;
Ok(())
}
}
pub struct BulkTransfer {
pub(crate) buffer: *mut u8,
pub buffer_length: usize,
pub actual_length: usize,
pub status: i32,
pub buffer_capacity: usize,
pub endpoint: Endpoint,
deallocate: Deallocate,
}
impl fmt::Display for BulkTransfer {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"|{}|{}|{}|{}|",
self.endpoint, self.buffer_length, self.actual_length, self.buffer_capacity
)
}
}
impl BulkTransfer {
pub fn input<DEALOC>(
ep: u8,
buffer: *mut u8,
buffer_capacity: usize,
deallocate: DEALOC,
) -> Self
where
DEALOC: Fn(*mut u8, usize) + 'static,
{
Self {
buffer,
buffer_capacity,
buffer_length: buffer_capacity,
actual_length: 0,
status: 0,
endpoint: Endpoint::bulk_in(ep),
deallocate: Box::new(deallocate),
}
}
pub fn output<DEALOC>(
ep: u8,
buffer: *mut u8,
buffer_capacity: usize,
deallocate: DEALOC,
) -> Self
where
DEALOC: Fn(*mut u8, usize) + 'static,
{
Self {
buffer,
buffer_capacity,
buffer_length: 0,
actual_length: 0,
status: 0,
endpoint: Endpoint::bulk_out(ep),
deallocate: Box::new(deallocate),
}
}
}
impl Drop for BulkTransfer {
fn drop(&mut self) {
if !self.buffer.is_null() {
(self.deallocate)(self.buffer, self.buffer_capacity);
}
}
}
impl Write for BulkTransfer {
fn write(&mut self, inbuf: &[u8]) -> io::Result<usize> {
if self.endpoint.is_bulk_in() {
return Err(Error::new(
ErrorKind::InvalidData,
"Can not write to an bulk in endpoint.",
));
}
let buf = unsafe {
let buf = self.buffer;
std::slice::from_raw_parts_mut(
buf.add(self.buffer_length),
self.buffer_capacity - self.buffer_length,
)
};
assert!(!buf.is_empty());
for (i, byte) in inbuf.iter().enumerate() {
buf[i] = *byte;
self.buffer_length += 1;
}
Ok(inbuf.len())
}
fn flush(&mut self) -> io::Result<()> {
self.actual_length = 0;
if self.endpoint.is_bulk_out() {
self.buffer_length = 0;
}
Ok(())
}
}
pub enum TransferKind {
Control(ControlTransfer),
Bulk(BulkTransfer),
Invalid(Endpoint),
}
impl fmt::Display for TransferKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TransferKind::Control(control) => write!(f, "Control Transfer: {}", control),
TransferKind::Bulk(bulk) => write!(f, "Control Transfer: {}", bulk),
TransferKind::Invalid(ep) => write!(f, "Invalid {}", ep),
}
}
}
pub trait BufferSlice {
fn buffer_from_raw<'a>(&self) -> &'a [u8];
}
pub trait UsbCoreDriver {
fn new_bulk_in(&mut self, ep: u8, read_capacity: usize) -> io::Result<BulkTransfer>;
fn new_bulk_out(&mut self, ep: u8, capacity: usize) -> io::Result<BulkTransfer>;
fn new_control(
&mut self,
request_type: u8,
request: u8,
value: u16,
index: u16,
length: u16,
) -> io::Result<ControlTransfer>;
fn new_control_out(
&mut self,
request_type: u8,
request: u8,
value: u16,
index: u16,
buffer: &[u8],
) -> io::Result<ControlTransfer> {
let mut ctrl = self.new_control(
request_type | ENDPOINT_OUT,
request,
value,
index,
buffer.len() as u16,
)?;
ctrl.write_all(buffer)?;
Ok(ctrl)
}
fn new_control_in(
&mut self,
request_type: u8,
request: u8,
value: u16,
index: u16,
length: u16,
) -> io::Result<ControlTransfer> {
let mut ctrl =
self.new_control(request_type | ENDPOINT_IN, request, value, index, length)?;
ctrl.buffer_length += length;
Ok(ctrl)
}
fn new_control_nodata(
&mut self,
request_type: u8,
request: u8,
value: u16,
index: u16,
) -> io::Result<ControlTransfer> {
self.new_control(request_type, request, value, index, 0)
}
}