osdp/lib.rs
1//! Pure-Rust, `no_std`-friendly implementation of the SIA OSDP v2.2 protocol.
2//!
3//! # Crate features
4//!
5//! - `std` *(default)*: enables [`alloc`], plus desktop convenience.
6//! - `alloc` *(default via `std`)*: enables [`alloc::vec::Vec`]-based codec paths.
7//! - `secure-channel` *(default)*: enables Annex D (AES-128, MAC, encryption).
8//! - `embedded-io` / `embedded-io-async`: transport adapters.
9//! - `defmt`: structured logging on embedded targets.
10//!
11//! # Layering
12//!
13//! - [`packet`] — wire framing (SOM, header, SCB, MAC, trailer)
14//! - [`command`] / [`reply`] — typed messages
15//! - [`multipart`] — RFC §5.10 multi-part assembly / disassembly
16//! - [`secure`] — Annex D secure channel
17//! - [`transport`] — byte-stream abstraction
18//! - [`driver`] — ACU and PD state machines
19//! - [`caps`] — Annex B function codes
20//!
21//! # Specification cross-references
22//!
23//! All spec citations refer to *SIA OSDP v2.2* (©2020 Security Industry
24//! Association). Where an item maps directly onto a spec section it is noted
25//! in the docs as `# Spec: §X.Y`.
26
27#![cfg_attr(not(feature = "std"), no_std)]
28#![cfg_attr(docsrs, feature(doc_cfg))]
29#![deny(missing_docs)]
30#![deny(unsafe_code)]
31
32#[cfg(feature = "alloc")]
33extern crate alloc;
34
35pub mod caps;
36pub mod clock;
37pub mod error;
38pub mod packet;
39pub mod transport;
40
41#[cfg(feature = "alloc")]
42#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
43pub mod command;
44#[cfg(feature = "alloc")]
45#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
46pub mod multipart;
47#[cfg(feature = "alloc")]
48#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
49pub mod reply;
50
51#[cfg(all(feature = "alloc", feature = "secure-channel"))]
52#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", feature = "secure-channel"))))]
53pub mod secure;
54
55#[cfg(feature = "alloc")]
56#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
57pub mod driver;
58
59pub use error::{Error, Result};
60pub use packet::{Address, ControlByte, ParsedPacket, Sqn, Trailer};
61
62#[cfg(feature = "alloc")]
63pub use packet::Packet;
64
65/// Start of message marker — begins every OSDP packet header.
66///
67/// # Spec: §5.9
68pub const SOM: u8 = 0x53;
69
70/// Broadcast address.
71///
72/// # Spec: §5.4
73///
74/// Address `0x7F` is reserved as a special "BROADCAST" address that each PD
75/// will accept and respond to. The reply uses `0x7F | 0x80 = 0xFF` in its
76/// address field.
77pub const BROADCAST_ADDR: u8 = 0x7F;
78
79/// Largest legal PD unicast address.
80///
81/// # Spec: §5.4
82pub const MAX_PD_ADDR: u8 = 0x7E;
83
84/// Reply flag set in [`Address`] when sent from PD to ACU.
85///
86/// # Spec: §5.9, Table 1
87pub const REPLY_FLAG: u8 = 0x80;
88
89/// Minimum receive-buffer size every PD must support.
90///
91/// # Spec: §5.6
92pub const MIN_RX_SIZE: usize = 128;
93
94/// Maximum packet length that any device must tolerate on the wire (even if
95/// addressed elsewhere).
96///
97/// # Spec: §5.6
98pub const MAX_BUS_PACKET: usize = 1440;
99
100/// Default ACU reply-delay budget.
101///
102/// # Spec: §5.7
103pub const REPLY_DELAY_MS: u32 = 200;
104
105/// Off-line declaration threshold.
106///
107/// # Spec: §5.7
108pub const OFFLINE_THRESHOLD_MS: u32 = 8_000;