use crate::OsdpStatusReport;
use alloc::vec::Vec;
use serde::{Deserialize, Serialize};
use super::ConvertEndian;
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum OsdpLedColor {
#[default]
None,
Red,
Green,
Amber,
Blue,
Magenta,
Cyan,
}
impl From<u8> for OsdpLedColor {
fn from(value: u8) -> Self {
match value as libosdp_sys::osdp_led_color_e {
libosdp_sys::osdp_led_color_e_OSDP_LED_COLOR_NONE => OsdpLedColor::None,
libosdp_sys::osdp_led_color_e_OSDP_LED_COLOR_RED => OsdpLedColor::Red,
libosdp_sys::osdp_led_color_e_OSDP_LED_COLOR_GREEN => OsdpLedColor::Green,
libosdp_sys::osdp_led_color_e_OSDP_LED_COLOR_AMBER => OsdpLedColor::Amber,
libosdp_sys::osdp_led_color_e_OSDP_LED_COLOR_BLUE => OsdpLedColor::Blue,
libosdp_sys::osdp_led_color_e_OSDP_LED_COLOR_MAGENTA => OsdpLedColor::Magenta,
libosdp_sys::osdp_led_color_e_OSDP_LED_COLOR_CYAN => OsdpLedColor::Cyan,
_ => panic!("Invalid LED color code"),
}
}
}
impl From<OsdpLedColor> for u8 {
fn from(value: OsdpLedColor) -> Self {
match value {
OsdpLedColor::None => libosdp_sys::osdp_led_color_e_OSDP_LED_COLOR_NONE as u8,
OsdpLedColor::Red => libosdp_sys::osdp_led_color_e_OSDP_LED_COLOR_RED as u8,
OsdpLedColor::Green => libosdp_sys::osdp_led_color_e_OSDP_LED_COLOR_GREEN as u8,
OsdpLedColor::Amber => libosdp_sys::osdp_led_color_e_OSDP_LED_COLOR_AMBER as u8,
OsdpLedColor::Blue => libosdp_sys::osdp_led_color_e_OSDP_LED_COLOR_BLUE as u8,
OsdpLedColor::Magenta => libosdp_sys::osdp_led_color_e_OSDP_LED_COLOR_MAGENTA as u8,
OsdpLedColor::Cyan => libosdp_sys::osdp_led_color_e_OSDP_LED_COLOR_CYAN as u8,
}
}
}
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct OsdpLedParams {
pub control_code: u8,
pub on_count: u8,
pub off_count: u8,
pub on_color: OsdpLedColor,
pub off_color: OsdpLedColor,
pub timer_count: u16,
}
impl From<libosdp_sys::osdp_cmd_led_params> for OsdpLedParams {
fn from(value: libosdp_sys::osdp_cmd_led_params) -> Self {
OsdpLedParams {
control_code: value.control_code,
on_count: value.on_count,
off_count: value.off_count,
on_color: value.on_color.into(),
off_color: value.off_color.into(),
timer_count: value.timer_count,
}
}
}
impl From<OsdpLedParams> for libosdp_sys::osdp_cmd_led_params {
fn from(value: OsdpLedParams) -> Self {
libosdp_sys::osdp_cmd_led_params {
control_code: value.control_code,
on_count: value.on_count,
off_count: value.off_count,
on_color: value.on_color.into(),
off_color: value.off_color.into(),
timer_count: value.timer_count,
}
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct OsdpCommandLed {
pub reader: u8,
pub led_number: u8,
pub temporary: OsdpLedParams,
pub permanent: OsdpLedParams,
}
impl From<libosdp_sys::osdp_cmd_led> for OsdpCommandLed {
fn from(value: libosdp_sys::osdp_cmd_led) -> Self {
OsdpCommandLed {
reader: value.reader,
led_number: value.led_number,
temporary: value.temporary.into(),
permanent: value.permanent.into(),
}
}
}
impl From<OsdpCommandLed> for libosdp_sys::osdp_cmd_led {
fn from(value: OsdpCommandLed) -> Self {
libosdp_sys::osdp_cmd_led {
reader: value.reader,
led_number: value.led_number,
temporary: value.temporary.into(),
permanent: value.permanent.into(),
}
}
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct OsdpCommandBuzzer {
pub reader: u8,
pub control_code: u8,
pub on_count: u8,
pub off_count: u8,
pub rep_count: u8,
}
impl From<libosdp_sys::osdp_cmd_buzzer> for OsdpCommandBuzzer {
fn from(value: libosdp_sys::osdp_cmd_buzzer) -> Self {
OsdpCommandBuzzer {
reader: value.reader,
control_code: value.control_code,
on_count: value.on_count,
off_count: value.off_count,
rep_count: value.rep_count,
}
}
}
impl From<OsdpCommandBuzzer> for libosdp_sys::osdp_cmd_buzzer {
fn from(value: OsdpCommandBuzzer) -> Self {
libosdp_sys::osdp_cmd_buzzer {
reader: value.reader,
control_code: value.control_code,
on_count: value.on_count,
off_count: value.off_count,
rep_count: value.rep_count,
}
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct OsdpCommandText {
pub reader: u8,
pub control_code: u8,
pub temp_time: u8,
pub offset_row: u8,
pub offset_col: u8,
pub data: Vec<u8>,
}
impl From<libosdp_sys::osdp_cmd_text> for OsdpCommandText {
fn from(value: libosdp_sys::osdp_cmd_text) -> Self {
let n = value.length as usize;
let data = value.data[0..n].to_vec();
OsdpCommandText {
reader: value.reader,
control_code: value.control_code,
temp_time: value.temp_time,
offset_row: value.offset_row,
offset_col: value.offset_col,
data,
}
}
}
impl From<OsdpCommandText> for libosdp_sys::osdp_cmd_text {
fn from(value: OsdpCommandText) -> Self {
let mut data = [0; libosdp_sys::OSDP_CMD_TEXT_MAX_LEN as usize];
data[..value.data.len()].copy_from_slice(&value.data[..]);
libosdp_sys::osdp_cmd_text {
reader: value.reader,
control_code: value.control_code,
temp_time: value.temp_time,
offset_row: value.offset_row,
offset_col: value.offset_col,
length: value.data.len() as u8,
data,
}
}
}
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct OsdpCommandOutput {
pub output_no: u8,
pub control_code: u8,
pub timer_count: u16,
}
impl From<libosdp_sys::osdp_cmd_output> for OsdpCommandOutput {
fn from(value: libosdp_sys::osdp_cmd_output) -> Self {
OsdpCommandOutput {
output_no: value.output_no,
control_code: value.control_code,
timer_count: value.timer_count,
}
}
}
impl From<OsdpCommandOutput> for libosdp_sys::osdp_cmd_output {
fn from(value: OsdpCommandOutput) -> Self {
libosdp_sys::osdp_cmd_output {
output_no: value.output_no,
control_code: value.control_code,
timer_count: value.timer_count,
}
}
}
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct OsdpComSet {
pub address: u8,
pub baud_rate: u32,
}
impl From<libosdp_sys::osdp_cmd_comset> for OsdpComSet {
fn from(value: libosdp_sys::osdp_cmd_comset) -> Self {
OsdpComSet {
address: value.address,
baud_rate: value.baud_rate,
}
}
}
impl From<OsdpComSet> for libosdp_sys::osdp_cmd_comset {
fn from(value: OsdpComSet) -> Self {
libosdp_sys::osdp_cmd_comset {
address: value.address,
baud_rate: value.baud_rate,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct OsdpCommandKeyset {
key_type: u8,
pub data: Vec<u8>,
}
impl OsdpCommandKeyset {
pub fn new_scbk(key: [u8; 16]) -> Self {
let data = key.to_vec();
Self { key_type: 1, data }
}
}
impl From<libosdp_sys::osdp_cmd_keyset> for OsdpCommandKeyset {
fn from(value: libosdp_sys::osdp_cmd_keyset) -> Self {
let n = value.length as usize;
let data = value.data[0..n].to_vec();
OsdpCommandKeyset {
key_type: value.type_,
data,
}
}
}
impl From<OsdpCommandKeyset> for libosdp_sys::osdp_cmd_keyset {
fn from(value: OsdpCommandKeyset) -> Self {
let mut data = [0; libosdp_sys::OSDP_CMD_KEYSET_KEY_MAX_LEN as usize];
data[..value.data.len()].copy_from_slice(&value.data[..]);
libosdp_sys::osdp_cmd_keyset {
type_: value.key_type,
length: value.data.len() as u8,
data,
}
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct OsdpCommandMfg {
pub vendor_code: (u8, u8, u8),
pub data: Vec<u8>,
}
impl From<libosdp_sys::osdp_cmd_mfg> for OsdpCommandMfg {
fn from(value: libosdp_sys::osdp_cmd_mfg) -> Self {
let n = value.length as usize;
let data = value.data[0..n].to_vec();
let bytes = value.vendor_code.to_le_bytes();
let vendor_code: (u8, u8, u8) = (bytes[0], bytes[1], bytes[2]);
OsdpCommandMfg {
vendor_code,
data,
}
}
}
impl From<OsdpCommandMfg> for libosdp_sys::osdp_cmd_mfg {
fn from(value: OsdpCommandMfg) -> Self {
let mut data = [0; libosdp_sys::OSDP_CMD_MFG_MAX_DATALEN as usize];
data[..value.data.len()].copy_from_slice(&value.data[..]);
libosdp_sys::osdp_cmd_mfg {
vendor_code: value.vendor_code.as_le(),
length: value.data.len() as u8,
data,
}
}
}
pub const OSDP_CMD_FILE_TX_FLAG_CANCEL: u32 = 1 << 31;
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct OsdpCommandFileTx {
pub id: i32,
pub flags: u32,
}
impl From<libosdp_sys::osdp_cmd_file_tx> for OsdpCommandFileTx {
fn from(value: libosdp_sys::osdp_cmd_file_tx) -> Self {
OsdpCommandFileTx {
id: value.id,
flags: value.flags,
}
}
}
impl From<OsdpCommandFileTx> for libosdp_sys::osdp_cmd_file_tx {
fn from(value: OsdpCommandFileTx) -> Self {
libosdp_sys::osdp_cmd_file_tx {
id: value.id,
flags: value.flags,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum OsdpCommand {
Led(OsdpCommandLed),
Buzzer(OsdpCommandBuzzer),
Text(OsdpCommandText),
Output(OsdpCommandOutput),
ComSet(OsdpComSet),
ComSetDone(OsdpComSet),
KeySet(OsdpCommandKeyset),
Mfg(OsdpCommandMfg),
FileTx(OsdpCommandFileTx),
Status(OsdpStatusReport),
}
impl From<OsdpCommand> for libosdp_sys::osdp_cmd {
fn from(value: OsdpCommand) -> Self {
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() },
},
}
}
}
impl From<libosdp_sys::osdp_cmd> for OsdpCommand {
fn from(value: libosdp_sys::osdp_cmd) -> Self {
match value.id {
libosdp_sys::osdp_cmd_e_OSDP_CMD_LED => {
OsdpCommand::Led(unsafe { value.__bindgen_anon_1.led.into() })
}
libosdp_sys::osdp_cmd_e_OSDP_CMD_BUZZER => {
OsdpCommand::Buzzer(unsafe { value.__bindgen_anon_1.buzzer.into() })
}
libosdp_sys::osdp_cmd_e_OSDP_CMD_TEXT => {
OsdpCommand::Text(unsafe { value.__bindgen_anon_1.text.into() })
}
libosdp_sys::osdp_cmd_e_OSDP_CMD_OUTPUT => {
OsdpCommand::Output(unsafe { value.__bindgen_anon_1.output.into() })
}
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() })
}
libosdp_sys::osdp_cmd_e_OSDP_CMD_MFG => {
OsdpCommand::Mfg(unsafe { value.__bindgen_anon_1.mfg.into() })
}
libosdp_sys::osdp_cmd_e_OSDP_CMD_FILE_TX => {
OsdpCommand::FileTx(unsafe { value.__bindgen_anon_1.file_tx.into() })
}
libosdp_sys::osdp_cmd_e_OSDP_CMD_STATUS => {
OsdpCommand::Status(unsafe { value.__bindgen_anon_1.status.into() })
}
_ => panic!("Unknown event"),
}
}
}
#[cfg(test)]
mod tests {
use crate::OsdpCommandMfg;
use libosdp_sys::osdp_cmd_mfg;
#[test]
fn test_command_mfg() {
let cmd = OsdpCommandMfg {
vendor_code: (0x05, 0x07, 0x09),
data: vec![0x55, 0xAA],
};
let cmd_struct: osdp_cmd_mfg = cmd.clone().into();
assert_eq!(cmd_struct.vendor_code, 0x90705);
assert_eq!(cmd_struct.length, 2);
assert_eq!(cmd_struct.data[0], 0x55);
assert_eq!(cmd_struct.data[1], 0xAA);
assert_eq!(cmd, cmd_struct.into());
}
}