autosar_data_abstraction/communication/network_management/
udp_nm.rs

1use crate::communication::{
2    AbstractNmCluster, AbstractNmClusterCoupling, AbstractNmNode, EthernetCluster, EthernetCommunicationController,
3    EthernetPhysicalChannel, NmEcu,
4};
5use crate::{AbstractionElement, AutosarAbstractionError, IdentifiableAbstractionElement, abstraction_element};
6use autosar_data::{Element, ElementName};
7
8//##################################################################
9
10/// Udp / Ethernet specific `NmCluster`
11#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub struct UdpNmCluster(Element);
13abstraction_element!(UdpNmCluster, UdpNmCluster);
14impl IdentifiableAbstractionElement for UdpNmCluster {}
15
16impl UdpNmCluster {
17    pub(crate) fn new(
18        name: &str,
19        parent: &Element,
20        settings: &UdpNmClusterSettings,
21        ethernet_cluster: &EthernetCluster,
22    ) -> Result<Self, AutosarAbstractionError> {
23        let nm_cluster = parent.create_named_sub_element(ElementName::UdpNmCluster, name)?;
24        let udp_nm_cluster = Self(nm_cluster);
25        udp_nm_cluster.set_communication_cluster(ethernet_cluster)?;
26        udp_nm_cluster.set_nm_msg_cycle_time(settings.nm_msg_cycle_time)?;
27        udp_nm_cluster.set_nm_message_timeout_time(settings.nm_msg_timeout_time)?;
28        udp_nm_cluster.set_nm_network_timeout(settings.nm_network_timeout)?;
29        udp_nm_cluster.set_nm_remote_sleep_indication_time(settings.nm_remote_sleep_indication_time)?;
30        udp_nm_cluster.set_nm_repeat_message_time(settings.nm_repeat_message_time)?;
31        udp_nm_cluster.set_nm_wait_bus_sleep_time(settings.nm_wait_bus_sleep_time)?;
32
33        Ok(udp_nm_cluster)
34    }
35
36    /// set the nmMsgCycleTime
37    pub fn set_nm_msg_cycle_time(&self, cycle_time: f64) -> Result<(), AutosarAbstractionError> {
38        self.element()
39            .get_or_create_sub_element(ElementName::NmMsgCycleTime)?
40            .set_character_data(cycle_time)?;
41        Ok(())
42    }
43
44    /// get the nmMsgCycleTime
45    #[must_use]
46    pub fn nm_msg_cycle_time(&self) -> Option<f64> {
47        self.element()
48            .get_sub_element(ElementName::NmMsgCycleTime)
49            .and_then(|elem| elem.character_data())
50            .and_then(|cdata| cdata.parse_float())
51    }
52
53    /// set the nmMessageTimeoutTime
54    pub fn set_nm_message_timeout_time(&self, timeout_time: f64) -> Result<(), AutosarAbstractionError> {
55        self.element()
56            .get_or_create_sub_element(ElementName::NmMessageTimeoutTime)?
57            .set_character_data(timeout_time)?;
58        Ok(())
59    }
60
61    /// get the nmMessageTimeoutTime
62    #[must_use]
63    pub fn nm_message_timeout_time(&self) -> Option<f64> {
64        self.element()
65            .get_sub_element(ElementName::NmMessageTimeoutTime)
66            .and_then(|elem| elem.character_data())
67            .and_then(|cdata| cdata.parse_float())
68    }
69
70    /// set the `NmNetworkTimeout`
71    pub fn set_nm_network_timeout(&self, timeout: f64) -> Result<(), AutosarAbstractionError> {
72        self.element()
73            .get_or_create_sub_element(ElementName::NmNetworkTimeout)?
74            .set_character_data(timeout)?;
75        Ok(())
76    }
77
78    /// get the `NmNetworkTimeout`
79    #[must_use]
80    pub fn nm_network_timeout(&self) -> Option<f64> {
81        self.element()
82            .get_sub_element(ElementName::NmNetworkTimeout)
83            .and_then(|elem| elem.character_data())
84            .and_then(|cdata| cdata.parse_float())
85    }
86
87    /// set the `NmRemoteSleepIndicationTime`
88    pub fn set_nm_remote_sleep_indication_time(&self, time: f64) -> Result<(), AutosarAbstractionError> {
89        self.element()
90            .get_or_create_sub_element(ElementName::NmRemoteSleepIndicationTime)?
91            .set_character_data(time)?;
92        Ok(())
93    }
94
95    /// get the `NmRemoteSleepIndicationTime`
96    #[must_use]
97    pub fn nm_remote_sleep_indication_time(&self) -> Option<f64> {
98        self.element()
99            .get_sub_element(ElementName::NmRemoteSleepIndicationTime)
100            .and_then(|elem| elem.character_data())
101            .and_then(|cdata| cdata.parse_float())
102    }
103
104    /// set the `NmRepeatMessageTime`
105    pub fn set_nm_repeat_message_time(&self, time: f64) -> Result<(), AutosarAbstractionError> {
106        self.element()
107            .get_or_create_sub_element(ElementName::NmRepeatMessageTime)?
108            .set_character_data(time)?;
109        Ok(())
110    }
111
112    /// get the `NmRepeatMessageTime`
113    #[must_use]
114    pub fn nm_repeat_message_time(&self) -> Option<f64> {
115        self.element()
116            .get_sub_element(ElementName::NmRepeatMessageTime)
117            .and_then(|elem| elem.character_data())
118            .and_then(|cdata| cdata.parse_float())
119    }
120
121    /// set the `NmWaitBusSleepTime`
122    pub fn set_nm_wait_bus_sleep_time(&self, time: f64) -> Result<(), AutosarAbstractionError> {
123        self.element()
124            .get_or_create_sub_element(ElementName::NmWaitBusSleepTime)?
125            .set_character_data(time)?;
126        Ok(())
127    }
128
129    /// get the `NmWaitBusSleepTime`
130    #[must_use]
131    pub fn nm_wait_bus_sleep_time(&self) -> Option<f64> {
132        self.element()
133            .get_sub_element(ElementName::NmWaitBusSleepTime)
134            .and_then(|elem| elem.character_data())
135            .and_then(|cdata| cdata.parse_float())
136    }
137
138    /// add a `UdpNmNode` to the cluster
139    pub fn create_udp_nm_node(
140        &self,
141        name: &str,
142        controller: &EthernetCommunicationController,
143        nm_ecu: &NmEcu,
144        nm_msg_cycle_offset: f64,
145    ) -> Result<UdpNmNode, AutosarAbstractionError> {
146        let nm_nodes = self.element().get_or_create_sub_element(ElementName::NmNodes)?;
147        UdpNmNode::new(name, &nm_nodes, controller, nm_ecu, nm_msg_cycle_offset)
148    }
149
150    /// set or delete the Vlan associated with the cluster through an `EthernetPhysicalChannel` reference
151    ///
152    /// If `vlan` is `Some`, the Vlan is set to the value of `vlan`. If `vlan` is `None`, the Vlan is removed.
153    pub fn set_vlan(&self, vlan: Option<&EthernetPhysicalChannel>) -> Result<(), AutosarAbstractionError> {
154        if let Some(vlan) = vlan {
155            self.element()
156                .get_or_create_sub_element(ElementName::VlanRef)?
157                .set_reference_target(vlan.element())?;
158        } else {
159            let _ = self.element().remove_sub_element_kind(ElementName::VlanRef);
160        }
161        Ok(())
162    }
163
164    /// get the Vlan associated with the cluster
165    #[must_use]
166    pub fn vlan(&self) -> Option<EthernetPhysicalChannel> {
167        self.element()
168            .get_sub_element(ElementName::VlanRef)
169            .and_then(|vlan_ref| vlan_ref.get_reference_target().ok())
170            .and_then(|elem| elem.try_into().ok())
171    }
172
173    /// set or delete the value nmImmediateNmTransmissions
174    pub fn set_nm_immediate_nm_transmissions(&self, value: Option<u32>) -> Result<(), AutosarAbstractionError> {
175        if let Some(value) = value {
176            self.element()
177                .get_or_create_sub_element(ElementName::NmImmediateNmTransmissions)?
178                .set_character_data(u64::from(value))?;
179        } else {
180            let _ = self
181                .element()
182                .remove_sub_element_kind(ElementName::NmImmediateNmTransmissions);
183        }
184        Ok(())
185    }
186
187    /// get the value of nmImmediateNmTransmissions
188    #[must_use]
189    pub fn nm_immediate_nm_transmissions(&self) -> Option<u32> {
190        self.element()
191            .get_sub_element(ElementName::NmImmediateNmTransmissions)
192            .and_then(|elem| elem.character_data())
193            .and_then(|cdata| cdata.parse_integer())
194    }
195
196    /// set or delete the value nmCbvPosition
197    pub fn set_nm_cbv_position(&self, value: Option<u32>) -> Result<(), AutosarAbstractionError> {
198        if let Some(value) = value {
199            self.element()
200                .get_or_create_sub_element(ElementName::NmCbvPosition)?
201                .set_character_data(u64::from(value))?;
202        } else {
203            let _ = self.element().remove_sub_element_kind(ElementName::NmCbvPosition);
204        }
205        Ok(())
206    }
207
208    /// get the value of nmCbvPosition
209    #[must_use]
210    pub fn nm_cbv_position(&self) -> Option<u32> {
211        self.element()
212            .get_sub_element(ElementName::NmCbvPosition)
213            .and_then(|elem| elem.character_data())
214            .and_then(|cdata| cdata.parse_integer())
215    }
216
217    /// set or delete the value nmNidPosition
218    pub fn set_nm_nid_position(&self, value: Option<u32>) -> Result<(), AutosarAbstractionError> {
219        if let Some(value) = value {
220            self.element()
221                .get_or_create_sub_element(ElementName::NmNidPosition)?
222                .set_character_data(u64::from(value))?;
223        } else {
224            let _ = self.element().remove_sub_element_kind(ElementName::NmNidPosition);
225        }
226        Ok(())
227    }
228
229    /// get the value of nmNidPosition
230    #[must_use]
231    pub fn nm_nid_position(&self) -> Option<u32> {
232        self.element()
233            .get_sub_element(ElementName::NmNidPosition)
234            .and_then(|elem| elem.character_data())
235            .and_then(|cdata| cdata.parse_integer())
236    }
237}
238
239impl AbstractNmCluster for UdpNmCluster {
240    type CommunicationClusterType = EthernetCluster;
241    type NmNodeType = UdpNmNode;
242}
243
244//##################################################################
245
246/// `UdpNmClusterSettings` encapsulates the mandatory settings for a `UdpNmCluster`
247#[derive(Debug, Clone, PartialEq)]
248pub struct UdpNmClusterSettings {
249    /// Period of an `NmPdu` in seconds
250    pub nm_msg_cycle_time: f64,
251    /// Timeout of a `NmPdu` in seconds
252    pub nm_msg_timeout_time: f64,
253    /// Network Timeout for `NmPdus` in seconds
254    pub nm_network_timeout: f64,
255    /// Timeout for Remote Sleep Indication in seconds
256    pub nm_remote_sleep_indication_time: f64,
257    /// Timeout for Repeat Message State in seconds
258    pub nm_repeat_message_time: f64,
259    /// Timeout for bus calm down phase in seconds
260    pub nm_wait_bus_sleep_time: f64,
261}
262
263//##################################################################
264
265/// Udp / Ethernet specific `NmClusterCoupling`
266///
267/// It couples multiple `UdpNmCluster`s and provides UdpNm-specific settings
268#[derive(Debug, Clone, PartialEq, Eq, Hash)]
269pub struct UdpNmClusterCoupling(Element);
270abstraction_element!(UdpNmClusterCoupling, UdpNmClusterCoupling);
271
272impl UdpNmClusterCoupling {
273    pub(crate) fn new(parent: &Element) -> Result<Self, AutosarAbstractionError> {
274        let nm_cluster_coupling = parent.create_sub_element(ElementName::UdpNmClusterCoupling)?;
275        Ok(Self(nm_cluster_coupling))
276    }
277
278    /// set or remove the nmImmediateRestartEnabled flag
279    ///
280    /// If `enabled` is `Some`, the flag is set to the value of `enabled`.
281    /// If `enabled` is `None`, the flag is removed.
282    pub fn set_nm_immediate_restart_enabled(&self, enabled: Option<bool>) -> Result<(), AutosarAbstractionError> {
283        if let Some(enabled) = enabled {
284            self.element()
285                .get_or_create_sub_element(ElementName::NmImmediateRestartEnabled)?
286                .set_character_data(enabled)?;
287        } else {
288            let _ = self
289                .element()
290                .remove_sub_element_kind(ElementName::NmImmediateRestartEnabled);
291        }
292        Ok(())
293    }
294
295    /// get the nmImmediateRestartEnabled flag
296    #[must_use]
297    pub fn nm_immediate_restart_enabled(&self) -> Option<bool> {
298        self.element()
299            .get_sub_element(ElementName::NmImmediateRestartEnabled)
300            .and_then(|elem| elem.character_data())
301            .and_then(|cdata| cdata.parse_bool())
302    }
303}
304
305impl AbstractNmClusterCoupling for UdpNmClusterCoupling {
306    type NmClusterType = UdpNmCluster;
307}
308
309//##################################################################
310
311/// Udp / Ethernet specific `NmNode`
312#[derive(Debug, Clone, PartialEq, Eq, Hash)]
313pub struct UdpNmNode(Element);
314abstraction_element!(UdpNmNode, UdpNmNode);
315impl IdentifiableAbstractionElement for UdpNmNode {}
316
317impl UdpNmNode {
318    pub(crate) fn new(
319        name: &str,
320        parent: &Element,
321        controller: &EthernetCommunicationController,
322        nm_ecu: &NmEcu,
323        nm_msg_cycle_offset: f64,
324    ) -> Result<Self, AutosarAbstractionError> {
325        let udp_nm_node_elem = parent.create_named_sub_element(ElementName::UdpNmNode, name)?;
326        let udp_nm_node = Self(udp_nm_node_elem);
327        udp_nm_node.set_communication_controller(controller)?;
328        udp_nm_node.set_nm_ecu(nm_ecu)?;
329        udp_nm_node.set_nm_msg_cycle_offset(nm_msg_cycle_offset)?;
330
331        Ok(udp_nm_node)
332    }
333
334    /// set the `NmMsgCycleOffset`
335    pub fn set_nm_msg_cycle_offset(&self, offset: f64) -> Result<(), AutosarAbstractionError> {
336        self.element()
337            .get_or_create_sub_element(ElementName::NmMsgCycleOffset)?
338            .set_character_data(offset)?;
339        Ok(())
340    }
341
342    /// get the `NmMsgCycleOffset`
343    #[must_use]
344    pub fn nm_msg_cycle_offset(&self) -> Option<f64> {
345        self.element()
346            .get_sub_element(ElementName::NmMsgCycleOffset)
347            .and_then(|elem| elem.character_data())
348            .and_then(|cdata| cdata.parse_float())
349    }
350
351    /// set ot remove the allNmMessagesKeepAwake flag
352    ///
353    /// If `enabled` is `Some`, the flag is set to the value of `enabled`. If `enabled` is `None`, the flag is removed.
354    pub fn set_all_nm_messages_keep_awake(&self, enabled: Option<bool>) -> Result<(), AutosarAbstractionError> {
355        if let Some(enabled) = enabled {
356            self.element()
357                .get_or_create_sub_element(ElementName::AllNmMessagesKeepAwake)?
358                .set_character_data(enabled)?;
359        } else {
360            let _ = self
361                .element()
362                .remove_sub_element_kind(ElementName::AllNmMessagesKeepAwake);
363        }
364        Ok(())
365    }
366
367    /// get the allNmMessagesKeepAwake flag
368    #[must_use]
369    pub fn all_nm_messages_keep_awake(&self) -> Option<bool> {
370        self.element()
371            .get_sub_element(ElementName::AllNmMessagesKeepAwake)
372            .and_then(|elem| elem.character_data())
373            .and_then(|cdata| cdata.parse_bool())
374    }
375}
376
377impl AbstractNmNode for UdpNmNode {
378    type CommunicationControllerType = EthernetCommunicationController;
379}