1
// SPDX-License-Identifier: BSD-2-Clause
2
/*
3
 * Copyright © The libcoap-rs Contributors, all rights reserved.
4
 * This file is part of the libcoap-rs project, see the README file for
5
 * general information on this project and the NOTICE.md and LICENSE files
6
 * for information regarding copyright ownership and terms of use.
7
 *
8
 * error.rs - CoAP error types.
9
 */
10

            
11
//! Error types
12

            
13
use std::{ffi::NulError, string::FromUtf8Error, sync::PoisonError};
14

            
15
use thiserror::Error;
16

            
17
use crate::protocol::{CoapMessageType, CoapOptionType};
18

            
19
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
20
pub enum MulticastGroupJoinError {
21
    /// Unknown error inside of libcoap
22
    #[error("CoAP join multicast group error: unknown error in call to libcoap")]
23
    Unknown,
24
}
25

            
26
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
27
pub enum MulticastHopLimitError {
28
    /// Unknown error inside of libcoap
29
    #[error("CoAP multicast hop limit error: unable to set hop limit for multicast")]
30
    Unknown,
31
}
32

            
33
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
34
pub enum EndpointCreationError {
35
    /// Unknown error inside of libcoap
36
    #[error("CoAP endpoint creation error: unknown error in call to libcoap")]
37
    Unknown,
38
}
39

            
40
#[cfg(feature = "oscore")]
41
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
42
pub enum OscoreConfigError {
43
    /// Tried to get oscore config as raw struct which has been invalidated before
44
    #[error("Oscore config error: tried to get oscore config as raw struct which has been invalidated before")]
45
    Invalid,
46
    /// Unknown error inside of libcoap, probably due to missing/invalid entries in your oscore
47
    /// config
48
    #[error("Oscore config error: unknown error in call to libcoap, probably due to missing/invalid entries in your oscore config")]
49
    Unknown,
50
}
51

            
52
#[cfg(feature = "oscore")]
53
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
54
pub enum OscoreServerCreationError {
55
    /// Oscore config seems to be invalid, make sure to use it only once
56
    #[error("Oscore server creation error: oscore config seems to be invalid, make sure to use it only once")]
57
    OscoreConfigInvalid(#[from] OscoreConfigError),
58
    /// Unknown error inside of libcoap
59
    #[error("Oscore server creation error: unknown error in call to libcoap")]
60
    Unknown,
61
}
62

            
63
#[cfg(feature = "oscore")]
64
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
65
pub enum OscoreRecipientError {
66
    /// Method is called on a context without appropriate oscore information
67
    #[error("Oscore recipient error: context is missing appropriate oscore information")]
68
    NoOscoreContext,
69
    /// Tried adding duplicate recipient to context
70
    #[error("Oscore recipient error: tried adding duplicate recipient to context")]
71
    DuplicateId,
72
    /// Tried removing a recipient that is not associated with the context
73
    #[error("Oscore recipient error: tried removing a recipient that is not associated with the context")]
74
    NotFound,
75
    /// Unknown error inside of libcoap, adding/removing a recipient failed
76
    #[error("Oscore recipient error: unknown error in call to libcoap, adding/removing the recipient failed")]
77
    Unknown,
78
}
79

            
80
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
81
pub enum ContextConfigurationError {
82
    /// Unknown error inside of libcoap
83
    #[error("CoAP context configuration error: unknown error in call to libcoap")]
84
    Unknown,
85
    #[error(
86
        "CoAP context configuration error: attempted to set encryption context while one has already been configured for this encryption variant"
87
    )]
88
    CryptoContextAlreadySet,
89
}
90

            
91
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
92
pub enum MessageCreationError {
93
    /// Unknown error inside of libcoap
94
    #[error("CoAP message creation error: unknown error in call to libcoap")]
95
    Unknown,
96
}
97

            
98
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
99
pub enum IoProcessError {
100
    /// Unknown error inside of libcoap
101
    #[error("CoAP IO error: unknown error in call to libcoap")]
102
    Unknown,
103
}
104

            
105
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
106
pub enum SessionGetAppDataError {
107
    /// Stored application data type differs from requested type
108
    #[error("CoAP application data retrieval error: wrong type")]
109
    WrongType,
110
}
111

            
112
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
113
pub enum OptionCreationError {
114
    /// Unknown error inside of libcoap
115
    #[error("CoAP option creation error: unknown error in call to libcoap")]
116
    Unknown,
117
}
118

            
119
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
120
pub enum SessionCreationError {
121
    /// Unknown error inside of libcoap
122
    #[error("CoAP session creation error: unknown error in call to libcoap")]
123
    Unknown,
124
    /// Oscore config seems to be invalid, make sure to use it only once
125
    #[cfg(feature = "oscore")]
126
    #[error("CoAP session creation error: oscore config seems to be invalid, make sure to use it only once")]
127
    OscoreConfigInvalid(#[from] OscoreConfigError),
128
}
129

            
130
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
131
pub enum UnknownOptionError {
132
    /// Unknown error inside of libcoap
133
    #[error("CoAP option conversion error: unknown option")]
134
    Unknown,
135
}
136

            
137
#[derive(Error, Debug)]
138
pub enum RngError {
139
    /// Unknown error inside of libcoap
140
    #[error("CoAP RNG error: unknown error in call to libcoap")]
141
    Unknown,
142
    /// RNG mutex is poisoned (panic in another thread while calling RNG function).
143
    #[error("CoAP RNG configuration error: global RNG mutex is poisoned")]
144
    GlobalMutexPoisonError,
145
}
146

            
147
impl<T> From<PoisonError<T>> for RngError {
148
    fn from(_value: PoisonError<T>) -> Self {
149
        RngError::GlobalMutexPoisonError
150
    }
151
}
152

            
153
#[derive(Error, Debug, Clone, Eq, PartialEq)]
154
pub enum OptionValueError {
155
    /// Provided value for option is too short.
156
    #[error("CoAP option has invalid value: too short")]
157
    TooShort,
158
    /// Provided value for option is too long.
159
    #[error("CoAP option has invalid value: too long")]
160
    TooLong,
161
    /// A string value could not be converted to UTF-8.
162
    #[error("CoAP option has invalid value: invalid string")]
163
    StringConversion(#[from] FromUtf8Error),
164
    /// URI encoded in message could not be parsed.
165
    #[error("CoAP option has invalid value: invalid URI")]
166
    UriParsing(#[from] UriParsingError),
167
    /// Option has an illegal value.
168
    #[error("CoAP option has invalid value")]
169
    IllegalValue,
170
}
171

            
172
#[derive(Error, Debug, Clone, Eq, PartialEq)]
173
pub enum UriParsingError {
174
    /// Unknown error inside of libcoap
175
    #[error("CoAP option creation error: unknown error in call to libcoap")]
176
    Unknown,
177
    /// URI does not have a valid scheme for libcoap (coap, coaps, coap+tcp, coaps+tcp, http, https).
178
    #[error("URI scheme {} is not a valid CoAP scheme known to libcoap", .0)]
179
    NotACoapScheme(String),
180
    /// Provided URI contains a null byte.
181
    #[error("Provided URI contains a null byte")]
182
    ContainsNullByte(#[from] NulError),
183
}
184

            
185
#[derive(Error, Debug, Clone, Eq, PartialEq)]
186
pub enum MessageConversionError {
187
    /// Value of an option is invalid.
188
    #[error("CoAP message conversion error: invalid option value for {:?}", .0)]
189
    InvalidOptionValue(Option<CoapOptionType>, #[source] OptionValueError),
190
    /// Message has an option that is specific for another message type (i.e., request option in
191
    /// response message).
192
    #[error("CoAP message conversion error: option of type {:?} invalid for message type", .0)]
193
    InvalidOptionForMessageType(CoapOptionType),
194
    /// Non-repeatable option was repeated.
195
    #[error("CoAP message conversion error: non-repeatable option of type {:?} repeated", .0)]
196
    NonRepeatableOptionRepeated(CoapOptionType),
197
    /// Provided URI has invalid scheme.
198
    #[error("CoAP message conversion error: provided uri does not have scheme valid for CoAP")]
199
    NotACoapUri(UriParsingError),
200
    /// Invalid message code.
201
    #[error("CoAP message conversion error: invalid message code")]
202
    InvalidMessageCode(#[from] MessageCodeError),
203
    /// A message with code 0.00 (Empty) contains data.
204
    #[error("CoAP message conversion error: empty message contains data")]
205
    DataInEmptyMessage,
206
    /// Message has no token.
207
    #[error("CoAP message conversion error: token missing")]
208
    MissingToken,
209
    /// Message has no ID.
210
    #[error("CoAP message conversion error: message id missing")]
211
    MissingMessageId,
212
    /// Two (or more) options were combined which must not be combined (e.g., Proxy-Scheme and
213
    /// Proxy-URI).
214
    #[error("CoAP message conversion error: options {:?} and {:?} cannot be combined", .0, .1)]
215
    InvalidOptionCombination(CoapOptionType, CoapOptionType),
216
    /// A critical option (as defined in [RFC 7252](https://datatracker.ietf.org/doc/html/rfc7252#section-5.4.1)
217
    /// was not recognized).
218
    #[error("CoAP option identified as critical but not recognized")]
219
    CriticalOptionUnrecognized,
220
    /// Unknown error inside of libcoap.
221
    #[error("unknown CoAP message conversion error")]
222
    Unknown,
223
}
224

            
225
impl From<UriParsingError> for MessageConversionError {
226
    fn from(v: UriParsingError) -> Self {
227
        MessageConversionError::NotACoapUri(v)
228
    }
229
}
230

            
231
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
232
pub enum MessageCodeError {
233
    /// Provided message code for request was not a request code.
234
    #[error("CoAP message code conversion error: not a request code")]
235
    NotARequestCode,
236
    /// Provided message code for response was not a response code.
237
    #[error("CoAP message code conversion error: not a response code")]
238
    NotAResponseCode,
239
}
240

            
241
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
242
pub enum MessageTypeError {
243
    /// Message type cannot be used for this message code (e.g., ACK for request).
244
    #[error("message type {:?} cannot be used for this message code", .0)]
245
    InvalidForMessageCode(CoapMessageType),
246
}