From f80cef80cf685066fb50385e14568bf86e700d88 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Mon, 18 Feb 2019 22:24:25 +0000 Subject: Use ssmarshal to convert data from and to byte slices Previously, we manually converted the request and response data from and to byte slices. This patch adds the ssmarshal dependency that automates the serialization and deserialization in the required format. --- src/commands.rs | 77 +++++++++++---------------------------------------------- 1 file changed, 14 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/commands.rs b/src/commands.rs index 62e2983..d2769ed 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -2,7 +2,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later use core::default::Default; -use core::marker::Sized; + +use serde::{Deserialize, Serialize}; +use serde::de::DeserializeOwned; use crate::device::CommandStatus; @@ -16,32 +18,21 @@ enum_cmd! { } } -trait RequestData: Sized { - fn from_bytes(data: &[u8]) -> Option; -} - -impl RequestData for () { - fn from_bytes(_data: &[u8]) -> Option { - Some(()) - } -} - -trait ResponseData { - fn write_bytes(&self, buf: &mut [u8]); -} - trait Command { - type Request: RequestData; - type Response: ResponseData; + type Request: DeserializeOwned; + type Response: Serialize; fn execute(data: Self::Request) -> Result; fn execute_raw(data: &[u8], buf: &mut [u8]) -> CommandStatus { - if let Some(request) = Self::Request::from_bytes(data) { + // TODO: better error if (de-)serialization fails + if let Ok((request, _)) = ssmarshal::deserialize::(data) { match Self::execute(request) { Ok(response) => { - response.write_bytes(buf); - CommandStatus::Ok + match ssmarshal::serialize(buf, &response) { + Ok(_) => CommandStatus::Ok, + Err(_) => CommandStatus::NotSupported, + } } Err(status) => status, } @@ -51,7 +42,7 @@ trait Command { } } -#[derive(Debug, Default)] +#[derive(Debug, Default, Serialize)] struct GetStatusResponse { firmware_version_minor: u8, firmware_version_major: u8, @@ -60,27 +51,6 @@ struct GetStatusResponse { config_capslock: u8, config_enable_user_password: u8, config_delete_user_password: u8, - buf: [u8; 10], -} - -impl ResponseData for GetStatusResponse { - fn write_bytes(&self, buf: &mut [u8]) { - let card_serial = self.card_serial.to_le_bytes(); - let data = &[ - self.firmware_version_minor, - self.firmware_version_major, - card_serial[0], - card_serial[1], - card_serial[2], - card_serial[3], - self.config_numlock, - self.config_capslock, - self.config_enable_user_password, - self.config_delete_user_password, - ]; - assert!(buf.len() >= data.len()); - buf[..data.len()].copy_from_slice(data); - } } #[derive(Debug, Default)] @@ -97,35 +67,16 @@ impl Command for GetStatusCommand { } } -#[derive(Debug, Default)] +#[derive(Debug, Default, Deserialize)] struct ReadSlotNameRequest { internal_slot_number: u8, } -impl RequestData for ReadSlotNameRequest { - fn from_bytes(data: &[u8]) -> Option { - if data.is_empty() { - None - } else { - Some(ReadSlotNameRequest { - internal_slot_number: data[0], - }) - } - } -} - -#[derive(Debug, Default)] +#[derive(Debug, Default, Serialize)] struct ReadSlotNameResponse { slot_name: [u8; 15], } -impl ResponseData for ReadSlotNameResponse { - fn write_bytes(&self, buf: &mut [u8]) { - assert!(buf.len() >= self.slot_name.len()); - buf[..self.slot_name.len()].copy_from_slice(&self.slot_name) - } -} - #[derive(Debug, Default)] struct ReadSlotNameCommand {} -- cgit v1.2.3