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>;