umsh_ulcp_device/
lan_bearer.rs1use umsh_ulcp::{
3 Status,
4 ids::prop,
5 lan::{DEFAULT_INGRESS_LIMIT, Group},
6};
7
8#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
10pub enum LanBearerRole {
11 #[default]
13 None,
14 Forwarding,
18 Phy,
22}
23
24#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
29pub struct LanBearerConfig {
30 pub enabled: bool,
31 group: Option<Group>,
32 ingress_limit: Option<u16>,
33}
34
35impl LanBearerConfig {
36 pub fn group(&self) -> Group {
38 self.group.unwrap_or_default()
39 }
40
41 pub fn ingress_limit(&self) -> u16 {
43 self.ingress_limit.unwrap_or(DEFAULT_INGRESS_LIMIT)
44 }
45
46 pub const fn is_config_prop(key: u32) -> bool {
48 matches!(
49 key,
50 prop::LAN_BEARER_ENABLED | prop::LAN_BEARER_GROUP | prop::LAN_BEARER_INGRESS_LIMIT
51 )
52 }
53
54 pub fn is_default(&self, key: u32) -> bool {
56 match key {
57 prop::LAN_BEARER_GROUP => self.group.is_none(),
58 prop::LAN_BEARER_INGRESS_LIMIT => self.ingress_limit.is_none(),
59 _ => false,
60 }
61 }
62
63 pub fn restore(&mut self, key: u32, saved: &Self) {
65 match key {
66 prop::LAN_BEARER_ENABLED => self.enabled = saved.enabled,
67 prop::LAN_BEARER_GROUP => self.group = saved.group,
68 prop::LAN_BEARER_INGRESS_LIMIT => self.ingress_limit = saved.ingress_limit,
69 _ => {}
70 }
71 }
72
73 pub fn set(&mut self, key: u32, value: &[u8]) -> Result<(), Status> {
76 match key {
77 prop::LAN_BEARER_ENABLED => {
78 self.enabled = match value {
79 [0] => false,
80 [1] => true,
81 _ => return Err(Status::INVALID_ARGUMENT),
82 }
83 }
84 prop::LAN_BEARER_GROUP => {
85 self.group = match value {
86 [] => None,
87 _ => Some(Group::decode(value).ok_or(Status::INVALID_ARGUMENT)?),
88 }
89 }
90 prop::LAN_BEARER_INGRESS_LIMIT => {
91 self.ingress_limit = match value {
92 [] => None,
93 _ => {
94 let limit = u16::from_le_bytes(
95 value.try_into().map_err(|_| Status::INVALID_ARGUMENT)?,
96 );
97 if limit == 0 {
98 return Err(Status::INVALID_ARGUMENT);
99 }
100 Some(limit)
101 }
102 }
103 }
104 _ => return Err(Status::PROP_NOT_FOUND),
105 }
106 Ok(())
107 }
108
109 pub fn encode(&self, key: u32, out: &mut [u8]) -> Option<usize> {
112 let group;
113 let limit;
114 let bytes: &[u8] = match key {
115 prop::LAN_BEARER_ENABLED => &[self.enabled as u8],
116 prop::LAN_BEARER_GROUP => {
117 group = self.group().encode();
118 &group
119 }
120 prop::LAN_BEARER_INGRESS_LIMIT => {
121 limit = self.ingress_limit().to_le_bytes();
122 &limit
123 }
124 _ => return None,
125 };
126 out.get_mut(..bytes.len())?.copy_from_slice(bytes);
127 Some(bytes.len())
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134
135 #[test]
136 fn an_empty_write_returns_a_setting_to_the_default() {
137 let mut config = LanBearerConfig::default();
138 assert!(config.is_default(prop::LAN_BEARER_GROUP));
139 config
140 .set(prop::LAN_BEARER_GROUP, &[239, 1, 2, 3, 0x10, 0x27])
141 .unwrap();
142 config
143 .set(prop::LAN_BEARER_INGRESS_LIMIT, &30u16.to_le_bytes())
144 .unwrap();
145 assert_eq!(config.group().address, [239, 1, 2, 3]);
146 assert_eq!(config.ingress_limit(), 30);
147 assert!(!config.is_default(prop::LAN_BEARER_GROUP));
148
149 config.set(prop::LAN_BEARER_GROUP, &[]).unwrap();
150 config.set(prop::LAN_BEARER_INGRESS_LIMIT, &[]).unwrap();
151 assert_eq!(config, LanBearerConfig::default());
152 assert_eq!(config.group(), Group::default());
153 assert_eq!(config.ingress_limit(), DEFAULT_INGRESS_LIMIT);
154 assert_eq!(
155 config.set(prop::LAN_BEARER_ENABLED, &[]),
156 Err(Status::INVALID_ARGUMENT)
157 );
158 }
159}