1use serde::Deserialize;
9
10#[derive(Debug, Clone, Deserialize)]
23#[serde(deny_unknown_fields)]
24pub struct CoapConfig {
25 #[serde(default)]
27 pub enabled: bool,
28
29 #[serde(default = "default_coap_listen_addr")]
31 pub listen_addr: String,
32
33 #[serde(default = "default_true")]
35 pub dtls_enabled: bool,
36
37 #[serde(default = "default_block_size")]
39 pub block_size: u16,
40
41 #[serde(default = "default_max_payload")]
43 pub max_payload: usize,
44
45 #[serde(default = "default_session_timeout_secs")]
47 pub session_timeout_secs: u64,
48
49 #[serde(default = "default_max_sessions")]
51 pub max_sessions: usize,
52}
53
54fn default_coap_listen_addr() -> String {
55 "0.0.0.0:5684".to_string()
56}
57
58fn default_true() -> bool {
59 true
60}
61
62fn default_block_size() -> u16 {
63 512
64}
65
66fn default_max_payload() -> usize {
67 65536
68}
69
70fn default_session_timeout_secs() -> u64 {
71 300
72}
73
74fn default_max_sessions() -> usize {
75 1024
76}
77
78impl Default for CoapConfig {
79 fn default() -> Self {
80 Self {
81 enabled: false,
82 listen_addr: default_coap_listen_addr(),
83 dtls_enabled: true,
84 block_size: default_block_size(),
85 max_payload: default_max_payload(),
86 session_timeout_secs: default_session_timeout_secs(),
87 max_sessions: default_max_sessions(),
88 }
89 }
90}
91
92impl CoapConfig {
93 pub fn validate(&self) -> Result<(), String> {
95 const VALID_BLOCK_SIZES: &[u16] = &[16, 32, 64, 128, 256, 512, 1024];
96 if !VALID_BLOCK_SIZES.contains(&self.block_size) {
97 return Err(format!(
98 "[coap].block_size must be one of {:?}, got {}",
99 VALID_BLOCK_SIZES, self.block_size
100 ));
101 }
102
103 if self.max_payload == 0 {
104 return Err("[coap].max_payload must be greater than 0".into());
105 }
106
107 Ok(())
108 }
109}