Skip to main content

osdp/command/
buzzer.rs

1//! `osdp_BUZ` (`0x6A`) — reader buzzer control.
2//!
3//! # Spec: §6.10–§6.11, Table 19
4//!
5//! Body is a 5-byte record per buzzer.
6
7use crate::error::Error;
8use alloc::vec::Vec;
9
10/// Buzzer tone code (Table 19).
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12#[repr(u8)]
13#[allow(missing_docs)]
14pub enum BuzzerTone {
15    /// Deprecated; treated as Off by modern firmware.
16    None = 0x00,
17    Off = 0x01,
18    Default = 0x02,
19}
20
21impl BuzzerTone {
22    /// Parse from byte (returns Off for unrecognized).
23    pub const fn from_byte(b: u8) -> Self {
24        match b {
25            0x00 => Self::None,
26            0x01 => Self::Off,
27            _ => Self::Default,
28        }
29    }
30
31    /// Raw byte.
32    pub const fn as_byte(self) -> u8 {
33        self as u8
34    }
35}
36
37/// `osdp_BUZ` body.
38#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub struct BuzzerControl {
40    /// Reader number.
41    pub reader: u8,
42    /// Tone code.
43    pub tone: BuzzerTone,
44    /// On time, in 100 ms units.
45    pub on_time: u8,
46    /// Off time, in 100 ms units.
47    pub off_time: u8,
48    /// Number of repetitions.
49    pub count: u8,
50}
51
52impl BuzzerControl {
53    /// Encode.
54    pub fn encode(&self) -> Result<Vec<u8>, Error> {
55        Ok(alloc::vec![
56            self.reader,
57            self.tone.as_byte(),
58            self.on_time,
59            self.off_time,
60            self.count,
61        ])
62    }
63
64    /// Decode.
65    pub fn decode(data: &[u8]) -> Result<Self, Error> {
66        if data.len() != 5 {
67            return Err(Error::MalformedPayload {
68                code: 0x6A,
69                reason: "BUZ requires 5 bytes",
70            });
71        }
72        Ok(Self {
73            reader: data[0],
74            tone: BuzzerTone::from_byte(data[1]),
75            on_time: data[2],
76            off_time: data[3],
77            count: data[4],
78        })
79    }
80}