use super::*;
use core::convert::{TryFrom, TryInto};
use heapless::{String, Vec};
pub use core::ops::Sub;
pub use heapless::consts::{B1, U4};
pub use heapless::ArrayLength;
pub use typenum::Diff;
pub use typenum::Sub1;
mod test;
#[derive(Debug)]
pub enum CommandError {
BufferInUse,
BufferNotReady,
CallbackFailed,
DataVecNoData,
DataVecTooSmall,
IdNotImplemented(HidIoCommandId, HidIoPacketType),
IdNotMatched(HidIoCommandId),
IdNotSupported(HidIoCommandId),
IdVecTooSmall,
InvalidCStr,
InvalidId(u32),
InvalidPacketBufferType(HidIoPacketType),
InvalidProperty8(u8),
InvalidRxMessage(HidIoPacketType),
InvalidUtf8(core::str::Utf8Error),
PacketDecodeError(HidIoParseError),
RxFailed,
RxTimeout,
RxTooManySyncs,
SerializationFailed(HidIoParseError),
SerializationVecTooSmall,
TestFailure,
TxBufferSendFailed,
TxBufferVecTooSmall,
TxNoActiveReceivers,
}
pub mod h0000 {
use super::super::HidIoCommandId;
use heapless::{ArrayLength, Vec};
#[derive(Clone, Debug)]
pub struct Cmd {}
#[derive(Clone, Debug)]
pub struct Ack<ID: ArrayLength<HidIoCommandId>> {
pub ids: Vec<HidIoCommandId, ID>,
}
#[derive(Clone, Debug)]
pub struct Nak {}
}
pub mod h0001 {
use heapless::{ArrayLength, String};
use num_enum::TryFromPrimitive;
#[repr(u8)]
#[derive(PartialEq, Clone, Copy, Debug, TryFromPrimitive)]
pub enum Property {
Unknown = 0x00,
MajorVersion = 0x01,
MinorVersion = 0x02,
PatchVersion = 0x03,
DeviceName = 0x04,
DeviceSerialNumber = 0x05,
DeviceVersion = 0x06,
DeviceMcu = 0x07,
FirmwareName = 0x08,
FirmwareVersion = 0x09,
DeviceVendor = 0x0A,
OsType = 0x0B,
OsVersion = 0x0C,
HostSoftwareName = 0x0D,
}
#[repr(u8)]
#[derive(PartialEq, Clone, Copy, Debug, TryFromPrimitive)]
pub enum OsType {
Unknown = 0x00,
Windows = 0x01,
Linux = 0x02,
Android = 0x03,
MacOs = 0x04,
Ios = 0x05,
ChromeOs = 0x06,
}
#[derive(Clone, Debug)]
pub struct Cmd {
pub property: Property,
}
#[derive(Clone, Debug)]
pub struct Ack<S: ArrayLength<u8>> {
pub property: Property,
pub os: OsType,
pub number: u16,
pub string: String<S>,
}
#[derive(Clone, Debug)]
pub struct Nak {
pub property: Property,
}
}
pub mod h0002 {
use heapless::{ArrayLength, Vec};
#[derive(Clone, Debug)]
pub struct Cmd<D: ArrayLength<u8>> {
pub data: Vec<u8, D>,
}
#[derive(Clone, Debug)]
pub struct Ack<D: ArrayLength<u8>> {
pub data: Vec<u8, D>,
}
#[derive(Clone, Debug)]
pub struct Nak {}
}
pub mod h0003 {
#[derive(Clone, Debug)]
pub struct Cmd {}
#[derive(Clone, Debug)]
pub struct Ack {}
#[derive(Clone, Debug)]
pub struct Nak {}
}
pub mod h0010 {
use heapless::{ArrayLength, String, Vec};
use num_enum::TryFromPrimitive;
#[repr(u8)]
#[derive(PartialEq, Clone, Copy, Debug, TryFromPrimitive)]
pub enum Command {
ListFields = 0x00,
GetFieldName = 0x01,
GetFieldValue = 0x02,
Unknown = 0xFF,
}
#[derive(Clone, Debug)]
pub struct Cmd {
pub command: Command,
pub field: u8,
}
#[derive(Clone, Debug)]
pub struct Ack<S: ArrayLength<u8>> {
pub command: Command,
pub field: u8,
pub field_list: Vec<u8, S>,
pub string: String<S>,
}
#[derive(Clone, Debug)]
pub struct Nak {
pub command: Command,
pub field: u8,
}
}
pub mod h0011 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0012 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0013 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0014 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0015 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0016 {
use num_enum::TryFromPrimitive;
#[repr(u8)]
#[derive(PartialEq, Clone, Copy, Debug, TryFromPrimitive)]
pub enum Error {
NotSupported = 0x00,
Disabled = 0x01,
}
#[derive(Clone, Debug)]
pub struct Cmd {}
#[derive(Clone, Debug)]
pub struct Ack {
pub scancode: u16,
}
#[derive(Clone, Debug)]
pub struct Nak {
pub error: Error,
}
}
pub mod h0017 {
use heapless::{ArrayLength, String};
#[derive(Clone, Debug)]
pub struct Cmd<S: ArrayLength<u8>> {
pub string: String<S>,
}
#[derive(Clone, Debug)]
pub struct Ack {}
#[derive(Clone, Debug)]
pub struct Nak {}
}
pub mod h0018 {
use heapless::{ArrayLength, String};
#[derive(Clone, Debug)]
pub struct Cmd<S: ArrayLength<u8>> {
pub symbols: String<S>,
}
#[derive(Clone, Debug)]
pub struct Ack {}
#[derive(Clone, Debug)]
pub struct Nak {}
}
pub mod h0019 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h001a {
use num_enum::TryFromPrimitive;
#[repr(u8)]
#[derive(PartialEq, Clone, Copy, Debug, TryFromPrimitive)]
pub enum Error {
NotSupported = 0x00,
Disabled = 0x01,
NotReady = 0x02,
}
#[derive(Clone, Debug)]
pub struct Cmd {}
#[derive(Clone, Debug)]
pub struct Ack {}
#[derive(Clone, Debug)]
pub struct Nak {
pub error: Error,
}
}
pub mod h0020 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0021 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0022 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0023 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0024 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0025 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0030 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0031 {
use heapless::{ArrayLength, String};
#[derive(Clone, Debug)]
pub struct Cmd<S: ArrayLength<u8>> {
pub command: String<S>,
}
#[derive(Clone, Debug)]
pub struct Ack {}
#[derive(Clone, Debug)]
pub struct Nak {}
}
pub mod h0032 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0033 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0034 {
use heapless::{ArrayLength, String};
#[derive(Clone, Debug)]
pub struct Cmd<S: ArrayLength<u8>> {
pub output: String<S>,
}
#[derive(Clone, Debug)]
pub struct Ack {}
#[derive(Clone, Debug)]
pub struct Nak {}
}
pub mod h0040 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0041 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0042 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0043 {
pub struct Cmd {}
pub struct Ack {}
pub struct Nak {}
}
pub mod h0050 {
#[derive(Clone, Debug)]
pub struct Cmd {
pub command: u16,
pub argument: u16,
}
#[derive(Clone, Debug)]
pub struct Ack {}
#[derive(Clone, Debug)]
pub struct Nak {}
}
pub mod h0051 {
use heapless::{ArrayLength, Vec};
#[derive(Clone, Debug)]
pub struct Cmd<D: ArrayLength<u8>> {
pub command: u16,
pub argument: u16,
pub data: Vec<u8, D>,
}
#[derive(Clone, Debug)]
pub struct Ack {}
#[derive(Clone, Debug)]
pub struct Nak {}
}
pub trait Commands<H: ArrayLength<u8>, ID: ArrayLength<HidIoCommandId> + ArrayLength<u8>>
where
H: core::fmt::Debug + Sub<B1> + Sub<U4>,
{
fn tx_packetbuffer_send(&mut self, buf: &mut HidIoPacketBuffer<H>) -> Result<(), CommandError>;
fn supported_id(&self, _id: HidIoCommandId) -> bool {
true
}
fn default_packet_chunk(&self) -> u32 {
64
}
fn empty_ack(&mut self, id: HidIoCommandId) -> Result<(), CommandError> {
self.tx_packetbuffer_send(&mut HidIoPacketBuffer {
ptype: HidIoPacketType::Ack,
id,
max_len: self.default_packet_chunk(),
done: true,
..Default::default()
})
}
fn empty_nak(&mut self, id: HidIoCommandId) -> Result<(), CommandError> {
self.tx_packetbuffer_send(&mut HidIoPacketBuffer {
ptype: HidIoPacketType::Nak,
id,
max_len: self.default_packet_chunk(),
done: true,
..Default::default()
})
}
fn byte_ack(&mut self, id: HidIoCommandId, byte: u8) -> Result<(), CommandError> {
self.tx_packetbuffer_send(&mut HidIoPacketBuffer {
ptype: HidIoPacketType::Ack,
id,
max_len: self.default_packet_chunk(),
data: Vec::from_slice(&[byte]).unwrap(),
done: true,
})
}
fn byte_nak(&mut self, id: HidIoCommandId, byte: u8) -> Result<(), CommandError> {
self.tx_packetbuffer_send(&mut HidIoPacketBuffer {
ptype: HidIoPacketType::Nak,
id,
max_len: self.default_packet_chunk(),
data: Vec::from_slice(&[byte]).unwrap(),
done: true,
})
}
fn short_ack(&mut self, id: HidIoCommandId, val: u16) -> Result<(), CommandError> {
self.tx_packetbuffer_send(&mut HidIoPacketBuffer {
ptype: HidIoPacketType::Ack,
id,
max_len: self.default_packet_chunk(),
data: Vec::from_slice(&val.to_le_bytes()).unwrap(),
done: true,
})
}
fn short_nak(&mut self, id: HidIoCommandId, val: u16) -> Result<(), CommandError> {
self.tx_packetbuffer_send(&mut HidIoPacketBuffer {
ptype: HidIoPacketType::Nak,
id,
max_len: self.default_packet_chunk(),
data: Vec::from_slice(&val.to_le_bytes()).unwrap(),
done: true,
})
}
fn rx_message_handling(&mut self, buf: HidIoPacketBuffer<H>) -> Result<(), CommandError>
where
<H as Sub<B1>>::Output: ArrayLength<u8>,
<H as Sub<U4>>::Output: ArrayLength<u8>,
{
if !self.supported_id(buf.id) {
return Err(CommandError::IdNotSupported(buf.id));
}
match buf.ptype {
HidIoPacketType::Data | HidIoPacketType::NaData => {}
HidIoPacketType::Ack => {}
HidIoPacketType::Nak => {}
_ => {
return Err(CommandError::InvalidRxMessage(buf.ptype));
}
}
match buf.id {
HidIoCommandId::SupportedIds => self.h0000_supported_ids_handler(buf),
HidIoCommandId::GetInfo => self.h0001_info_handler(buf),
HidIoCommandId::TestPacket => self.h0002_test_handler(buf),
HidIoCommandId::ResetHidIo => self.h0003_resethidio_handler(buf),
HidIoCommandId::FlashMode => self.h0016_flashmode_handler(buf),
HidIoCommandId::UnicodeText => self.h0017_unicodetext_handler(buf),
HidIoCommandId::UnicodeState => self.h0018_unicodestate_handler(buf),
HidIoCommandId::SleepMode => self.h001a_sleepmode_handler(buf),
HidIoCommandId::TerminalCmd => self.h0031_terminalcmd_handler(buf),
HidIoCommandId::TerminalOut => self.h0034_terminalout_handler(buf),
HidIoCommandId::ManufacturingTest => self.h0050_manufacturing_handler(buf),
HidIoCommandId::ManufacturingResult => self.h0051_manufacturingres_handler(buf),
_ => Err(CommandError::IdNotMatched(buf.id)),
}
}
fn h0000_supported_ids(&mut self, _data: h0000::Cmd) -> Result<(), CommandError> {
self.tx_packetbuffer_send(&mut HidIoPacketBuffer {
id: HidIoCommandId::SupportedIds,
max_len: self.default_packet_chunk(),
done: true,
..Default::default()
})
}
fn h0000_supported_ids_cmd(&mut self, _data: h0000::Cmd) -> Result<h0000::Ack<ID>, h0000::Nak> {
Err(h0000::Nak {})
}
fn h0000_supported_ids_ack(&mut self, _data: h0000::Ack<ID>) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::SupportedIds,
HidIoPacketType::Ack,
))
}
fn h0000_supported_ids_nak(&mut self, _data: h0000::Nak) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::SupportedIds,
HidIoPacketType::Nak,
))
}
fn h0000_supported_ids_handler(
&mut self,
buf: HidIoPacketBuffer<H>,
) -> Result<(), CommandError> {
match buf.ptype {
HidIoPacketType::Data => {
match self.h0000_supported_ids_cmd(h0000::Cmd {}) {
Ok(ack) => {
let mut buf = HidIoPacketBuffer {
ptype: HidIoPacketType::Ack,
id: buf.id,
max_len: self.default_packet_chunk(),
done: true,
..Default::default()
};
for id in ack.ids {
if buf
.data
.extend_from_slice(&(id as u16).to_le_bytes())
.is_err()
{
return Err(CommandError::IdVecTooSmall);
}
}
self.tx_packetbuffer_send(&mut buf)
}
Err(_nak) => self.empty_nak(buf.id),
}
}
HidIoPacketType::NaData => Err(CommandError::InvalidPacketBufferType(buf.ptype)),
HidIoPacketType::Ack => {
let mut ids: Vec<HidIoCommandId, ID> = Vec::new();
let mut pos = 0;
while pos <= buf.data.len() - 2 {
let slice = &buf.data[pos..pos + 2];
let idnum = u16::from_le_bytes(slice.try_into().unwrap()) as u32;
let id = match HidIoCommandId::try_from(idnum) {
Ok(id) => id,
Err(_) => {
return Err(CommandError::InvalidId(idnum));
}
};
if ids.push(id).is_err() {
break;
}
pos += 2;
}
self.h0000_supported_ids_ack(h0000::Ack { ids })
}
HidIoPacketType::Nak => self.h0000_supported_ids_nak(h0000::Nak {}),
_ => Ok(()),
}
}
fn h0001_info(&mut self, data: h0001::Cmd) -> Result<(), CommandError> {
let mut buf = HidIoPacketBuffer {
id: HidIoCommandId::GetInfo,
max_len: self.default_packet_chunk(),
done: true,
..Default::default()
};
if buf.data.push(data.property as u8).is_err() {
return Err(CommandError::DataVecTooSmall);
}
self.tx_packetbuffer_send(&mut buf)
}
fn h0001_info_cmd(&mut self, _data: h0001::Cmd) -> Result<h0001::Ack<Sub1<H>>, h0001::Nak>
where
<H as Sub<B1>>::Output: ArrayLength<u8>,
{
Err(h0001::Nak {
property: h0001::Property::Unknown,
})
}
fn h0001_info_ack(&mut self, _data: h0001::Ack<Sub1<H>>) -> Result<(), CommandError>
where
<H as Sub<B1>>::Output: ArrayLength<u8>,
{
Err(CommandError::IdNotImplemented(
HidIoCommandId::GetInfo,
HidIoPacketType::Ack,
))
}
fn h0001_info_nak(&mut self, _data: h0001::Nak) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::GetInfo,
HidIoPacketType::Nak,
))
}
fn h0001_info_handler(&mut self, buf: HidIoPacketBuffer<H>) -> Result<(), CommandError>
where
<H as Sub<B1>>::Output: ArrayLength<u8>,
{
match buf.ptype {
HidIoPacketType::Data => {
if buf.data.len() < 1 {
return Err(CommandError::DataVecNoData);
}
let property = match h0001::Property::try_from(buf.data[0]) {
Ok(property) => property,
Err(_) => {
return Err(CommandError::InvalidProperty8(buf.data[0]));
}
};
match self.h0001_info_cmd(h0001::Cmd { property }) {
Ok(ack) => {
let mut buf = HidIoPacketBuffer {
ptype: HidIoPacketType::Ack,
id: buf.id,
max_len: self.default_packet_chunk(),
done: true,
..Default::default()
};
if buf.data.push(ack.property as u8).is_err() {
return Err(CommandError::DataVecTooSmall);
}
match property {
h0001::Property::Unknown => {}
h0001::Property::MajorVersion
| h0001::Property::MinorVersion
| h0001::Property::PatchVersion => {
for byte in &ack.number.to_le_bytes() {
if buf.data.push(*byte).is_err() {
return Err(CommandError::DataVecTooSmall);
}
}
}
h0001::Property::OsType => {
if buf.data.push(ack.os as u8).is_err() {
return Err(CommandError::DataVecTooSmall);
}
}
_ => {
for byte in ack.string.into_bytes() {
if buf.data.push(byte).is_err() {
return Err(CommandError::DataVecTooSmall);
}
}
}
}
self.tx_packetbuffer_send(&mut buf)
}
Err(_nak) => self.byte_nak(buf.id, property as u8),
}
}
HidIoPacketType::NaData => Err(CommandError::InvalidPacketBufferType(buf.ptype)),
HidIoPacketType::Ack => {
if buf.data.len() < 1 {
return Err(CommandError::DataVecNoData);
}
let property = match h0001::Property::try_from(buf.data[0]) {
Ok(property) => property,
Err(_) => {
return Err(CommandError::InvalidProperty8(buf.data[0]));
}
};
let mut ack = h0001::Ack {
property,
os: h0001::OsType::Unknown,
number: 0,
string: String::new(),
};
match property {
h0001::Property::Unknown => {}
h0001::Property::MajorVersion
| h0001::Property::MinorVersion
| h0001::Property::PatchVersion => {
ack.number = u16::from_le_bytes(buf.data[1..3].try_into().unwrap());
}
h0001::Property::OsType => {
let typenum = buf.data[1];
ack.os = match h0001::OsType::try_from(typenum) {
Ok(ostype) => ostype,
Err(_) => {
return Err(CommandError::InvalidProperty8(typenum));
}
};
}
_ => {
let bytes: Vec<u8, Sub1<H>> = Vec::from_slice(&buf.data[1..]).unwrap();
let string = match String::from_utf8(bytes) {
Ok(string) => string,
Err(e) => {
return Err(CommandError::InvalidUtf8(e));
}
};
ack.string = string;
}
}
self.h0001_info_ack(ack)
}
HidIoPacketType::Nak => {
if buf.data.len() < 1 {
return Err(CommandError::DataVecNoData);
}
let property = match h0001::Property::try_from(buf.data[0]) {
Ok(property) => property,
Err(_) => {
return Err(CommandError::InvalidProperty8(buf.data[0]));
}
};
self.h0001_info_nak(h0001::Nak { property })
}
_ => Ok(()),
}
}
fn h0002_test(&mut self, data: h0002::Cmd<H>, na: bool) -> Result<(), CommandError> {
let mut buf = HidIoPacketBuffer {
id: HidIoCommandId::TestPacket,
max_len: self.default_packet_chunk(),
..Default::default()
};
if na {
buf.ptype = HidIoPacketType::NaData;
}
if !buf.append_payload(&data.data) {
return Err(CommandError::DataVecTooSmall);
}
buf.done = true;
self.tx_packetbuffer_send(&mut buf)
}
fn h0002_test_cmd(&mut self, _data: h0002::Cmd<H>) -> Result<h0002::Ack<H>, h0002::Nak> {
Err(h0002::Nak {})
}
fn h0002_test_nacmd(&mut self, _data: h0002::Cmd<H>) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::TestPacket,
HidIoPacketType::NaData,
))
}
fn h0002_test_ack(&mut self, _data: h0002::Ack<H>) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::TestPacket,
HidIoPacketType::Ack,
))
}
fn h0002_test_nak(&mut self, _data: h0002::Nak) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::TestPacket,
HidIoPacketType::Nak,
))
}
fn h0002_test_handler(&mut self, buf: HidIoPacketBuffer<H>) -> Result<(), CommandError> {
match buf.ptype {
HidIoPacketType::Data => {
let cmd = h0002::Cmd::<H> {
data: match Vec::from_slice(&buf.data) {
Ok(data) => data,
Err(_) => {
return Err(CommandError::DataVecTooSmall);
}
},
};
match self.h0002_test_cmd(cmd) {
Ok(ack) => {
let mut buf = HidIoPacketBuffer {
ptype: HidIoPacketType::Ack,
id: buf.id,
max_len: self.default_packet_chunk(),
..Default::default()
};
if !buf.append_payload(&ack.data) {
return Err(CommandError::DataVecTooSmall);
}
buf.done = true;
self.tx_packetbuffer_send(&mut buf)
}
Err(_nak) => self.empty_nak(buf.id),
}
}
HidIoPacketType::NaData => {
let cmd = h0002::Cmd::<H> {
data: match Vec::from_slice(&buf.data) {
Ok(data) => data,
Err(_) => {
return Err(CommandError::DataVecTooSmall);
}
},
};
self.h0002_test_nacmd(cmd)
}
HidIoPacketType::Ack => {
let ack = h0002::Ack::<H> {
data: match Vec::from_slice(&buf.data) {
Ok(data) => data,
Err(_) => {
return Err(CommandError::DataVecTooSmall);
}
},
};
self.h0002_test_ack(ack)
}
HidIoPacketType::Nak => self.h0002_test_nak(h0002::Nak {}),
_ => Ok(()),
}
}
fn h0003_resethidio(&mut self, _data: h0003::Cmd) -> Result<(), CommandError> {
self.tx_packetbuffer_send(&mut HidIoPacketBuffer {
id: HidIoCommandId::ResetHidIo,
max_len: self.default_packet_chunk(),
done: true,
..Default::default()
})
}
fn h0003_resethidio_cmd(&mut self, _data: h0003::Cmd) -> Result<h0003::Ack, h0003::Nak> {
Err(h0003::Nak {})
}
fn h0003_resethidio_ack(&mut self, _data: h0003::Ack) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::ResetHidIo,
HidIoPacketType::Ack,
))
}
fn h0003_resethidio_nak(&mut self, _data: h0003::Nak) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::ResetHidIo,
HidIoPacketType::Nak,
))
}
fn h0003_resethidio_handler(&mut self, buf: HidIoPacketBuffer<H>) -> Result<(), CommandError> {
match buf.ptype {
HidIoPacketType::Data => match self.h0003_resethidio_cmd(h0003::Cmd {}) {
Ok(_ack) => self.empty_ack(buf.id),
Err(_nak) => self.empty_nak(buf.id),
},
HidIoPacketType::NaData => Err(CommandError::InvalidPacketBufferType(buf.ptype)),
HidIoPacketType::Ack => self.h0003_resethidio_ack(h0003::Ack {}),
HidIoPacketType::Nak => self.h0003_resethidio_nak(h0003::Nak {}),
_ => Ok(()),
}
}
fn h0016_flashmode(&mut self, _data: h0016::Cmd) -> Result<(), CommandError> {
self.tx_packetbuffer_send(&mut HidIoPacketBuffer {
id: HidIoCommandId::FlashMode,
max_len: self.default_packet_chunk(),
done: true,
..Default::default()
})
}
fn h0016_flashmode_cmd(&mut self, _data: h0016::Cmd) -> Result<h0016::Ack, h0016::Nak> {
Err(h0016::Nak {
error: h0016::Error::NotSupported,
})
}
fn h0016_flashmode_ack(&mut self, _data: h0016::Ack) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::FlashMode,
HidIoPacketType::Ack,
))
}
fn h0016_flashmode_nak(&mut self, _data: h0016::Nak) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::FlashMode,
HidIoPacketType::Nak,
))
}
fn h0016_flashmode_handler(&mut self, buf: HidIoPacketBuffer<H>) -> Result<(), CommandError> {
match buf.ptype {
HidIoPacketType::Data => match self.h0016_flashmode_cmd(h0016::Cmd {}) {
Ok(ack) => self.short_ack(buf.id, ack.scancode),
Err(nak) => self.byte_nak(buf.id, nak.error as u8),
},
HidIoPacketType::NaData => Err(CommandError::InvalidPacketBufferType(buf.ptype)),
HidIoPacketType::Ack => {
if buf.data.len() < 2 {
return Err(CommandError::DataVecNoData);
}
let scancode = u16::from_le_bytes(buf.data[0..2].try_into().unwrap());
self.h0016_flashmode_ack(h0016::Ack { scancode })
}
HidIoPacketType::Nak => {
if buf.data.len() < 1 {
return Err(CommandError::DataVecNoData);
}
let error = match h0016::Error::try_from(buf.data[0]) {
Ok(error) => error,
Err(_) => {
return Err(CommandError::InvalidProperty8(buf.data[0]));
}
};
self.h0016_flashmode_nak(h0016::Nak { error })
}
_ => Ok(()),
}
}
fn h0017_unicodetext(&mut self, data: h0017::Cmd<H>, na: bool) -> Result<(), CommandError> {
let mut buf = HidIoPacketBuffer {
id: HidIoCommandId::UnicodeText,
max_len: self.default_packet_chunk(),
..Default::default()
};
if na {
buf.ptype = HidIoPacketType::NaData;
}
if !buf.append_payload(data.string.as_bytes()) {
return Err(CommandError::DataVecTooSmall);
}
buf.done = true;
self.tx_packetbuffer_send(&mut buf)
}
fn h0017_unicodetext_cmd(&mut self, _data: h0017::Cmd<H>) -> Result<h0017::Ack, h0017::Nak> {
Err(h0017::Nak {})
}
fn h0017_unicodetext_nacmd(&mut self, _data: h0017::Cmd<H>) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::UnicodeText,
HidIoPacketType::NaData,
))
}
fn h0017_unicodetext_ack(&mut self, _data: h0017::Ack) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::UnicodeText,
HidIoPacketType::Ack,
))
}
fn h0017_unicodetext_nak(&mut self, _data: h0017::Nak) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::UnicodeText,
HidIoPacketType::Nak,
))
}
fn h0017_unicodetext_handler(&mut self, buf: HidIoPacketBuffer<H>) -> Result<(), CommandError> {
match buf.ptype {
HidIoPacketType::Data => {
let cmd = h0017::Cmd::<H> {
string: match String::from_utf8(buf.data) {
Ok(string) => string,
Err(e) => {
return Err(CommandError::InvalidUtf8(e));
}
},
};
match self.h0017_unicodetext_cmd(cmd) {
Ok(_ack) => self.empty_ack(buf.id),
Err(_nak) => self.empty_nak(buf.id),
}
}
HidIoPacketType::NaData => {
let cmd = h0017::Cmd::<H> {
string: match String::from_utf8(buf.data) {
Ok(string) => string,
Err(e) => {
return Err(CommandError::InvalidUtf8(e));
}
},
};
self.h0017_unicodetext_nacmd(cmd)
}
HidIoPacketType::Ack => self.h0017_unicodetext_ack(h0017::Ack {}),
HidIoPacketType::Nak => self.h0017_unicodetext_nak(h0017::Nak {}),
_ => Ok(()),
}
}
fn h0018_unicodestate(&mut self, data: h0018::Cmd<H>, na: bool) -> Result<(), CommandError> {
let mut buf = HidIoPacketBuffer {
id: HidIoCommandId::UnicodeState,
max_len: self.default_packet_chunk(),
..Default::default()
};
if na {
buf.ptype = HidIoPacketType::NaData;
}
if !buf.append_payload(data.symbols.as_bytes()) {
return Err(CommandError::DataVecTooSmall);
}
buf.done = true;
self.tx_packetbuffer_send(&mut buf)
}
fn h0018_unicodestate_cmd(&mut self, _data: h0018::Cmd<H>) -> Result<h0018::Ack, h0018::Nak> {
Err(h0018::Nak {})
}
fn h0018_unicodestate_nacmd(&mut self, _data: h0018::Cmd<H>) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::UnicodeState,
HidIoPacketType::NaData,
))
}
fn h0018_unicodestate_ack(&mut self, _data: h0018::Ack) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::UnicodeState,
HidIoPacketType::Ack,
))
}
fn h0018_unicodestate_nak(&mut self, _data: h0018::Nak) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::UnicodeState,
HidIoPacketType::Nak,
))
}
fn h0018_unicodestate_handler(
&mut self,
buf: HidIoPacketBuffer<H>,
) -> Result<(), CommandError> {
match buf.ptype {
HidIoPacketType::Data => {
let cmd = h0018::Cmd::<H> {
symbols: match String::from_utf8(buf.data) {
Ok(symbols) => symbols,
Err(e) => {
return Err(CommandError::InvalidUtf8(e));
}
},
};
match self.h0018_unicodestate_cmd(cmd) {
Ok(_ack) => self.empty_ack(buf.id),
Err(_nak) => self.empty_nak(buf.id),
}
}
HidIoPacketType::NaData => {
let cmd = h0018::Cmd::<H> {
symbols: match String::from_utf8(buf.data) {
Ok(symbols) => symbols,
Err(e) => {
return Err(CommandError::InvalidUtf8(e));
}
},
};
self.h0018_unicodestate_nacmd(cmd)
}
HidIoPacketType::Ack => self.h0018_unicodestate_ack(h0018::Ack {}),
HidIoPacketType::Nak => self.h0018_unicodestate_nak(h0018::Nak {}),
_ => Ok(()),
}
}
fn h001a_sleepmode(&mut self, _data: h001a::Cmd) -> Result<(), CommandError> {
self.tx_packetbuffer_send(&mut HidIoPacketBuffer {
id: HidIoCommandId::SleepMode,
max_len: self.default_packet_chunk(),
done: true,
..Default::default()
})
}
fn h001a_sleepmode_cmd(&mut self, _data: h001a::Cmd) -> Result<h001a::Ack, h001a::Nak> {
Err(h001a::Nak {
error: h001a::Error::NotSupported,
})
}
fn h001a_sleepmode_ack(&mut self, _data: h001a::Ack) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::FlashMode,
HidIoPacketType::Ack,
))
}
fn h001a_sleepmode_nak(&mut self, _data: h001a::Nak) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::FlashMode,
HidIoPacketType::Nak,
))
}
fn h001a_sleepmode_handler(&mut self, buf: HidIoPacketBuffer<H>) -> Result<(), CommandError> {
match buf.ptype {
HidIoPacketType::Data => match self.h001a_sleepmode_cmd(h001a::Cmd {}) {
Ok(_ack) => self.empty_ack(buf.id),
Err(nak) => self.byte_nak(buf.id, nak.error as u8),
},
HidIoPacketType::NaData => Err(CommandError::InvalidPacketBufferType(buf.ptype)),
HidIoPacketType::Ack => self.h001a_sleepmode_ack(h001a::Ack {}),
HidIoPacketType::Nak => {
if buf.data.len() < 1 {
return Err(CommandError::DataVecNoData);
}
let error = match h001a::Error::try_from(buf.data[0]) {
Ok(error) => error,
Err(_) => {
return Err(CommandError::InvalidProperty8(buf.data[0]));
}
};
self.h001a_sleepmode_nak(h001a::Nak { error })
}
_ => Ok(()),
}
}
fn h0031_terminalcmd(&mut self, data: h0031::Cmd<H>, na: bool) -> Result<(), CommandError> {
let mut buf = HidIoPacketBuffer {
id: HidIoCommandId::TerminalCmd,
max_len: self.default_packet_chunk(),
..Default::default()
};
if na {
buf.ptype = HidIoPacketType::NaData;
}
if !buf.append_payload(&data.command.as_bytes()) {
return Err(CommandError::DataVecTooSmall);
}
buf.done = true;
self.tx_packetbuffer_send(&mut buf)
}
fn h0031_terminalcmd_cmd(&mut self, _data: h0031::Cmd<H>) -> Result<h0031::Ack, h0031::Nak> {
Err(h0031::Nak {})
}
fn h0031_terminalcmd_nacmd(&mut self, _data: h0031::Cmd<H>) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::TerminalCmd,
HidIoPacketType::NaData,
))
}
fn h0031_terminalcmd_ack(&mut self, _data: h0031::Ack) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::TerminalCmd,
HidIoPacketType::Ack,
))
}
fn h0031_terminalcmd_nak(&mut self, _data: h0031::Nak) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::TerminalCmd,
HidIoPacketType::Nak,
))
}
fn h0031_terminalcmd_handler(&mut self, buf: HidIoPacketBuffer<H>) -> Result<(), CommandError> {
match buf.ptype {
HidIoPacketType::Data => {
let cmd = h0031::Cmd::<H> {
command: match String::from_utf8(buf.data) {
Ok(string) => string,
Err(e) => {
return Err(CommandError::InvalidUtf8(e));
}
},
};
match self.h0031_terminalcmd_cmd(cmd) {
Ok(_ack) => self.empty_ack(buf.id),
Err(_nak) => self.empty_nak(buf.id),
}
}
HidIoPacketType::NaData => {
let cmd = h0031::Cmd::<H> {
command: match String::from_utf8(buf.data) {
Ok(string) => string,
Err(e) => {
return Err(CommandError::InvalidUtf8(e));
}
},
};
self.h0031_terminalcmd_nacmd(cmd)
}
HidIoPacketType::Ack => self.h0031_terminalcmd_ack(h0031::Ack {}),
HidIoPacketType::Nak => self.h0031_terminalcmd_nak(h0031::Nak {}),
_ => Ok(()),
}
}
fn h0034_terminalout(&mut self, data: h0034::Cmd<H>, na: bool) -> Result<(), CommandError> {
let mut buf = HidIoPacketBuffer {
id: HidIoCommandId::TerminalOut,
max_len: self.default_packet_chunk(),
..Default::default()
};
if na {
buf.ptype = HidIoPacketType::NaData;
}
if !buf.append_payload(&data.output.as_bytes()) {
return Err(CommandError::DataVecTooSmall);
}
buf.done = true;
self.tx_packetbuffer_send(&mut buf)
}
fn h0034_terminalout_cmd(&mut self, _data: h0034::Cmd<H>) -> Result<h0034::Ack, h0034::Nak> {
Err(h0034::Nak {})
}
fn h0034_terminalout_nacmd(&mut self, _data: h0034::Cmd<H>) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::TerminalOut,
HidIoPacketType::NaData,
))
}
fn h0034_terminalout_ack(&mut self, _data: h0034::Ack) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::TerminalOut,
HidIoPacketType::Ack,
))
}
fn h0034_terminalout_nak(&mut self, _data: h0034::Nak) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::TerminalOut,
HidIoPacketType::Nak,
))
}
fn h0034_terminalout_handler(&mut self, buf: HidIoPacketBuffer<H>) -> Result<(), CommandError> {
match buf.ptype {
HidIoPacketType::Data => {
let cmd = h0034::Cmd::<H> {
output: match String::from_utf8(buf.data) {
Ok(string) => string,
Err(e) => {
return Err(CommandError::InvalidUtf8(e));
}
},
};
match self.h0034_terminalout_cmd(cmd) {
Ok(_ack) => self.empty_ack(buf.id),
Err(_nak) => self.empty_nak(buf.id),
}
}
HidIoPacketType::NaData => {
let cmd = h0034::Cmd::<H> {
output: match String::from_utf8(buf.data) {
Ok(string) => string,
Err(e) => {
return Err(CommandError::InvalidUtf8(e));
}
},
};
self.h0034_terminalout_nacmd(cmd)
}
HidIoPacketType::Ack => self.h0034_terminalout_ack(h0034::Ack {}),
HidIoPacketType::Nak => self.h0034_terminalout_nak(h0034::Nak {}),
_ => Ok(()),
}
}
fn h0050_manufacturing(&mut self, data: h0050::Cmd) -> Result<(), CommandError> {
let mut buf = HidIoPacketBuffer {
id: HidIoCommandId::ManufacturingTest,
max_len: self.default_packet_chunk(),
..Default::default()
};
if !buf.append_payload(&data.command.to_le_bytes()) {
return Err(CommandError::DataVecTooSmall);
}
if !buf.append_payload(&data.argument.to_le_bytes()) {
return Err(CommandError::DataVecTooSmall);
}
buf.done = true;
self.tx_packetbuffer_send(&mut buf)
}
fn h0050_manufacturing_cmd(&mut self, _data: h0050::Cmd) -> Result<h0050::Ack, h0050::Nak> {
Err(h0050::Nak {})
}
fn h0050_manufacturing_ack(&mut self, _data: h0050::Ack) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::ManufacturingTest,
HidIoPacketType::Ack,
))
}
fn h0050_manufacturing_nak(&mut self, _data: h0050::Nak) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::ManufacturingTest,
HidIoPacketType::Nak,
))
}
fn h0050_manufacturing_handler(
&mut self,
buf: HidIoPacketBuffer<H>,
) -> Result<(), CommandError> {
match buf.ptype {
HidIoPacketType::Data => {
if buf.data.len() < 4 {
return Err(CommandError::DataVecNoData);
}
let command = u16::from_le_bytes(buf.data[0..2].try_into().unwrap());
let argument = u16::from_le_bytes(buf.data[2..4].try_into().unwrap());
match self.h0050_manufacturing_cmd(h0050::Cmd { command, argument }) {
Ok(_ack) => self.empty_ack(buf.id),
Err(_nak) => self.empty_nak(buf.id),
}
}
HidIoPacketType::NaData => Err(CommandError::InvalidPacketBufferType(buf.ptype)),
HidIoPacketType::Ack => self.h0050_manufacturing_ack(h0050::Ack {}),
HidIoPacketType::Nak => self.h0050_manufacturing_nak(h0050::Nak {}),
_ => Ok(()),
}
}
fn h0051_manufacturingres(&mut self, data: h0051::Cmd<Diff<H, U4>>) -> Result<(), CommandError>
where
<H as Sub<U4>>::Output: ArrayLength<u8>,
{
let mut buf = HidIoPacketBuffer {
id: HidIoCommandId::ManufacturingResult,
max_len: self.default_packet_chunk(),
..Default::default()
};
if !buf.append_payload(&data.command.to_le_bytes()) {
return Err(CommandError::DataVecTooSmall);
}
if !buf.append_payload(&data.argument.to_le_bytes()) {
return Err(CommandError::DataVecTooSmall);
}
if !buf.append_payload(&data.data) {
return Err(CommandError::DataVecTooSmall);
}
buf.done = true;
self.tx_packetbuffer_send(&mut buf)
}
fn h0051_manufacturingres_cmd(
&mut self,
_data: h0051::Cmd<Diff<H, U4>>,
) -> Result<h0051::Ack, h0051::Nak>
where
<H as Sub<U4>>::Output: ArrayLength<u8>,
{
Err(h0051::Nak {})
}
fn h0051_manufacturingres_ack(&mut self, _data: h0051::Ack) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::ManufacturingResult,
HidIoPacketType::Ack,
))
}
fn h0051_manufacturingres_nak(&mut self, _data: h0051::Nak) -> Result<(), CommandError> {
Err(CommandError::IdNotImplemented(
HidIoCommandId::ManufacturingResult,
HidIoPacketType::Nak,
))
}
fn h0051_manufacturingres_handler(
&mut self,
buf: HidIoPacketBuffer<H>,
) -> Result<(), CommandError>
where
<H as Sub<U4>>::Output: ArrayLength<u8>,
{
match buf.ptype {
HidIoPacketType::Data => {
if buf.data.len() < 4 {
return Err(CommandError::DataVecNoData);
}
let command = u16::from_le_bytes(buf.data[0..2].try_into().unwrap());
let argument = u16::from_le_bytes(buf.data[2..4].try_into().unwrap());
let data: Vec<u8, Diff<H, U4>> = if buf.data.len() > 4 {
Vec::from_slice(&buf.data[5..]).unwrap()
} else {
Vec::new()
};
match self.h0051_manufacturingres_cmd(h0051::Cmd {
command,
argument,
data,
}) {
Ok(_ack) => self.empty_ack(buf.id),
Err(_nak) => self.empty_nak(buf.id),
}
}
HidIoPacketType::NaData => Err(CommandError::InvalidPacketBufferType(buf.ptype)),
HidIoPacketType::Ack => self.h0051_manufacturingres_ack(h0051::Ack {}),
HidIoPacketType::Nak => self.h0051_manufacturingres_nak(h0051::Nak {}),
_ => Ok(()),
}
}
}