sma_proto/
error.rs

1/******************************************************************************\
2    sma-proto - A SMA Speedwire protocol library
3    Copyright (C) 2024 Max Maisel
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU Affero General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU Affero General Public License for more details.
14
15    You should have received a copy of the GNU Affero General Public License
16    along with this program.  If not, see <https://www.gnu.org/licenses/>.
17\******************************************************************************/
18#[cfg(not(feature = "std"))]
19use core::{fmt::Debug, prelude::rust_2021::derive};
20
21use byteorder_cursor::BufferTooSmall;
22
23/// Errors returned from SMA speedwire protocol processing.
24#[derive(Clone, Debug)]
25pub enum Error {
26    /// The provided buffer is too small.
27    BufferTooSmall(BufferTooSmall),
28    /// The provided buffer contained unexpected trailing bytes and
29    /// was not completely deserialized.
30    BufferNotConsumed { trailing: usize },
31    /// The processed packet starts with an invalid SMA FOURCC value.
32    InvalidFourCC { fourcc: u32 },
33    /// The packet header length is incorrect.
34    InvalidStartTagLen { len: u16 },
35    /// The start tag value in the common packet header is invalid.
36    InvalidStartTag { tag: u16 },
37    /// The group value in the common packet header is invalid.
38    InvalidGroup { group: u32 },
39    /// The protocol version as indicated in the common packet header
40    /// is unsupported.
41    UnsupportedVersion { version: u16 },
42    /// The sub-protocol type as indicated in the common packet header
43    /// is unsupported.
44    UnsupportedProtocol { protocol: u16 },
45    /// The padding bytes are not all zero.
46    InvalidPadding { padding: u32 },
47    /// The OBIS ID encountered is unsupported.
48    UnsupportedObisId { id: u32 },
49    /// The wordcount field in the inverter sub-protocol header data length
50    /// is invalid.
51    InvalidWordcount { wordcount: u8 },
52    /// The class field of this message has an unsupported value.
53    UnsupportedCommandClass { class: u8 },
54    /// The opcode of this message has an unsupported value.
55    UnsupportedOpcode { opcode: u32 },
56    /// The payload of a packet exceeds the maximum supported length.
57    PayloadTooLarge { len: usize },
58}
59
60impl core::fmt::Display for Error {
61    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
62        match self {
63            Self::BufferTooSmall(e) => {
64                write!(f, "{e}")
65            }
66            Self::BufferNotConsumed { trailing } => {
67                write!(
68                    f,
69                    "The supplied buffer contained {trailing} trailing bytes"
70                )
71            }
72            Self::InvalidFourCC { fourcc } => {
73                write!(f, "Found invalid FOURCC value {fourcc:X}")
74            }
75            Self::InvalidStartTagLen { len } => {
76                write!(f, "Found invalid start tag length {len}")
77            }
78            Self::InvalidStartTag { tag } => {
79                write!(f, "Found invalid start tag value {tag:X}")
80            }
81            Self::InvalidGroup { group } => {
82                write!(f, "Found invalid group {group:X}")
83            }
84            Self::UnsupportedVersion { version } => {
85                write!(f, "Unsupported SMA protocol version {version}")
86            }
87            Self::UnsupportedProtocol { protocol } => {
88                write!(f, "Unsupported SMA sub-protocol {protocol:X}")
89            }
90            Self::InvalidPadding { padding } => {
91                write!(f, "Found non-zero padding value {padding:X}")
92            }
93            Self::UnsupportedObisId { id } => {
94                write!(f, "Unsupported OBIS ID {id:X}")
95            }
96            Self::InvalidWordcount { wordcount } => {
97                write!(
98                    f,
99                    "The word count {wordcount} in the protocol header \
100                    is invalid"
101                )
102            }
103            Self::UnsupportedCommandClass { class } => {
104                write!(f, "Found unsupported command class {class:X}")
105            }
106            Self::UnsupportedOpcode { opcode } => {
107                write!(f, "Found unsupported opcode {opcode:X}")
108            }
109            Self::PayloadTooLarge { len } => {
110                write!(
111                    f,
112                    "The messages payload length {len} exceeds \
113                    the supported maximum"
114                )
115            }
116        }
117    }
118}
119
120impl From<BufferTooSmall> for Error {
121    fn from(e: BufferTooSmall) -> Self {
122        Self::BufferTooSmall(e)
123    }
124}
125
126/// A specialized Result type for SMA speedwire operations.
127pub type Result<T> = core::result::Result<T, Error>;