aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2019-02-18 22:24:25 +0000
committerRobin Krahl <robin.krahl@ireas.org>2019-02-18 23:27:55 +0100
commitf80cef80cf685066fb50385e14568bf86e700d88 (patch)
treecde3257cd697af0e49b36182ae2545a3c9a83182 /src
parent9df0f3bd565dfbf8c97d02969a17504c688bf381 (diff)
downloadntw-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.rs77
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 {}