diff --git a/.gitmodules b/.gitmodules index 005fa46..d5ad99c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "vendor"] path = libosdp-sys/vendor - url = https://github.com/goToMain/libosdp - branch = master + url = https://github.com/rustylocker/libosdp + branch = fix-unused-warnings diff --git a/libosdp-sys/Cargo.toml b/libosdp-sys/Cargo.toml index ec3da74..fe3904a 100644 --- a/libosdp-sys/Cargo.toml +++ b/libosdp-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libosdp-sys" -version = "3.0.8" +version = "3.1.0" edition = "2021" authors = ["Siddharth Chandrasekaran "] description = "Sys crate for https://github.com/goToMain/libosdp" diff --git a/libosdp-sys/build.rs b/libosdp-sys/build.rs index 4d64a83..9bcf661 100644 --- a/libosdp-sys/build.rs +++ b/libosdp-sys/build.rs @@ -130,6 +130,7 @@ fn main() -> Result<()> { } let source_files = vec![ + "vendor/utils/src/crc16.c", "vendor/utils/src/list.c", "vendor/utils/src/queue.c", "vendor/utils/src/slab.c", diff --git a/libosdp-sys/vendor b/libosdp-sys/vendor index 8c334ad..279cf82 160000 --- a/libosdp-sys/vendor +++ b/libosdp-sys/vendor @@ -1 +1 @@ -Subproject commit 8c334ade353e905712c46e7522fca512b0b33a59 +Subproject commit 279cf82367253259aa6c81edc015b37a27f6e613 diff --git a/libosdp/Cargo.toml b/libosdp/Cargo.toml index 11edbbc..d97d848 100644 --- a/libosdp/Cargo.toml +++ b/libosdp/Cargo.toml @@ -1,7 +1,7 @@ [package] edition = "2021" name = "libosdp" -version = "0.1.9" +version = "0.1.10" authors = ["Siddharth Chandrasekaran "] description = "Library implementation of IEC 60839-11-5 OSDP (Open Supervised Device Protocol)" documentation = "https://docs.rs/libosdp" @@ -15,9 +15,10 @@ categories = ["development-tools", "embedded"] [dependencies] bitflags = "2.4.0" embedded-io = { version = "0.6.1", features = ["alloc"] } -libosdp-sys = "3.0.8" +libosdp-sys = { version = "3.1.0", path = "../libosdp-sys" } log = { version = "0.4.20", optional = true } serde = { version = "1.0.192", features = ["derive", "alloc"], default-features = false } +serde_arrays = "0.2.0" thiserror = { version = "1.0.50", optional = true } defmt = { version = "0.3", optional = true, features = ["alloc"] } itoa = "1.0.11" diff --git a/libosdp/examples/cp.rs b/libosdp/examples/cp.rs index 3f00c32..e479fd3 100644 --- a/libosdp/examples/cp.rs +++ b/libosdp/examples/cp.rs @@ -35,6 +35,11 @@ impl Channel for OsdpChannel { // TODO: flush device Ok(()) } + + fn close(&mut self) -> Result<(), ChannelError> { + // TODO: close device + Ok(()) + } } fn main() -> Result<(), OsdpError> { diff --git a/libosdp/examples/pd.rs b/libosdp/examples/pd.rs index 0310cf5..8cd9824 100644 --- a/libosdp/examples/pd.rs +++ b/libosdp/examples/pd.rs @@ -37,6 +37,11 @@ impl Channel for OsdpChannel { // TODO: flush device Ok(()) } + + fn close(&mut self) -> Result<(), ChannelError> { + // TODO: close device + Ok(()) + } } fn main() -> Result<(), OsdpError> { diff --git a/libosdp/src/channel.rs b/libosdp/src/channel.rs index 7c87f1b..35ac78e 100644 --- a/libosdp/src/channel.rs +++ b/libosdp/src/channel.rs @@ -69,6 +69,9 @@ pub trait Channel: Send { /// Flush this output stream, ensuring that all intermediately buffered /// contents reach their destination. fn flush(&mut self) -> Result<(), ChannelError>; + + /// Close this output stream + fn close(&mut self) -> Result<(), ChannelError>; } impl core::fmt::Debug for dyn Channel { @@ -112,6 +115,12 @@ unsafe extern "C" fn raw_flush(data: *mut c_void) { let _ = channel.as_mut().flush(); } +unsafe extern "C" fn raw_close(data: *mut c_void) { + let channel: *mut Box = data as *mut _; + let channel = channel.as_mut().unwrap(); + let _ = channel.as_mut().close(); +} + impl From> for libosdp_sys::osdp_channel { fn from(val: Box) -> Self { let id = val.get_id(); @@ -122,6 +131,7 @@ impl From> for libosdp_sys::osdp_channel { recv: Some(raw_read), send: Some(raw_write), flush: Some(raw_flush), + close: Some(raw_close), } } } diff --git a/libosdp/src/commands.rs b/libosdp/src/commands.rs index 2945fc5..35d7a24 100644 --- a/libosdp/src/commands.rs +++ b/libosdp/src/commands.rs @@ -156,7 +156,7 @@ impl From for OsdpCommandLed { fn from(value: libosdp_sys::osdp_cmd_led) -> Self { OsdpCommandLed { reader: value.reader, - led_number: value.reader, + led_number: value.led_number, temporary: value.temporary.into(), permanent: value.permanent.into(), } @@ -344,21 +344,11 @@ impl From for libosdp_sys::osdp_cmd_output { /// will expect the PD to be in this state moving forward. #[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)] pub struct OsdpComSet { - address: u8, - baud_rate: u32, -} - -impl OsdpComSet { - /// Create an instance of OsdpComSet command - /// - /// # Arguments - /// - /// * `address` - address to which this PD will respond after this command - /// * `baud_rate` - Serial communication speed; only acceptable values are, - /// 9600/19200/38400/57600/115200/230400 - pub fn new(address: u8, baud_rate: u32) -> Self { - Self { address, baud_rate } - } + /// Unit ID to which this PD will respond after the change takes effect. + pub address: u8, + /// Baud rate. + /// Valid values: 9600, 19200, 38400, 115200, 230400. + pub baud_rate: u32, } impl From for OsdpComSet { @@ -428,9 +418,6 @@ pub struct OsdpCommandMfg { /// 3-byte IEEE assigned OUI used as vendor code pub vendor_code: (u8, u8, u8), - /// 1-byte manufacturer defined command ID - pub command: u8, - /// Command data (if any) pub data: Vec, } @@ -443,7 +430,6 @@ impl From for OsdpCommandMfg { let vendor_code: (u8, u8, u8) = (bytes[0], bytes[1], bytes[2]); OsdpCommandMfg { vendor_code, - command: value.command, data, } } @@ -455,31 +441,25 @@ impl From for libosdp_sys::osdp_cmd_mfg { data[..value.data.len()].copy_from_slice(&value.data[..]); libosdp_sys::osdp_cmd_mfg { vendor_code: value.vendor_code.as_le(), - command: value.command, length: value.data.len() as u8, data, } } } +/// File transfer command flag used to cancel ongoing transfers (not sent on OSDP channel). +pub const OSDP_CMD_FILE_TX_FLAG_CANCEL: u32 = 1 << 31; + /// Command to kick-off a file transfer to the PD. #[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)] pub struct OsdpCommandFileTx { - id: i32, - flags: u32, -} - -impl OsdpCommandFileTx { - /// Create an instance of OsdpCommandFileTx. - /// - /// # Arguments - /// - /// * `id` - The ID of the file; these are pre-shared between the CP and PD - /// * `flags` - Reserved and set to zero by OSDP spec; bit-31 used by - /// libOSDP to cancel ongoing transfers (it is not sent on OSDP channel) - pub fn new(id: i32, flags: u32) -> Self { - Self { id, flags } - } + /// Pre-agreed file ID between CP and PD + pub id: i32, + /// Reserved and set to zero by OSDP spec. + /// Note that the upper bits are used by libosdp internally (IOW, not sent + /// over the OSDP bus). Currently the following flags are defined: + /// - OSDP_CMD_FILE_TX_FLAG_CANCEL + pub flags: u32, } impl From for OsdpCommandFileTx { @@ -517,11 +497,14 @@ pub enum OsdpCommand { /// Command to control digital output exposed by the PD Output(OsdpCommandOutput), - /// Command to set the communication parameters for the PD. The effects - /// of this command is expected to be be stored in PD’s non-volatile memory - /// as the CP will expect the PD to be in this state moving forward + /// Command to request setting the communication parameters for the PD. ComSet(OsdpComSet), + /// Set communication parameter completed. + /// The effects of this command is expected to be be stored in PD’s non-volatile + /// memory as the CP will expect the PD to be in this state moving forward + ComSetDone(OsdpComSet), + /// Command to set secure channel keys to the PD KeySet(OsdpCommandKeyset), @@ -540,46 +523,60 @@ impl From for libosdp_sys::osdp_cmd { match value { OsdpCommand::Led(c) => libosdp_sys::osdp_cmd { id: libosdp_sys::osdp_cmd_e_OSDP_CMD_LED, + flags: 0, __bindgen_anon_1: libosdp_sys::osdp_cmd__bindgen_ty_1 { led: c.clone().into(), }, }, OsdpCommand::Buzzer(c) => libosdp_sys::osdp_cmd { id: libosdp_sys::osdp_cmd_e_OSDP_CMD_BUZZER, + flags: 0, __bindgen_anon_1: libosdp_sys::osdp_cmd__bindgen_ty_1 { buzzer: c.into() }, }, OsdpCommand::Text(c) => libosdp_sys::osdp_cmd { id: libosdp_sys::osdp_cmd_e_OSDP_CMD_TEXT, + flags: 0, __bindgen_anon_1: libosdp_sys::osdp_cmd__bindgen_ty_1 { text: c.clone().into(), }, }, OsdpCommand::Output(c) => libosdp_sys::osdp_cmd { id: libosdp_sys::osdp_cmd_e_OSDP_CMD_OUTPUT, + flags: 0, __bindgen_anon_1: libosdp_sys::osdp_cmd__bindgen_ty_1 { output: c.into() }, }, OsdpCommand::ComSet(c) => libosdp_sys::osdp_cmd { id: libosdp_sys::osdp_cmd_e_OSDP_CMD_COMSET, + flags: 0, + __bindgen_anon_1: libosdp_sys::osdp_cmd__bindgen_ty_1 { comset: c.into() }, + }, + OsdpCommand::ComSetDone(c) => libosdp_sys::osdp_cmd { + id: libosdp_sys::osdp_cmd_e_OSDP_CMD_COMSET_DONE, + flags: 0, __bindgen_anon_1: libosdp_sys::osdp_cmd__bindgen_ty_1 { comset: c.into() }, }, OsdpCommand::KeySet(c) => libosdp_sys::osdp_cmd { id: libosdp_sys::osdp_cmd_e_OSDP_CMD_KEYSET, + flags: 0, __bindgen_anon_1: libosdp_sys::osdp_cmd__bindgen_ty_1 { keyset: c.clone().into(), }, }, OsdpCommand::Mfg(c) => libosdp_sys::osdp_cmd { id: libosdp_sys::osdp_cmd_e_OSDP_CMD_MFG, + flags: 0, __bindgen_anon_1: libosdp_sys::osdp_cmd__bindgen_ty_1 { mfg: c.clone().into(), }, }, OsdpCommand::FileTx(c) => libosdp_sys::osdp_cmd { id: libosdp_sys::osdp_cmd_e_OSDP_CMD_FILE_TX, + flags: 0, __bindgen_anon_1: libosdp_sys::osdp_cmd__bindgen_ty_1 { file_tx: c.into() }, }, OsdpCommand::Status(c) => libosdp_sys::osdp_cmd { id: libosdp_sys::osdp_cmd_e_OSDP_CMD_STATUS, + flags: 0, __bindgen_anon_1: libosdp_sys::osdp_cmd__bindgen_ty_1 { status: c.into() }, }, } @@ -604,6 +601,9 @@ impl From for OsdpCommand { libosdp_sys::osdp_cmd_e_OSDP_CMD_COMSET => { OsdpCommand::ComSet(unsafe { value.__bindgen_anon_1.comset.into() }) } + libosdp_sys::osdp_cmd_e_OSDP_CMD_COMSET_DONE => { + OsdpCommand::ComSetDone(unsafe { value.__bindgen_anon_1.comset.into() }) + } libosdp_sys::osdp_cmd_e_OSDP_CMD_KEYSET => { OsdpCommand::KeySet(unsafe { value.__bindgen_anon_1.keyset.into() }) } @@ -630,13 +630,11 @@ mod tests { fn test_command_mfg() { let cmd = OsdpCommandMfg { vendor_code: (0x05, 0x07, 0x09), - command: 0x47, data: vec![0x55, 0xAA], }; let cmd_struct: osdp_cmd_mfg = cmd.clone().into(); assert_eq!(cmd_struct.vendor_code, 0x90705); - assert_eq!(cmd_struct.command, 0x47); assert_eq!(cmd_struct.length, 2); assert_eq!(cmd_struct.data[0], 0x55); assert_eq!(cmd_struct.data[1], 0xAA); diff --git a/libosdp/src/events.rs b/libosdp/src/events.rs index 3b30b2b..71db220 100644 --- a/libosdp/src/events.rs +++ b/libosdp/src/events.rs @@ -25,14 +25,11 @@ use defmt::panic; #[cfg_attr(feature = "defmt-03", derive(defmt::Format))] pub enum OsdpCardFormats { /// Card format is not specified + #[default] Unspecified, /// Wiegand format Wiegand, - - /// Ascii format - #[default] - Ascii, } impl From for OsdpCardFormats { @@ -44,7 +41,6 @@ impl From for OsdpCardFormats { libosdp_sys::osdp_event_cardread_format_e_OSDP_CARD_FMT_RAW_WIEGAND => { OsdpCardFormats::Wiegand } - libosdp_sys::osdp_event_cardread_format_e_OSDP_CARD_FMT_ASCII => OsdpCardFormats::Ascii, _ => panic!("Unknown osdp card format"), } } @@ -59,7 +55,6 @@ impl From for libosdp_sys::osdp_event_cardread_format_e { OsdpCardFormats::Wiegand => { libosdp_sys::osdp_event_cardread_format_e_OSDP_CARD_FMT_RAW_WIEGAND } - OsdpCardFormats::Ascii => libosdp_sys::osdp_event_cardread_format_e_OSDP_CARD_FMT_ASCII, } } } @@ -96,13 +91,13 @@ pub struct OsdpEventCardRead { } impl OsdpEventCardRead { - /// Create an ASCII card read event for self and direction set to forward - pub fn new_ascii(data: Vec) -> Self { + /// Create an raw data card read event for self and direction set to forward + pub fn new_raw(data: Vec) -> Self { Self { reader_no: 0, - format: OsdpCardFormats::Ascii, + format: OsdpCardFormats::Unspecified, direction: false, - nr_bits: 0, + nr_bits: data.len() * 8, data, } } @@ -127,10 +122,7 @@ impl From for OsdpEventCardRead { let direction = value.direction == 1; let format = value.format.into(); let len = value.length as usize; - let (nr_bits, nr_bytes) = match format { - OsdpCardFormats::Ascii => (0, len), - _ => (len, len.div_ceil(8)), - }; + let (nr_bits, nr_bytes) = (len, len.div_ceil(8)); let data = value.data[0..nr_bytes].to_vec(); OsdpEventCardRead { reader_no: value.reader_no, @@ -145,10 +137,7 @@ impl From for OsdpEventCardRead { impl From for libosdp_sys::osdp_event_cardread { fn from(value: OsdpEventCardRead) -> Self { let mut data = [0; libosdp_sys::OSDP_EVENT_CARDREAD_MAX_DATALEN as usize]; - let length = match value.format { - OsdpCardFormats::Ascii => value.data.len() as i32, - _ => value.nr_bits as i32, - }; + let length = value.nr_bits as i32; data[..value.data.len()].copy_from_slice(&value.data[..]); libosdp_sys::osdp_event_cardread { reader_no: value.reader_no, @@ -213,9 +202,6 @@ pub struct OsdpEventMfgReply { /// 3-byte IEEE assigned OUI used as vendor code pub vendor_code: (u8, u8, u8), - /// 1-byte reply code - pub reply: u8, - /// Reply data (if any) pub data: Vec, } @@ -228,7 +214,6 @@ impl From for OsdpEventMfgReply { let vendor_code: (u8, u8, u8) = (bytes[0], bytes[1], bytes[2]); OsdpEventMfgReply { vendor_code, - reply: value.command, data, } } @@ -240,7 +225,6 @@ impl From for libosdp_sys::osdp_event_mfgrep { data[..value.data.len()].copy_from_slice(&value.data[..]); libosdp_sys::osdp_event_mfgrep { vendor_code: value.vendor_code.as_le(), - command: value.reply, length: value.data.len() as u8, data, } @@ -303,7 +287,7 @@ impl From for libosdp_sys::osdp_status_report_type { /// Event to describe various status changes on PD /// /// This event is used by the PD to indicate status such as input, output, -/// tamper, etc.,. up to a maximum of 32 status bits can be reported. The values +/// tamper, etc.,. up to a maximum of 64 status bits can be reported. The values /// of the least significant N bit of status are considered, where N is the /// number of items as described in the corresponding capability codes, /// - PdCapability::OutputControl @@ -311,29 +295,13 @@ impl From for libosdp_sys::osdp_status_report_type { #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] #[cfg_attr(feature = "defmt-03", derive(defmt::Format))] pub struct OsdpStatusReport { - type_: OsdpStatusReportType, - nr_entries: usize, - mask: u32, -} - -impl OsdpStatusReport { - /// Create an input event with given bit mask - pub fn new_input(nr_entries: usize, mask: u32) -> Self { - Self { - type_: OsdpStatusReportType::Input, - nr_entries, - mask, - } - } - - /// Create an output event with given bit mask - pub fn new_output(nr_entries: usize, mask: u32) -> Self { - Self { - type_: OsdpStatusReportType::Output, - nr_entries, - mask, - } - } + /// The kind of event to report see `enum osdp_event_status_type_e` + pub type_: OsdpStatusReportType, + /// Number of valid entries in `report` + pub nr_entries: usize, + /// Status report + #[serde(with = "serde_arrays")] + pub report: [u8; 64], } impl From for OsdpStatusReport { @@ -341,7 +309,7 @@ impl From for OsdpStatusReport { OsdpStatusReport { type_: value.type_.into(), nr_entries: value.nr_entries as usize, - mask: value.mask, + report: value.report, } } } @@ -351,7 +319,7 @@ impl From for libosdp_sys::osdp_status_report { libosdp_sys::osdp_status_report { type_: value.type_.into(), nr_entries: value.nr_entries as i32, - mask: value.mask, + report: value.report, } } } @@ -381,24 +349,28 @@ impl From for libosdp_sys::osdp_event { match value { OsdpEvent::CardRead(e) => libosdp_sys::osdp_event { type_: libosdp_sys::osdp_event_type_OSDP_EVENT_CARDREAD, + flags: 0, __bindgen_anon_1: libosdp_sys::osdp_event__bindgen_ty_1 { cardread: e.clone().into(), }, }, OsdpEvent::KeyPress(e) => libosdp_sys::osdp_event { type_: libosdp_sys::osdp_event_type_OSDP_EVENT_KEYPRESS, + flags: 0, __bindgen_anon_1: libosdp_sys::osdp_event__bindgen_ty_1 { keypress: e.clone().into(), }, }, OsdpEvent::MfgReply(e) => libosdp_sys::osdp_event { type_: libosdp_sys::osdp_event_type_OSDP_EVENT_MFGREP, + flags: 0, __bindgen_anon_1: libosdp_sys::osdp_event__bindgen_ty_1 { mfgrep: e.clone().into(), }, }, OsdpEvent::Status(e) => libosdp_sys::osdp_event { type_: libosdp_sys::osdp_event_type_OSDP_EVENT_STATUS, + flags: 0, __bindgen_anon_1: libosdp_sys::osdp_event__bindgen_ty_1 { status: e.into() }, }, } @@ -429,20 +401,20 @@ impl From for OsdpEvent { mod tests { use super::OsdpEventCardRead; use libosdp_sys::{ - osdp_event_cardread, osdp_event_cardread_format_e_OSDP_CARD_FMT_ASCII, + osdp_event_cardread, osdp_event_cardread_format_e_OSDP_CARD_FMT_RAW_UNSPECIFIED, osdp_event_cardread_format_e_OSDP_CARD_FMT_RAW_WIEGAND, }; #[test] fn test_event_cardread() { - let event = OsdpEventCardRead::new_ascii(vec![0x55, 0xAA]); + let event = OsdpEventCardRead::new_raw(vec![0x55, 0xAA]); let event_struct: osdp_event_cardread = event.clone().into(); - assert_eq!(event_struct.length, 2); + assert_eq!(event_struct.length, 2 * 8); assert_eq!(event_struct.direction, 0); assert_eq!( event_struct.format, - osdp_event_cardread_format_e_OSDP_CARD_FMT_ASCII + osdp_event_cardread_format_e_OSDP_CARD_FMT_RAW_UNSPECIFIED ); assert_eq!(event_struct.data[0], 0x55); assert_eq!(event_struct.data[1], 0xAA); diff --git a/libosdp/src/pd.rs b/libosdp/src/pd.rs index 8984d7b..cdffb9a 100644 --- a/libosdp/src/pd.rs +++ b/libosdp/src/pd.rs @@ -50,18 +50,23 @@ unsafe extern "C" fn log_handler( } } -extern "C" fn trampoline(data: *mut c_void, cmd: *mut libosdp_sys::osdp_cmd) -> i32 +extern "C" fn trampoline(data_ptr: *mut c_void, cmd_ptr: *mut libosdp_sys::osdp_cmd) -> i32 where - F: FnMut(OsdpCommand) -> i32, + F: FnMut(&mut OsdpCommand) -> i32, { - let cmd: OsdpCommand = unsafe { (*cmd).into() }; - let callback: &mut F = unsafe { &mut *(data as *mut F) }; - callback(cmd) + let mut cmd: OsdpCommand = unsafe { cmd_ptr.read().into() }; + let callback: &mut F = unsafe { &mut *(data_ptr as *mut F) }; + let res = callback(&mut cmd); + // TODO: Free data_ptr's box? + unsafe { + cmd_ptr.write(cmd.into()); + } + res } fn get_trampoline(_closure: &F) -> CommandCallback where - F: FnMut(OsdpCommand) -> i32, + F: FnMut(&mut OsdpCommand) -> i32, { trampoline:: } @@ -131,7 +136,7 @@ impl PeripheralDevice { /// CP. pub fn set_command_callback(&mut self, closure: F) where - F: FnMut(OsdpCommand) -> i32, + F: FnMut(&mut OsdpCommand) -> i32, { unsafe { let callback = get_trampoline(&closure); diff --git a/libosdp/src/pdcap.rs b/libosdp/src/pdcap.rs index d17adb0..0d0556a 100644 --- a/libosdp/src/pdcap.rs +++ b/libosdp/src/pdcap.rs @@ -135,6 +135,17 @@ pub enum PdCapability { /// This capability indicates the ability of the reader to handle biometric /// input. Biometrics(PdCapEntity), + + /// This capability indicates if the reader is capable of supporting + /// Secure Pin Entry (SPE) for smart cards + SecurePinEntry(PdCapEntity), + + /// This capability indicates the version of OSDP the PD supports + /// Compliance Levels: + /// 0 - Unspecified + /// 1 - IEC 60839-11-5 + /// 2 - SIA OSDP 2.2 + OsdpVersion(PdCapEntity), } #[rustfmt::skip] @@ -186,6 +197,12 @@ impl FromStr for PdCapability { "Biometrics" => { Ok(PdCapability::Biometrics(PdCapEntity::from_str(ent)?)) }, + "SecurePinEntry" => { + Ok(PdCapability::SecurePinEntry(PdCapEntity::from_str(ent)?)) + }, + "OsdpVersion" => { + Ok(PdCapability::OsdpVersion(PdCapEntity::from_str(ent)?)) + }, _ => Err(OsdpError::Parse(format!("PdCapability: {s}"))), } } else { @@ -244,6 +261,12 @@ impl From for PdCapability { libosdp_sys::osdp_pd_cap_function_code_e_OSDP_PD_CAP_BIOMETRICS => { PdCapability::Biometrics(e) } + libosdp_sys::osdp_pd_cap_function_code_e_OSDP_PD_CAP_SECURE_PIN_ENTRY => { + PdCapability::SecurePinEntry(e) + } + libosdp_sys::osdp_pd_cap_function_code_e_OSDP_PD_CAP_OSDP_VERSION => { + PdCapability::OsdpVersion(e) + } _ => panic!("Unknown function code"), } } @@ -295,6 +318,12 @@ impl From for u8 { PdCapability::Biometrics(_) => { libosdp_sys::osdp_pd_cap_function_code_e_OSDP_PD_CAP_BIOMETRICS as u8 } + PdCapability::SecurePinEntry(_) => { + libosdp_sys::osdp_pd_cap_function_code_e_OSDP_PD_CAP_SECURE_PIN_ENTRY as u8 + } + PdCapability::OsdpVersion(_) => { + libosdp_sys::osdp_pd_cap_function_code_e_OSDP_PD_CAP_OSDP_VERSION as u8 + } } } } @@ -373,6 +402,16 @@ impl From for libosdp_sys::osdp_pd_cap { compliance_level: e.compliance, num_items: e.num_items, }, + PdCapability::SecurePinEntry(e) => libosdp_sys::osdp_pd_cap { + function_code, + compliance_level: e.compliance, + num_items: e.num_items, + }, + PdCapability::OsdpVersion(e) => libosdp_sys::osdp_pd_cap { + function_code, + compliance_level: e.compliance, + num_items: e.num_items, + }, } } } diff --git a/libosdp/src/pdid.rs b/libosdp/src/pdid.rs index cac2342..997ccd0 100644 --- a/libosdp/src/pdid.rs +++ b/libosdp/src/pdid.rs @@ -9,9 +9,9 @@ use super::ConvertEndian; #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] pub struct PdId { /// 1-Byte Manufacturer's version number - pub version: i32, + pub version: u8, /// 1-byte Manufacturer's model number - pub model: i32, + pub model: u8, /// 3-bytes IEEE assigned OUI pub vendor_code: (u8, u8, u8), /// 4-byte serial number for the PD @@ -43,8 +43,8 @@ impl From for PdId { let bytes = value.firmware_version.to_le_bytes(); let firmware_version = (bytes[0], bytes[1], bytes[2]); Self { - version: value.version, - model: value.model, + version: u8::try_from(value.version).unwrap_or(0), + model: u8::try_from(value.model).unwrap_or(0), vendor_code, serial_number: value.serial_number.to_be_bytes(), firmware_version, @@ -81,8 +81,8 @@ impl ConvertEndian for (u8, u8, u8) { impl From for libosdp_sys::osdp_pd_id { fn from(value: PdId) -> Self { libosdp_sys::osdp_pd_id { - version: value.version, - model: value.model, + version: value.version as i32, + model: value.model as i32, vendor_code: value.vendor_code.as_le(), serial_number: value.serial_number.as_le(), firmware_version: value.firmware_version.as_le(), diff --git a/libosdp/tests/commands.rs b/libosdp/tests/commands.rs index cb2489a..78a9c65 100644 --- a/libosdp/tests/commands.rs +++ b/libosdp/tests/commands.rs @@ -59,7 +59,7 @@ fn test_commands() -> Result<()> { let cmd_rx = pd.receiver.recv().unwrap(); assert_eq!(cmd_rx, command, "Buzzer command check failed"); - let event = OsdpEvent::CardRead(OsdpEventCardRead::new_ascii(vec![0x55, 0xAA])); + let event = OsdpEvent::CardRead(OsdpEventCardRead::new_raw(vec![0x55, 0xAA])); notify_event(pd.get_device(), event.clone())?; assert_eq!( cp.receiver.recv().unwrap(), diff --git a/libosdp/tests/common/device.rs b/libosdp/tests/common/device.rs index f069d6e..7bda55a 100644 --- a/libosdp/tests/common/device.rs +++ b/libosdp/tests/common/device.rs @@ -94,7 +94,7 @@ impl PdDevice { let mut pd = PeripheralDevice::new(pd_info, bus)?; let (cmd_tx, cmd_rx) = std::sync::mpsc::channel::(); pd.set_command_callback(|command| { - cmd_tx.send(command).unwrap(); + cmd_tx.send(command.clone()).unwrap(); 0 }); @@ -106,7 +106,7 @@ impl PdDevice { let dev = dev_clone; let sender = cmd_tx; dev.lock().unwrap().set_command_callback(|command| { - sender.send(command).expect("PD command send"); + sender.send(command.clone()).expect("PD command send"); 0 }); loop { diff --git a/libosdp/tests/common/memory_channel.rs b/libosdp/tests/common/memory_channel.rs index 60e6d6d..e0e4149 100644 --- a/libosdp/tests/common/memory_channel.rs +++ b/libosdp/tests/common/memory_channel.rs @@ -64,4 +64,8 @@ impl libosdp::Channel for MemoryChannel { fn flush(&mut self) -> Result<(), libosdp::ChannelError> { Ok(()) } + + fn close(&mut self) -> Result<(), ChannelError> { + Ok(()) + } } diff --git a/libosdp/tests/common/threadbus.rs b/libosdp/tests/common/threadbus.rs index 77ca78b..58374e4 100644 --- a/libosdp/tests/common/threadbus.rs +++ b/libosdp/tests/common/threadbus.rs @@ -94,4 +94,8 @@ impl libosdp::Channel for ThreadBus { fn flush(&mut self) -> Result<(), libosdp::ChannelError> { Ok(()) } + + fn close(&mut self) -> Result<(), libosdp::ChannelError> { + Ok(()) + } } diff --git a/libosdp/tests/file_transfer.rs b/libosdp/tests/file_transfer.rs index e0aea66..312aa9d 100644 --- a/libosdp/tests/file_transfer.rs +++ b/libosdp/tests/file_transfer.rs @@ -143,7 +143,7 @@ fn test_file_transfer() -> Result<()> { pd.get_device().register_file_ops(Box::new(fm))?; - let command = OsdpCommand::FileTx(OsdpCommandFileTx::new(1, 0)); + let command = OsdpCommand::FileTx(OsdpCommandFileTx {id: 1, flags: 0}); cp.get_device().send_command(0, command.clone())?; assert_eq!( diff --git a/osdpctl/src/config.rs b/osdpctl/src/config.rs index 895f3ee..1c3906d 100644 --- a/osdpctl/src/config.rs +++ b/osdpctl/src/config.rs @@ -180,8 +180,8 @@ impl PdConfig { .unwrap() .unwrap() as u32; let pd_id = PdId { - version: config.getuint("pd_id", "version").unwrap().unwrap() as i32, - model: config.getuint("pd_id", "model").unwrap().unwrap() as i32, + version: config.getuint("pd_id", "version").unwrap().unwrap() as u8, + model: config.getuint("pd_id", "model").unwrap().unwrap() as u8, vendor_code: ( vendor_code as u8, (vendor_code >> 8) as u8, diff --git a/osdpctl/src/pd.rs b/osdpctl/src/pd.rs index 3474ced..d1082f3 100644 --- a/osdpctl/src/pd.rs +++ b/osdpctl/src/pd.rs @@ -48,6 +48,9 @@ pub fn main(mut dev: PdConfig, daemonize: bool) -> Result<()> { OsdpCommand::ComSet(c) => { log::info!("Command: {:?}", c); } + OsdpCommand::ComSetDone(c) => { + log::info!("Command: {:?}", c); + } OsdpCommand::KeySet(c) => { log::info!("Command: {:?}", c); let mut key = [0; 16]; diff --git a/osdpctl/src/unix_channel.rs b/osdpctl/src/unix_channel.rs index 5983702..fc67cef 100644 --- a/osdpctl/src/unix_channel.rs +++ b/osdpctl/src/unix_channel.rs @@ -86,4 +86,8 @@ impl libosdp::Channel for UnixChannel { fn flush(&mut self) -> std::prelude::v1::Result<(), libosdp::ChannelError> { self.stream.flush().map_err(ChannelError::from) } + + fn close(&mut self) -> std::prelude::v1::Result<(), libosdp::ChannelError> { + Ok(()) + } }