Skip to main content

osdp/reply/
mfg.rs

1//! Manufacturer-specific replies.
2//!
3//! # Spec: §7.23–§7.25
4//!
5//! - `osdp_MFGSTATR` (`0x83`) — vendor status (OUI + payload).
6//! - `osdp_MFGERRR` (`0x84`) — vendor error (OUI + error code + payload).
7//! - `osdp_MFGREP` (`0x90`) — vendor reply (OUI + payload).
8
9use crate::error::Error;
10use alloc::vec::Vec;
11
12macro_rules! oui_plus_payload {
13    ($Ty:ident, $code:expr, $doc:literal) => {
14        #[doc = $doc]
15        #[derive(Debug, Clone, PartialEq, Eq)]
16        pub struct $Ty {
17            /// IEEE-assigned OUI.
18            pub oui: [u8; 3],
19            /// Vendor payload.
20            pub payload: Vec<u8>,
21        }
22
23        impl $Ty {
24            /// Encode.
25            pub fn encode(&self) -> Result<Vec<u8>, Error> {
26                let mut out = Vec::with_capacity(3 + self.payload.len());
27                out.extend_from_slice(&self.oui);
28                out.extend_from_slice(&self.payload);
29                Ok(out)
30            }
31
32            /// Decode.
33            pub fn decode(data: &[u8]) -> Result<Self, Error> {
34                if data.len() < 3 {
35                    return Err(Error::MalformedPayload {
36                        code: $code,
37                        reason: "manufacturer reply requires 3-byte OUI",
38                    });
39                }
40                let mut oui = [0u8; 3];
41                oui.copy_from_slice(&data[..3]);
42                Ok(Self {
43                    oui,
44                    payload: data[3..].to_vec(),
45                })
46            }
47        }
48    };
49}
50
51oui_plus_payload!(
52    MfgStatR,
53    0x83,
54    "`osdp_MFGSTATR` body — manufacturer status reply."
55);
56oui_plus_payload!(
57    MfgErrR,
58    0x84,
59    "`osdp_MFGERRR` body — manufacturer error reply."
60);
61oui_plus_payload!(MfgRep, 0x90, "`osdp_MFGREP` body — manufacturer reply.");