diff options
author | Robin Krahl <robin.krahl@ireas.org> | 2019-02-18 22:24:25 +0000 |
---|---|---|
committer | Robin Krahl <robin.krahl@ireas.org> | 2019-02-18 23:27:55 +0100 |
commit | f80cef80cf685066fb50385e14568bf86e700d88 (patch) | |
tree | cde3257cd697af0e49b36182ae2545a3c9a83182 /src | |
parent | 9df0f3bd565dfbf8c97d02969a17504c688bf381 (diff) | |
download | ntw-f80cef80cf685066fb50385e14568bf86e700d88.tar.gz ntw-f80cef80cf685066fb50385e14568bf86e700d88.tar.bz2 |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/commands.rs | 77 |
1 files changed, 14 insertions, 63 deletions
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<Self>; -} - -impl RequestData for () { - fn from_bytes(_data: &[u8]) -> Option<Self> { - 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<Self::Response, CommandStatus>; 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::<Self::Request>(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<Self> { - 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 {} |