use usb_device::{
class_prelude::*,
Result,
};
use crate::{
logging::*,
InterfaceSubclass,
InterfaceProtocol,
};
pub const USB_CLASS_MSC: u8 = 0x08;
pub struct MscClass<'a, B: UsbBus> {
pub(crate) msc_if: InterfaceNumber,
pub(crate) read_ep: EndpointOut<'a, B>,
pub(crate) write_ep: EndpointIn<'a, B>,
pub(crate) subclass: InterfaceSubclass,
pub(crate) protocol: InterfaceProtocol,
}
impl<B: UsbBus> MscClass<'_, B> {
pub fn new(
alloc: &UsbBusAllocator<B>,
max_packet_size: u16,
subclass: InterfaceSubclass,
protocol: InterfaceProtocol,
) -> MscClass<'_, B> {
MscClass {
msc_if: alloc.interface(),
write_ep: alloc.bulk(max_packet_size),
read_ep: alloc.bulk(max_packet_size),
subclass,
protocol,
}
}
pub fn max_packet_size(&self) -> u16 {
self.read_ep.max_packet_size()
}
pub fn read_packet(&mut self, buf: &mut [u8]) -> Result<usize> {
self.read_ep.read(buf)
}
pub fn write_packet(&mut self, buf: &[u8]) -> Result<usize> {
self.write_ep.write(buf)
}
pub fn correct_interface_number(&self, interface_number: u16) -> bool {
interface_number == u8::from(self.msc_if) as u16
}
}
impl<B: UsbBus> UsbClass<B> for MscClass<'_, B> {
fn get_configuration_descriptors(&self, writer: &mut DescriptorWriter) -> Result<()> {
writer.interface(
self.msc_if,
USB_CLASS_MSC,
self.subclass.to_primitive(),
self.protocol.to_primitive(),
)?;
writer.endpoint(&self.read_ep)?;
writer.endpoint(&self.write_ep)?;
Ok(())
}
fn reset(&mut self) { }
fn control_in(&mut self, xfer: ControlIn<B>) {
let req = xfer.request();
if self.correct_interface_number(req.index) {
trace_usb_control!("USB_CONTROL> Unhandled control-IN: {:?}", req);
}
}
fn control_out(&mut self, xfer: ControlOut<B>) {
let req = xfer.request();
if self.correct_interface_number(req.index) {
trace_usb_control!("USB_CONTRO> Unhandled control-OUT: {:?}", req);
};
}
}