aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2019-02-19 12:58:07 +0000
committerRobin Krahl <robin.krahl@ireas.org>2019-02-19 14:54:24 +0100
commit55d3369d9e7f68bb0c836c8143778b2918f01ba5 (patch)
tree06b1c6b9563423af40b3710e71970138e68f147d
parentffb3d8f11b232e811bebfe0c9b450a8a95a7b12b (diff)
downloadntw-55d3369d9e7f68bb0c836c8143778b2918f01ba5.tar.gz
ntw-55d3369d9e7f68bb0c836c8143778b2918f01ba5.tar.bz2
Use ssmarshal to generate the response data
Previously, we manually constructed the data to sent with a Get_Report response. This patch introduces the Response struct which can be serialized using ssmarshal. As Serialize is only implemented for arrays with a length up to 32, we have to use the serde-big-array crate for the data field. As the command ID might not be recognized by us, we use a raw u8 value instead of the CommandId enum.
-rw-r--r--Cargo.lock11
-rw-r--r--Cargo.toml1
-rw-r--r--src/device.rs62
3 files changed, 48 insertions, 26 deletions
diff --git a/Cargo.lock b/Cargo.lock
index a729af6..bb5177b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -78,6 +78,7 @@ dependencies = [
"embedded-hal 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde-big-array 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ssmarshal 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"stm32f103xx-usb 0.1.0 (git+https://github.com/mvirkkunen/stm32f103xx-usb?rev=57d23751367461bec5f39322727bdd65e5c2aa30)",
"stm32f1xx-hal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -161,6 +162,15 @@ dependencies = [
]
[[package]]
+name = "serde-big-array"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "serde_derive"
version = "1.0.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -275,6 +285,7 @@ dependencies = [
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "9f301d728f2b94c9a7691c90f07b0b4e8a4517181d9461be94c04bddeb4bd850"
+"checksum serde-big-array 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "dbd629249ae3007dac9632aa92334c5ba9c8a4dbe0a6263e546121dd1c57394a"
"checksum serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "beed18e6f5175aef3ba670e57c60ef3b1b74d250d962a26604bff4c80e970dd4"
"checksum ssmarshal 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3e6ad23b128192ed337dfa4f1b8099ced0c2bf30d61e551b65fda5916dbb850"
"checksum stm32f1 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48763f6f093674476399efbd8d2e52349dc32c3bbf57657234cbb15d309cd8a3"
diff --git a/Cargo.toml b/Cargo.toml
index a11296e..b5f2c65 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,7 @@ cortex-m = "0.5.8"
cortex-m-rt = "0.6.7"
embedded-hal = "0.2.2"
panic-halt = "0.2.0"
+serde-big-array = "0.1.4"
stm32f103xx-usb = { git = "https://github.com/mvirkkunen/stm32f103xx-usb", rev = "57d23751367461bec5f39322727bdd65e5c2aa30" }
usb-device = { git = "https://github.com/mvirkkunen/usb-device", rev = "e58e30f3b9c9bf4aab00ea039d129b964a3fd2d3" }
diff --git a/src/device.rs b/src/device.rs
index 300ce56..5fd0aed 100644
--- a/src/device.rs
+++ b/src/device.rs
@@ -1,6 +1,8 @@
// Copyright 2019 Robin Krahl <robin.krahl@ireas.org>
// SPDX-License-Identifier: GPL-3.0-or-later
+use serde::Serialize;
+use serde_big_array::big_array;
use usb_device::bus::{UsbBus, UsbBusAllocator};
use usb_device::device::{UsbDevice, UsbDeviceBuilder, UsbVidPid};
@@ -20,6 +22,8 @@ const REPORT_DESCRIPTOR: &[u8] = &[
0x75, 0x08, 0x95, 0x40, 0xB1, 0x02, 0xC0,
];
+big_array! { BigArray; COMMAND_LEN, }
+
enum_u8! {
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum DeviceStatus {
@@ -47,6 +51,30 @@ enum_u8! {
}
}
+#[derive(Serialize)]
+struct Response {
+ pub device_status: DeviceStatus,
+ pub command_id: u8,
+ pub last_crc: [u8; 4],
+ pub command_status: CommandStatus,
+ #[serde(with = "BigArray")]
+ pub data: [u8; COMMAND_LEN],
+ pub crc: u32,
+}
+
+impl Response {
+ fn new(device_status: DeviceStatus, command_id: u8) -> Response {
+ Response {
+ device_status,
+ command_id,
+ last_crc: [0; 4],
+ command_status: CommandStatus::NotSupported,
+ data: [0; COMMAND_LEN],
+ crc: 0,
+ }
+ }
+}
+
pub struct Nitrokey {
buf: [u8; REPORT_LEN],
}
@@ -77,36 +105,18 @@ impl HidDevice for Nitrokey {
return Err(());
}
- const PREFIX_LEN: usize = 7;
- const SUFFIX_LEN: usize = 4;
- const PREFIX_END: usize = PREFIX_LEN;
- const SUFFIX_START: usize = REPORT_LEN - SUFFIX_LEN;
- let mut buf = [0; COMMAND_LEN];
-
- let device_status = DeviceStatus::Ok;
- let command_id = self.buf[0];
- let command_status = if let Ok(command_id) = CommandId::try_from(command_id) {
- command_id.execute(&self.buf[1..60], &mut buf)
+ let mut response = Response::new(DeviceStatus::Ok, self.buf[0]);
+ response.last_crc = [self.buf[60], self.buf[61], self.buf[62], self.buf[63]];
+ response.command_status = if let Ok(command_id) = CommandId::try_from(response.command_id) {
+ command_id.execute(&self.buf[1..60], &mut response.data)
} else {
CommandStatus::UnknownCommand
};
+ // TODO: calculate actual CRC
+ response.crc = 1; // libnitrokey accepts any non-zero value
- let pre_data: [u8; PREFIX_LEN] = [
- device_status.into(), // device status
- command_id, // command_id
- self.buf[60],
- self.buf[61],
- self.buf[62],
- self.buf[63], // last_command_crc
- command_status.into(), // last_command_status
- ];
- let post_data: [u8; SUFFIX_LEN] = [
- 0x00, 0x00, 0x00, 0x01, // crc -- libnitrokey accepts any non-zero value
- ];
-
- self.buf[..PREFIX_END].copy_from_slice(&pre_data);
- self.buf[PREFIX_END..SUFFIX_START].copy_from_slice(&buf);
- self.buf[SUFFIX_START..].copy_from_slice(&post_data);
+ let len = ssmarshal::serialize(&mut self.buf, &response).map_err(|_| ())?;
+ assert!(len == REPORT_LEN);
Ok(&self.buf)
}