Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions embedded-service/src/hid/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use core::borrow::Borrow;

use super::{Error, ReportId};
use crate::buffer::SharedRef;
use crate::{buffer::SharedRef, hid::InvalidSizeError};

/// HID report types
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -350,7 +350,10 @@ impl<'a> Command<'a> {

if report_id.0 >= EXTENDED_REPORT_ID {
if buf.len() < EXTENDED_REPORT_CMD_LEN {
return Err(Error::InvalidSize(EXTENDED_REPORT_CMD_LEN, buf.len()));
return Err(Error::InvalidSize(InvalidSizeError {
expected: EXTENDED_REPORT_CMD_LEN,
actual: buf.len(),
}));
}

val |= EXTENDED_REPORT_ID as u16;
Expand All @@ -363,7 +366,10 @@ impl<'a> Command<'a> {
Ok((EXTENDED_REPORT_CMD_LEN, &mut buf[EXTENDED_REPORT_CMD_LEN..]))
} else {
if buf.len() < STANDARD_REPORT_CMD_LEN {
return Err(Error::InvalidSize(STANDARD_REPORT_CMD_LEN, buf.len()));
return Err(Error::InvalidSize(InvalidSizeError {
expected: STANDARD_REPORT_CMD_LEN,
actual: buf.len(),
}));
}

val |= report_id.0 as u16;
Expand All @@ -377,7 +383,10 @@ impl<'a> Command<'a> {
/// Returns the number of bytes written and the remaining buffer
fn encode_basic_op(buf: &mut [u8], opcode: Opcode) -> Result<(usize, &mut [u8]), Error> {
if buf.len() < BASIC_CMD_LEN {
return Err(Error::InvalidSize(BASIC_CMD_LEN, buf.len()));
return Err(Error::InvalidSize(InvalidSizeError {
expected: BASIC_CMD_LEN,
actual: buf.len(),
}));
}

buf[0..BASIC_CMD_LEN].copy_from_slice(&<Opcode as Into<u16>>::into(opcode).to_le_bytes());
Expand All @@ -389,7 +398,10 @@ impl<'a> Command<'a> {
fn encode_register(buf: &mut [u8], reg: Option<u16>) -> Result<(usize, &mut [u8]), Error> {
if let Some(reg) = reg {
if buf.len() < REGISTER_LEN {
return Err(Error::InvalidSize(REGISTER_LEN, buf.len()));
return Err(Error::InvalidSize(InvalidSizeError {
expected: REGISTER_LEN,
actual: buf.len(),
}));
}
buf[0..REGISTER_LEN].copy_from_slice(&reg.to_le_bytes());
Ok((REGISTER_LEN, &mut buf[REGISTER_LEN..]))
Expand All @@ -402,7 +414,10 @@ impl<'a> Command<'a> {
/// Returns the number of bytes written and the remaining buffer
fn encode_value<T: Into<u16>>(buf: &mut [u8], value: T) -> Result<(usize, &mut [u8]), Error> {
if buf.len() < LENGTH_VALUE_LEN {
return Err(Error::InvalidSize(LENGTH_VALUE_LEN, buf.len()));
return Err(Error::InvalidSize(InvalidSizeError {
expected: LENGTH_VALUE_LEN,
actual: buf.len(),
}));
}
// Length value includes the size of the length as well
buf[0..VALUE_LEN].copy_from_slice(&4u16.to_le_bytes());
Expand All @@ -416,7 +431,10 @@ impl<'a> Command<'a> {
// +2 to encode the length of the data
let total_len = data.len() + 2;
if buf.len() < total_len {
return Err(Error::InvalidSize(total_len, buf.len()));
return Err(Error::InvalidSize(InvalidSizeError {
expected: total_len,
actual: buf.len(),
}));
}

buf[0..VALUE_LEN].copy_from_slice(&(total_len as u16).to_le_bytes());
Expand Down
22 changes: 19 additions & 3 deletions embedded-service/src/hid/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,24 @@ pub use command::*;
/// HID descriptor length
pub const DESCRIPTOR_LEN: usize = 30;

/// Data for [`Error::InvalidSize`]
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct InvalidSizeError {
/// Expected size
pub expected: usize,
/// Actual size
pub actual: usize,
}

/// HID errors
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error {
/// Invalid data
InvalidData,
/// Invalid size: expected and actual sizes
InvalidSize(usize, usize),
InvalidSize(InvalidSizeError),
/// Invalid register address
InvalidRegisterAddress,
/// Invalid device
Expand Down Expand Up @@ -68,7 +78,10 @@ impl Descriptor {
/// Serializes a descriptor into the slice
pub fn encode_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> {
if buf.len() < DESCRIPTOR_LEN {
return Err(Error::InvalidSize(DESCRIPTOR_LEN, buf.len()));
return Err(Error::InvalidSize(InvalidSizeError {
expected: DESCRIPTOR_LEN,
actual: buf.len(),
}));
}

buf[0..2].copy_from_slice(&self.w_hid_desc_length.to_le_bytes());
Expand All @@ -93,7 +106,10 @@ impl Descriptor {
/// Deserializes a descriptor from the slice
pub fn decode_from_slice(buf: &[u8]) -> Result<Self, Error> {
if buf.len() < DESCRIPTOR_LEN {
return Err(Error::InvalidSize(DESCRIPTOR_LEN, buf.len()));
return Err(Error::InvalidSize(InvalidSizeError {
expected: DESCRIPTOR_LEN,
actual: buf.len(),
}));
}

// Reserved bytes must be zero
Expand Down
100 changes: 69 additions & 31 deletions hid-service/src/i2c/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::borrow::BorrowMut;

use embassy_sync::mutex::Mutex;
use embedded_hal_async::i2c::{AddressMode, I2c};
use embedded_services::hid::{DeviceContainer, Opcode, Response};
use embedded_services::hid::{DeviceContainer, InvalidSizeError, Opcode, Response};
use embedded_services::{GlobalRawMutex, buffer::*};
use embedded_services::{error, hid, info, trace};

Expand Down Expand Up @@ -38,7 +38,13 @@ impl<A: AddressMode + Copy, B: I2c<A>> Device<A, B> {
let mut borrow = self.buffer.borrow_mut();
let mut reg = [0u8; 2];
let buf: &mut [u8] = borrow.borrow_mut();
let buf = &mut buf[0..hid::DESCRIPTOR_LEN];
let buf_len = buf.len();
let buf = buf
.get_mut(0..hid::DESCRIPTOR_LEN)
.ok_or(Error::Hid(hid::Error::InvalidSize(InvalidSizeError {
expected: hid::DESCRIPTOR_LEN,
actual: buf_len,
})))?;

reg.copy_from_slice(&self.device.regs.hid_desc_reg.to_le_bytes());
if let Err(e) = bus.write_read(self.address, &reg, buf).await {
Expand All @@ -47,18 +53,18 @@ impl<A: AddressMode + Copy, B: I2c<A>> Device<A, B> {
}

let res = hid::Descriptor::decode_from_slice(buf);
if res.is_err() {
error!("Failed to deseralize HID descriptor");
return Err(Error::Hid(hid::Error::Serialize));
}
let desc = res.unwrap();
info!("HID descriptor: {:#?}", desc);
{
let mut descriptor = self.descriptor.lock().await;
*descriptor = Some(desc);
match res {
Ok(desc) => {
info!("HID descriptor: {:#?}", desc);
let mut descriptor = self.descriptor.lock().await;
*descriptor = Some(desc);
Ok(desc)
}
Err(e) => {
error!("Failed to deserialize HID descriptor: {:?}", e);
Err(Error::Hid(hid::Error::Serialize))
}
}

Ok(desc)
}

pub async fn read_hid_descriptor(&self) -> Result<SharedRef<'static, u8>, Error<B::Error>> {
Expand All @@ -78,11 +84,23 @@ impl<A: AddressMode + Copy, B: I2c<A>> Device<A, B> {

let mut borrow = self.buffer.borrow_mut();
let buf: &mut [u8] = borrow.borrow_mut();
let buffer_len = buf.len();
let reg = desc.w_report_desc_register.to_le_bytes();
let len = desc.w_report_desc_length as usize;

let mut bus = self.bus.lock().await;
if let Err(e) = bus.write_read(self.address, &reg, &mut buf[0..len]).await {
if let Err(e) = bus
.write_read(
self.address,
&reg,
buf.get_mut(0..len)
.ok_or(Error::Hid(hid::Error::InvalidSize(InvalidSizeError {
expected: len,
actual: buffer_len,
})))?,
)
.await
{
error!("Failed to read report descriptor");
return Err(Error::Bus(e));
}
Expand All @@ -96,7 +114,13 @@ impl<A: AddressMode + Copy, B: I2c<A>> Device<A, B> {

let mut borrow = self.buffer.borrow_mut();
let buf: &mut [u8] = borrow.borrow_mut();
let buf = &mut buf[0..desc.w_max_input_length as usize];
let buffer_len = buf.len();
let buf = buf
.get_mut(0..desc.w_max_input_length as usize)
.ok_or(Error::Hid(hid::Error::InvalidSize(InvalidSizeError {
expected: desc.w_max_input_length as usize,
actual: buffer_len,
})))?;

let mut bus = self.bus.lock().await;
if let Err(e) = bus.read(self.address, buf).await {
Expand All @@ -115,25 +139,36 @@ impl<A: AddressMode + Copy, B: I2c<A>> Device<A, B> {

let mut borrow = self.buffer.borrow_mut();
let buf: &mut [u8] = borrow.borrow_mut();
let buffer_len = buf.len();

let opcode: Opcode = cmd.into();
let res = cmd.encode_into_slice(
buf,
Some(self.device.regs.command_reg),
if opcode.has_response() || opcode.requires_host_data() {
Some(self.device.regs.data_reg)
} else {
None
},
);
if res.is_err() {
error!("Failed to serialize command");
return Err(Error::Hid(hid::Error::Serialize));
}
let len = cmd
.encode_into_slice(
buf,
Some(self.device.regs.command_reg),
if opcode.has_response() || opcode.requires_host_data() {
Some(self.device.regs.data_reg)
} else {
None
},
)
.map_err(|_| {
error!("Failed to serialize command");
Error::Hid(hid::Error::Serialize)
})?;

let len = res.unwrap();
let mut bus = self.bus.lock().await;
if let Err(e) = bus.write(self.address, &buf[..len]).await {
if let Err(e) = bus
.write(
self.address,
buf.get(..len)
.ok_or(Error::Hid(hid::Error::InvalidSize(InvalidSizeError {
expected: len,
actual: buffer_len,
})))?,
)
.await
{
error!("Failed to write command");
return Err(Error::Bus(e));
}
Expand Down Expand Up @@ -168,7 +203,10 @@ impl<A: AddressMode + Copy, B: I2c<A>> Device<A, B> {
Some(hid::Response::InputReport(report))
}
hid::Request::Command(cmd) => self.handle_command(&cmd).await?,
_ => unimplemented!(),
_ => {
error!("Unimplemented HID request");
None
}
};

self.device
Expand Down
Loading