autosar_data_abstraction/communication/physical_channel/ethernet/
someip_old.rs

1use crate::communication::{SoAdRoutingGroup, SocketAddress};
2use crate::{AbstractionElement, AutosarAbstractionError, IdentifiableAbstractionElement};
3use autosar_data::{Element, ElementName};
4
5//##################################################################
6
7/// A `ProvidedServiceInstanceV1` is a SD service instance that is provided by this ECU.
8///
9/// This is the old V1 version of the service definition.
10#[derive(Debug, Clone, PartialEq, Eq, Hash)]
11pub struct ProvidedServiceInstanceV1(Element);
12
13impl AbstractionElement for ProvidedServiceInstanceV1 {
14    fn element(&self) -> &Element {
15        &self.0
16    }
17}
18
19impl IdentifiableAbstractionElement for ProvidedServiceInstanceV1 {}
20
21impl TryFrom<Element> for ProvidedServiceInstanceV1 {
22    type Error = AutosarAbstractionError;
23
24    fn try_from(element: Element) -> Result<Self, Self::Error> {
25        // hierarchy: ApplicationEndpoint -> ProvidedServiceInstances -> ProvidedServiceInstance
26        let parent_name = element.parent()?.map(|p| p.element_name());
27        if !matches!(parent_name, Some(ElementName::ProvidedServiceInstances)) {
28            return Err(AutosarAbstractionError::ConversionError {
29                element,
30                dest: "ProvidedServiceInstanceV1".to_string(),
31            });
32        }
33
34        if element.element_name() == ElementName::ProvidedServiceInstance {
35            Ok(Self(element))
36        } else {
37            Err(AutosarAbstractionError::ConversionError {
38                element,
39                dest: "ProvidedServiceInstanceV1".to_string(),
40            })
41        }
42    }
43}
44
45impl ProvidedServiceInstanceV1 {
46    pub(crate) fn new(
47        name: &str,
48        parent: &Element,
49        service_identifier: u16,
50        instance_identifier: u16,
51    ) -> Result<Self, AutosarAbstractionError> {
52        let psi_elem = parent.create_named_sub_element(ElementName::ProvidedServiceInstance, name)?;
53        let psi = Self(psi_elem);
54
55        psi.set_service_identifier(u32::from(service_identifier))?;
56        psi.set_instance_identifier(u32::from(instance_identifier))?;
57
58        Ok(psi)
59    }
60
61    /// set the service identifier of this `ProvidedServiceInstance`
62    pub fn set_service_identifier(&self, service_identifier: u32) -> Result<(), AutosarAbstractionError> {
63        self.element()
64            .get_or_create_sub_element(ElementName::ServiceIdentifier)?
65            .set_character_data(u64::from(service_identifier))?;
66        Ok(())
67    }
68
69    /// get the service identifier of this `ProvidedServiceInstance`
70    #[must_use]
71    pub fn service_identifier(&self) -> Option<u32> {
72        self.0
73            .get_sub_element(ElementName::ServiceIdentifier)
74            .and_then(|si| si.character_data())
75            .and_then(|cdata| cdata.parse_integer())
76    }
77
78    /// set the instance identifier of this `ProvidedServiceInstance`
79    pub fn set_instance_identifier(&self, instance_identifier: u32) -> Result<(), AutosarAbstractionError> {
80        self.element()
81            .get_or_create_sub_element(ElementName::InstanceIdentifier)?
82            .set_character_data(u64::from(instance_identifier))?;
83        Ok(())
84    }
85
86    /// get the instance identifier of this `ProvidedServiceInstance`
87    #[must_use]
88    pub fn instance_identifier(&self) -> Option<u32> {
89        self.0
90            .get_sub_element(ElementName::InstanceIdentifier)
91            .and_then(|ii| ii.character_data())
92            .and_then(|cdata| cdata.parse_integer())
93    }
94
95    /// create a new `EventHandlerV1` in this `ProvidedServiceInstance`
96    pub fn create_event_handler(&self, name: &str) -> Result<EventHandlerV1, AutosarAbstractionError> {
97        let ehs = self.element().get_or_create_sub_element(ElementName::EventHandlers)?;
98        EventHandlerV1::new(name, &ehs)
99    }
100
101    /// get the `EventHandlerV1`s in this `ProvidedServiceInstance`
102    pub fn event_handlers(&self) -> impl Iterator<Item = EventHandlerV1> + Send + use<> {
103        self.element()
104            .get_sub_element(ElementName::EventHandlers)
105            .into_iter()
106            .flat_map(|ehs| ehs.sub_elements())
107            .filter_map(|eh| EventHandlerV1::try_from(eh).ok())
108    }
109
110    /// set the SD server configuration for this `ProvidedServiceInstance`
111    pub fn set_sd_server_config(&self, sd_server_config: &SdConfig) -> Result<(), AutosarAbstractionError> {
112        // remove any existing SdServerConfig, so that we can start fresh
113        let _ = self.element().remove_sub_element_kind(ElementName::SdServerConfig);
114
115        let config_elem = self.element().get_or_create_sub_element(ElementName::SdServerConfig)?;
116        config_elem
117            .create_sub_element(ElementName::ServerServiceMajorVersion)?
118            .set_character_data(u64::from(sd_server_config.service_major_version))?;
119        config_elem
120            .create_sub_element(ElementName::ServerServiceMinorVersion)?
121            .set_character_data(u64::from(sd_server_config.service_minor_version))?;
122        config_elem
123            .create_sub_element(ElementName::Ttl)?
124            .set_character_data(u64::from(sd_server_config.ttl))?;
125        if let Some(offer_cyclic_delay) = sd_server_config.offer_cyclic_delay {
126            config_elem
127                .create_sub_element(ElementName::OfferCyclicDelay)?
128                .set_character_data(offer_cyclic_delay)?;
129        }
130
131        let initial_offer_elem = config_elem.create_sub_element(ElementName::InitialOfferBehavior)?;
132        initial_offer_elem
133            .create_sub_element(ElementName::InitialDelayMaxValue)?
134            .set_character_data(sd_server_config.initial_delay_max_value)?;
135        initial_offer_elem
136            .create_sub_element(ElementName::InitialDelayMinValue)?
137            .set_character_data(sd_server_config.initial_delay_min_value)?;
138        initial_offer_elem
139            .create_sub_element(ElementName::InitialRepetitionsMax)?
140            .set_character_data(u64::from(sd_server_config.initial_repetitions_max))?;
141        if let Some(initial_repetitions_base_delay) = sd_server_config.initial_repetitions_base_delay {
142            initial_offer_elem
143                .create_sub_element(ElementName::InitialRepetitionsBaseDelay)?
144                .set_character_data(initial_repetitions_base_delay)?;
145        }
146
147        let req_resp_delay_elem = config_elem.create_sub_element(ElementName::RequestResponseDelay)?;
148        req_resp_delay_elem
149            .create_sub_element(ElementName::MaxValue)?
150            .set_character_data(sd_server_config.request_response_delay_max_value)?;
151        req_resp_delay_elem
152            .create_sub_element(ElementName::MinValue)?
153            .set_character_data(sd_server_config.request_response_delay_min_value)?;
154
155        Ok(())
156    }
157
158    /// get the SD server configuration for this `ProvidedServiceInstance`
159    #[must_use]
160    pub fn sd_server_config(&self) -> Option<SdConfig> {
161        let config_elem = self.element().get_sub_element(ElementName::SdServerConfig)?;
162        let service_major_version = config_elem
163            .get_sub_element(ElementName::ServerServiceMajorVersion)?
164            .character_data()?
165            .parse_integer()?;
166        let service_minor_version = config_elem
167            .get_sub_element(ElementName::ServerServiceMinorVersion)?
168            .character_data()?
169            .parse_integer()?;
170
171        let initial_offer_elem = config_elem.get_sub_element(ElementName::InitialOfferBehavior)?;
172        let initial_delay_max_value = initial_offer_elem
173            .get_sub_element(ElementName::InitialDelayMaxValue)?
174            .character_data()?
175            .parse_float()?;
176        let initial_delay_min_value = initial_offer_elem
177            .get_sub_element(ElementName::InitialDelayMinValue)?
178            .character_data()?
179            .parse_float()?;
180        let initial_repetitions_max = initial_offer_elem
181            .get_sub_element(ElementName::InitialRepetitionsMax)?
182            .character_data()?
183            .parse_integer()?;
184        let initial_repetitions_base_delay = initial_offer_elem
185            .get_sub_element(ElementName::InitialRepetitionsBaseDelay)
186            .and_then(|elem| elem.character_data())
187            .and_then(|cdata| cdata.parse_float());
188        let offer_cyclic_delay = config_elem
189            .get_sub_element(ElementName::OfferCyclicDelay)
190            .and_then(|elem| elem.character_data())
191            .and_then(|cdata| cdata.parse_float());
192
193        let req_resp_delay_elem = config_elem.get_sub_element(ElementName::RequestResponseDelay)?;
194        let request_response_delay_max_value = req_resp_delay_elem
195            .get_sub_element(ElementName::MaxValue)?
196            .character_data()?
197            .parse_float()?;
198        let request_response_delay_min_value = req_resp_delay_elem
199            .get_sub_element(ElementName::MinValue)?
200            .character_data()?
201            .parse_float()?;
202
203        let ttl = config_elem
204            .get_sub_element(ElementName::Ttl)?
205            .character_data()?
206            .parse_integer()?;
207
208        Some(SdConfig {
209            service_major_version,
210            service_minor_version,
211            initial_delay_max_value,
212            initial_delay_min_value,
213            initial_repetitions_base_delay,
214            initial_repetitions_max,
215            offer_cyclic_delay,
216            request_response_delay_max_value,
217            request_response_delay_min_value,
218            ttl,
219        })
220    }
221}
222
223//##################################################################
224
225/// An `EventHandlerV1` is a SD event handler that is used to receive events from other ECUs.
226///
227/// This is the old V1 version of the service definition.
228#[derive(Debug, Clone, PartialEq, Eq, Hash)]
229pub struct EventHandlerV1(Element);
230
231impl AbstractionElement for EventHandlerV1 {
232    fn element(&self) -> &Element {
233        &self.0
234    }
235}
236
237impl IdentifiableAbstractionElement for EventHandlerV1 {}
238
239impl TryFrom<Element> for EventHandlerV1 {
240    type Error = AutosarAbstractionError;
241
242    fn try_from(element: Element) -> Result<Self, Self::Error> {
243        // hierarchy: ApplicationEndpoint(named) -> ProvidedServiceInstances -> ProvidedServiceInstance(named) -> EventHandlers -> EventHandler(named)
244        let parent_name = element
245            .named_parent()?
246            .and_then(|p| p.named_parent().ok().flatten())
247            .map(|p| p.element_name());
248        if !matches!(parent_name, Some(ElementName::ApplicationEndpoint)) {
249            return Err(AutosarAbstractionError::ConversionError {
250                element,
251                dest: "EventHandlerV1".to_string(),
252            });
253        }
254
255        if element.element_name() == ElementName::EventHandler {
256            Ok(Self(element))
257        } else {
258            Err(AutosarAbstractionError::ConversionError {
259                element,
260                dest: "EventHandlerV1".to_string(),
261            })
262        }
263    }
264}
265
266impl EventHandlerV1 {
267    pub(crate) fn new(name: &str, parent: &Element) -> Result<Self, AutosarAbstractionError> {
268        let elem = parent.create_named_sub_element(ElementName::EventHandler, name)?;
269        Ok(Self(elem))
270    }
271
272    /// add a reference to a `ConsumedEventGroupV1` to this `EventHandlerV1`
273    pub fn add_consumed_event_group(
274        &self,
275        consumed_event_group: &ConsumedEventGroupV1,
276    ) -> Result<(), AutosarAbstractionError> {
277        let elem = self
278            .element()
279            .get_or_create_sub_element(ElementName::ConsumedEventGroupRefs)?;
280        elem.create_sub_element(ElementName::ConsumedEventGroupRef)?
281            .set_reference_target(consumed_event_group.element())?;
282        Ok(())
283    }
284
285    /// add a reference to a `SoAdRoutingGroup` to this `EventHandler`
286    pub fn add_routing_group(&self, routing_group: &SoAdRoutingGroup) -> Result<(), AutosarAbstractionError> {
287        let elem = self
288            .element()
289            .get_or_create_sub_element(ElementName::RoutingGroupRefs)?;
290        elem.create_sub_element(ElementName::RoutingGroupRef)?
291            .set_reference_target(routing_group.element())?;
292        Ok(())
293    }
294
295    /// get the routing groups referenced by this `EventHandler`
296    pub fn routing_groups(&self) -> impl Iterator<Item = SoAdRoutingGroup> + Send + use<> {
297        self.element()
298            .get_sub_element(ElementName::RoutingGroupRefs)
299            .into_iter()
300            .flat_map(|rgs| rgs.sub_elements())
301            .filter_map(|rgref| rgref.get_reference_target().ok())
302            .filter_map(|rg| SoAdRoutingGroup::try_from(rg).ok())
303    }
304
305    /// set the SD server event configuration for this `EventHandler`
306    pub fn set_sd_server_config(&self, server_config: &SdEventConfig) -> Result<(), AutosarAbstractionError> {
307        // remove any existing SdServerConfig, so that we can start fresh
308        let _ = self.element().remove_sub_element_kind(ElementName::SdServerConfig);
309
310        let sd_config_elem = self.element().create_sub_element(ElementName::SdServerConfig)?;
311        sd_config_elem
312            .create_sub_element(ElementName::Ttl)?
313            .set_character_data(u64::from(server_config.ttl))?;
314
315        let req_resp_delay_elem = sd_config_elem.create_sub_element(ElementName::RequestResponseDelay)?;
316        req_resp_delay_elem
317            .create_sub_element(ElementName::MinValue)?
318            .set_character_data(server_config.request_response_delay_min_value)?;
319        req_resp_delay_elem
320            .create_sub_element(ElementName::MaxValue)?
321            .set_character_data(server_config.request_response_delay_max_value)?;
322
323        Ok(())
324    }
325
326    /// get the SD server configuration for this `EventHandler`
327    #[must_use]
328    pub fn sd_server_config(&self) -> Option<SdEventConfig> {
329        let config_elem = self.element().get_sub_element(ElementName::SdServerConfig)?;
330        let ttl = config_elem
331            .get_sub_element(ElementName::Ttl)?
332            .character_data()?
333            .parse_integer()?;
334
335        let req_resp_delay_elem = config_elem.get_sub_element(ElementName::RequestResponseDelay)?;
336        let request_response_delay_min_value = req_resp_delay_elem
337            .get_sub_element(ElementName::MinValue)?
338            .character_data()?
339            .parse_float()?;
340        let request_response_delay_max_value = req_resp_delay_elem
341            .get_sub_element(ElementName::MaxValue)?
342            .character_data()?
343            .parse_float()?;
344
345        Some(SdEventConfig {
346            request_response_delay_max_value,
347            request_response_delay_min_value,
348            ttl,
349        })
350    }
351
352    /// get the consumed event groups referenced by this `EventHandler`
353    pub fn consumed_event_groups(&self) -> impl Iterator<Item = ConsumedEventGroupV1> + Send + use<> {
354        self.element()
355            .get_sub_element(ElementName::ConsumedEventGroupRefs)
356            .into_iter()
357            .flat_map(|cegs| cegs.sub_elements())
358            .filter_map(|cegref| cegref.get_reference_target().ok())
359            .filter_map(|ceg| ConsumedEventGroupV1::try_from(ceg).ok())
360    }
361}
362
363//##################################################################
364
365/// A `ConsumedServiceInstanceV1` is a SD service instance that is consumed by this ECU.
366///
367/// This is the old V1 version of the service definition.
368#[derive(Debug, Clone, PartialEq, Eq, Hash)]
369pub struct ConsumedServiceInstanceV1(Element);
370
371impl AbstractionElement for ConsumedServiceInstanceV1 {
372    fn element(&self) -> &Element {
373        &self.0
374    }
375}
376
377impl IdentifiableAbstractionElement for ConsumedServiceInstanceV1 {}
378
379impl TryFrom<Element> for ConsumedServiceInstanceV1 {
380    type Error = AutosarAbstractionError;
381
382    fn try_from(element: Element) -> Result<Self, Self::Error> {
383        // hierarchy: ApplicationEndpoint -> ConsumedServiceInstances -> ConsumedServiceInstance
384        let parent_name = element.parent()?.map(|p| p.element_name());
385        if !matches!(parent_name, Some(ElementName::ConsumedServiceInstances)) {
386            return Err(AutosarAbstractionError::ConversionError {
387                element,
388                dest: "ConsumedServiceInstanceV1".to_string(),
389            });
390        }
391
392        if element.element_name() == ElementName::ConsumedServiceInstance {
393            Ok(Self(element))
394        } else {
395            Err(AutosarAbstractionError::ConversionError {
396                element,
397                dest: "ConsumedServiceInstanceV1".to_string(),
398            })
399        }
400    }
401}
402
403impl ConsumedServiceInstanceV1 {
404    pub(crate) fn new(
405        name: &str,
406        parent: &Element,
407        provided_service_instance: &ProvidedServiceInstanceV1,
408    ) -> Result<Self, AutosarAbstractionError> {
409        let elem = parent.create_named_sub_element(ElementName::ConsumedServiceInstance, name)?;
410
411        elem.create_sub_element(ElementName::ProvidedServiceInstanceRef)?
412            .set_reference_target(provided_service_instance.element())?;
413
414        Ok(Self(elem))
415    }
416
417    /// get the `ProvidedServiceInstance` referenced by this `ConsumedServiceInstanceV1`
418    #[must_use]
419    pub fn provided_service_instance(&self) -> Option<ProvidedServiceInstanceV1> {
420        self.element()
421            .get_sub_element(ElementName::ProvidedServiceInstanceRef)
422            .and_then(|psiref| psiref.get_reference_target().ok())
423            .and_then(|psielem| ProvidedServiceInstanceV1::try_from(psielem).ok())
424    }
425
426    /// create a new `ConsumedEventGrup` in this `ConsumedServiceInstanceV1`
427    pub fn create_consumed_event_group(
428        &self,
429        name: &str,
430        event_group_identifier: u32,
431        event_handler: &EventHandlerV1,
432    ) -> Result<ConsumedEventGroupV1, AutosarAbstractionError> {
433        let cegs = self
434            .element()
435            .get_or_create_sub_element(ElementName::ConsumedEventGroups)?;
436        ConsumedEventGroupV1::new(name, &cegs, event_group_identifier, event_handler)
437    }
438
439    /// get the `ConsumedEventGroup`s in this `ConsumedServiceInstanceV1`
440    pub fn consumed_event_groups(&self) -> impl Iterator<Item = ConsumedEventGroupV1> + Send + use<> {
441        self.element()
442            .get_sub_element(ElementName::ConsumedEventGroups)
443            .into_iter()
444            .flat_map(|cegs| cegs.sub_elements())
445            .filter_map(|ceg| ConsumedEventGroupV1::try_from(ceg).ok())
446    }
447
448    /// set the SD client configuration for this `ConsumedServiceInstanceV1`
449    pub fn set_sd_client_config(&self, sd_client_config: &SdConfig) -> Result<(), AutosarAbstractionError> {
450        // remove any existing SdClientConfig, so that we can start fresh
451        let _ = self.element().remove_sub_element_kind(ElementName::SdClientConfig);
452
453        let config_elem = self.element().get_or_create_sub_element(ElementName::SdClientConfig)?;
454        config_elem
455            .create_sub_element(ElementName::ClientServiceMajorVersion)?
456            .set_character_data(u64::from(sd_client_config.service_major_version))?;
457        config_elem
458            .create_sub_element(ElementName::ClientServiceMinorVersion)?
459            .set_character_data(u64::from(sd_client_config.service_minor_version))?;
460        config_elem
461            .create_sub_element(ElementName::Ttl)?
462            .set_character_data(u64::from(sd_client_config.ttl))?;
463
464        let initial_find_elem = config_elem.create_sub_element(ElementName::InitialFindBehavior)?;
465        initial_find_elem
466            .create_sub_element(ElementName::InitialDelayMaxValue)?
467            .set_character_data(sd_client_config.initial_delay_max_value)?;
468        initial_find_elem
469            .create_sub_element(ElementName::InitialDelayMinValue)?
470            .set_character_data(sd_client_config.initial_delay_min_value)?;
471        initial_find_elem
472            .create_sub_element(ElementName::InitialRepetitionsMax)?
473            .set_character_data(u64::from(sd_client_config.initial_repetitions_max))?;
474        if let Some(initial_repetitions_base_delay) = sd_client_config.initial_repetitions_base_delay {
475            initial_find_elem
476                .create_sub_element(ElementName::InitialRepetitionsBaseDelay)?
477                .set_character_data(initial_repetitions_base_delay)?;
478        }
479        // offer_cyclic_delay is not used in client configuration, so it is not set
480
481        Ok(())
482    }
483
484    /// get the SD client configuration for this `ConsumedServiceInstanceV1`
485    #[must_use]
486    pub fn sd_client_config(&self) -> Option<SdConfig> {
487        let config_elem = self.element().get_sub_element(ElementName::SdClientConfig)?;
488        let service_major_version = config_elem
489            .get_sub_element(ElementName::ClientServiceMajorVersion)?
490            .character_data()?
491            .parse_integer()?;
492        let service_minor_version = config_elem
493            .get_sub_element(ElementName::ClientServiceMinorVersion)?
494            .character_data()?
495            .parse_integer()?;
496        let ttl = config_elem
497            .get_sub_element(ElementName::Ttl)?
498            .character_data()?
499            .parse_integer()?;
500
501        let initial_find_elem = config_elem.get_sub_element(ElementName::InitialFindBehavior)?;
502        let initial_delay_max_value = initial_find_elem
503            .get_sub_element(ElementName::InitialDelayMaxValue)?
504            .character_data()?
505            .parse_float()?;
506        let initial_delay_min_value = initial_find_elem
507            .get_sub_element(ElementName::InitialDelayMinValue)?
508            .character_data()?
509            .parse_float()?;
510        let initial_repetitions_max = initial_find_elem
511            .get_sub_element(ElementName::InitialRepetitionsMax)?
512            .character_data()?
513            .parse_integer()?;
514        let initial_repetitions_base_delay = initial_find_elem
515            .get_sub_element(ElementName::InitialRepetitionsBaseDelay)
516            .and_then(|elem| elem.character_data())
517            .and_then(|cdata| cdata.parse_float());
518
519        // note: offer_cyclic_delay is not used in client configuration, so it is always returned as None
520        Some(SdConfig {
521            service_major_version,
522            service_minor_version,
523            ttl,
524            initial_delay_max_value,
525            initial_delay_min_value,
526            initial_repetitions_max,
527            initial_repetitions_base_delay,
528            offer_cyclic_delay: None,
529            request_response_delay_max_value: 0.0,
530            request_response_delay_min_value: 0.0,
531        })
532    }
533}
534
535//##################################################################
536
537/// A `ConsumedEventGroupV1` is a SD event group of a service instance that is consumed by this ECU.
538///
539/// This is the old V1 version of the service definition.
540#[derive(Debug, Clone, PartialEq, Eq, Hash)]
541pub struct ConsumedEventGroupV1(Element);
542
543impl AbstractionElement for ConsumedEventGroupV1 {
544    fn element(&self) -> &Element {
545        &self.0
546    }
547}
548
549impl IdentifiableAbstractionElement for ConsumedEventGroupV1 {}
550
551impl TryFrom<Element> for ConsumedEventGroupV1 {
552    type Error = AutosarAbstractionError;
553
554    fn try_from(element: Element) -> Result<Self, Self::Error> {
555        // hierarchy: ApplicationEndpoint(named) -> ConsumedServiceInstances -> ConsumedServiceInstance(named) -> ConsumedEventGroups -> ConsumedEventGroup(named)
556        let parent_name = element
557            .named_parent()?
558            .and_then(|p| p.named_parent().ok().flatten())
559            .map(|p| p.element_name());
560        if !matches!(parent_name, Some(ElementName::ApplicationEndpoint)) {
561            return Err(AutosarAbstractionError::ConversionError {
562                element,
563                dest: "ConsumedEventGroupV1".to_string(),
564            });
565        }
566
567        if element.element_name() == ElementName::ConsumedEventGroup {
568            Ok(Self(element))
569        } else {
570            Err(AutosarAbstractionError::ConversionError {
571                element,
572                dest: "ConsumedEventGroupV1".to_string(),
573            })
574        }
575    }
576}
577
578impl ConsumedEventGroupV1 {
579    pub(crate) fn new(
580        name: &str,
581        parent: &Element,
582        event_group_identifier: u32,
583        event_handler: &EventHandlerV1,
584    ) -> Result<Self, AutosarAbstractionError> {
585        let ceg_elem = parent.create_named_sub_element(ElementName::ConsumedEventGroup, name)?;
586
587        // go back up the chain to find the ApplicationEndpoint
588        let ae = parent.named_parent()?.unwrap().named_parent()?.unwrap();
589        ceg_elem
590            .create_sub_element(ElementName::ApplicationEndpointRef)?
591            .set_reference_target(&ae)?;
592        let ceg = Self(ceg_elem);
593        event_handler.add_consumed_event_group(&ceg)?;
594
595        ceg.set_event_group_identifier(event_group_identifier)?;
596
597        Ok(ceg)
598    }
599
600    /// iterate over any `EventHandlerV1`s that reference this `ConsumedEventGroupV1`
601    #[must_use]
602    pub fn event_handlers(&self) -> Vec<EventHandlerV1> {
603        let model_result = self.element().model();
604        let path_result = self.element().path();
605        if let (Ok(model), Ok(path)) = (model_result, path_result) {
606            model
607                .get_references_to(&path)
608                .iter()
609                .filter_map(|e| {
610                    e.upgrade()
611                        .and_then(|ref_elem| ref_elem.named_parent().ok().flatten())
612                        .and_then(|elem| EventHandlerV1::try_from(elem).ok())
613                })
614                .collect()
615        } else {
616            vec![]
617        }
618    }
619
620    /// set the `SocketAddress` that receives events from this `ConsumedEventGroup`
621    /// This may be a different `SocketAddress` than the one that is used to send requests.
622    pub fn set_application_endpoint(&self, socket_address: &SocketAddress) -> Result<(), AutosarAbstractionError> {
623        let Some(ae_elem) = socket_address
624            .element()
625            .get_sub_element(ElementName::ApplicationEndpoint)
626        else {
627            return Err(AutosarAbstractionError::InvalidParameter(
628                "SocketAddress does not have an ApplicationEndpoint".to_string(),
629            ));
630        };
631        self.element()
632            .get_or_create_sub_element(ElementName::ApplicationEndpointRef)?
633            .set_reference_target(&ae_elem)?;
634        Ok(())
635    }
636
637    /// get the Socket that receives events from this `ConsumedEventGroup`
638    /// This may be a different Socket than the one that is used to send requests.
639    #[must_use]
640    pub fn application_endpoint(&self) -> Option<SocketAddress> {
641        self.element()
642            .get_sub_element(ElementName::ApplicationEndpointRef)
643            .and_then(|aeref| aeref.get_reference_target().ok())
644            .and_then(|ae: Element| ae.parent().ok().flatten())
645            .and_then(|sa| SocketAddress::try_from(sa).ok())
646    }
647
648    /// set the event group identifier of this `ConsumedEventGroup`
649    pub fn set_event_group_identifier(&self, event_group_identifier: u32) -> Result<(), AutosarAbstractionError> {
650        self.element()
651            .get_or_create_sub_element(ElementName::EventGroupIdentifier)?
652            .set_character_data(u64::from(event_group_identifier))?;
653        Ok(())
654    }
655
656    /// get the event group identifier of this `ConsumedEventGroup`
657    #[must_use]
658    pub fn event_group_identifier(&self) -> Option<u32> {
659        self.0
660            .get_sub_element(ElementName::EventGroupIdentifier)
661            .and_then(|egi| egi.character_data())
662            .and_then(|cdata| cdata.parse_integer())
663    }
664
665    /// add a reference to a `SoAdRoutingGroup` to this `ConsumedEventGroup`
666    pub fn add_routing_group(&self, routing_group: &SoAdRoutingGroup) -> Result<(), AutosarAbstractionError> {
667        let elem = self
668            .element()
669            .get_or_create_sub_element(ElementName::RoutingGroupRefs)?;
670        elem.create_sub_element(ElementName::RoutingGroupRef)?
671            .set_reference_target(routing_group.element())?;
672        Ok(())
673    }
674
675    /// get the routing groups referenced by this `ConsumedEventGroup`
676    pub fn routing_groups(&self) -> impl Iterator<Item = SoAdRoutingGroup> + Send + use<> {
677        self.element()
678            .get_sub_element(ElementName::RoutingGroupRefs)
679            .into_iter()
680            .flat_map(|rgs| rgs.sub_elements())
681            .filter_map(|rgref| rgref.get_reference_target().ok())
682            .filter_map(|rg| SoAdRoutingGroup::try_from(rg).ok())
683    }
684
685    /// set the SD client event configuration for this `ConsumedEventGroup`
686    pub fn set_sd_client_config(&self, sd_client_config: &SdEventConfig) -> Result<(), AutosarAbstractionError> {
687        // remove any existing SdClientConfig, so that we can start fresh
688        let _ = self.element().remove_sub_element_kind(ElementName::SdClientConfig);
689
690        let sd_config_elem = self.element().create_sub_element(ElementName::SdClientConfig)?;
691        sd_config_elem
692            .create_sub_element(ElementName::Ttl)?
693            .set_character_data(u64::from(sd_client_config.ttl))?;
694
695        let req_resp_delay_elem = sd_config_elem.create_sub_element(ElementName::RequestResponseDelay)?;
696        req_resp_delay_elem
697            .create_sub_element(ElementName::MinValue)?
698            .set_character_data(sd_client_config.request_response_delay_min_value)?;
699        req_resp_delay_elem
700            .create_sub_element(ElementName::MaxValue)?
701            .set_character_data(sd_client_config.request_response_delay_max_value)?;
702
703        Ok(())
704    }
705
706    /// get the SD client configuration for this `ConsumedEventGroup`
707    #[must_use]
708    pub fn sd_client_config(&self) -> Option<SdEventConfig> {
709        let config_elem = self.element().get_sub_element(ElementName::SdClientConfig)?;
710        let ttl = config_elem
711            .get_sub_element(ElementName::Ttl)?
712            .character_data()?
713            .parse_integer()?;
714
715        let req_resp_delay_elem = config_elem.get_sub_element(ElementName::RequestResponseDelay)?;
716        let request_response_delay_min_value = req_resp_delay_elem
717            .get_sub_element(ElementName::MinValue)?
718            .character_data()?
719            .parse_float()?;
720        let request_response_delay_max_value = req_resp_delay_elem
721            .get_sub_element(ElementName::MaxValue)?
722            .character_data()?
723            .parse_float()?;
724
725        Some(SdEventConfig {
726            request_response_delay_max_value,
727            request_response_delay_min_value,
728            ttl,
729        })
730    }
731}
732
733//##################################################################
734
735/// SD configuration for a service instance
736///
737/// This struct is used to configure the SD server and client behavior for a service instance.
738/// it is used for the old V1 service definitions.
739#[derive(Debug, Clone, PartialEq)]
740pub struct SdConfig {
741    /// The major version of the service
742    pub service_major_version: u32,
743    /// The minor version of the service
744    pub service_minor_version: u32,
745    /// The maximum delay for the initial offer
746    pub initial_delay_max_value: f64,
747    /// The minimum delay for the initial offer
748    pub initial_delay_min_value: f64,
749    /// The base delay for offer repetitions (if aggregated by `SdServerConfig`) or find repetitions (if aggregated by `SdClientConfig`)
750    pub initial_repetitions_base_delay: Option<f64>,
751    /// The maximum number of repetitions for the initial offer or find
752    pub initial_repetitions_max: u32,
753    /// The delay between two offers (if aggregated by `SdServerConfig`) or finds (if aggregated by `SdClientConfig`)
754    pub offer_cyclic_delay: Option<f64>,
755    /// The maximum delay for a request-response cycle
756    pub request_response_delay_max_value: f64,
757    /// The minimum delay for a request-response cycle
758    pub request_response_delay_min_value: f64,
759    /// The time-to-live for the service offer
760    pub ttl: u32,
761}
762
763/// Configuration for an SD event handler
764#[derive(Debug, Clone, PartialEq)]
765pub struct SdEventConfig {
766    /// The maximum delay for a request-response cycle
767    pub request_response_delay_max_value: f64,
768    /// The minimum delay for a request-response cycle
769    pub request_response_delay_min_value: f64,
770    /// The time-to-live for the service offer
771    pub ttl: u32,
772}
773
774//##################################################################
775
776#[cfg(test)]
777mod test {
778    use super::*;
779    use crate::{
780        AutosarModelAbstraction, System, SystemCategory,
781        communication::{
782            EthernetVlanInfo, EventGroupControlType, NetworkEndpointAddress, SocketAddress, SocketAddressType, TpConfig,
783        },
784    };
785    use autosar_data::AutosarVersion;
786
787    /// helper function to create a test setup with:
788    /// - a system
789    /// - an ethernet cluster
790    ///   - a physical channel
791    ///   - a network endpoint
792    ///   - a socket address
793    fn helper_create_test_objects(model: &AutosarModelAbstraction) -> SocketAddress {
794        let package = model.get_or_create_package("/ethernet").unwrap();
795        let system = package.create_system("system", SystemCategory::EcuExtract).unwrap();
796        let cluster = system.create_ethernet_cluster("ethcluster", &package).unwrap();
797        let channel = cluster
798            .create_physical_channel(
799                "channel",
800                Some(&EthernetVlanInfo {
801                    vlan_name: "VLAN_02".to_string(),
802                    vlan_id: 2,
803                }),
804            )
805            .unwrap();
806        let network_endpoint_address = NetworkEndpointAddress::IPv4 {
807            address: Some("192.168.2.222".to_string()),
808            address_source: None,
809            default_gateway: None,
810            network_mask: None,
811        };
812        let network_endpoint = channel
813            .create_network_endpoint("endpoint", network_endpoint_address, None)
814            .unwrap();
815        let tp_config = TpConfig::UdpTp {
816            port_number: Some(1234),
817            port_dynamically_assigned: None,
818        };
819        channel
820            .create_socket_address(
821                "socket",
822                &network_endpoint,
823                &tp_config,
824                SocketAddressType::Unicast(None),
825            )
826            .unwrap()
827    }
828
829    #[test]
830    fn someip_v1() {
831        let model = AutosarModelAbstraction::create("file.arxml", AutosarVersion::Autosar_00047);
832        let package = model.get_or_create_package("/ethernet").unwrap();
833
834        let socket_address = helper_create_test_objects(&model);
835        let system = System::try_from(model.get_element_by_path("/ethernet/system").unwrap()).unwrap();
836        let psi = socket_address
837            .create_provided_service_instance("provided_service", 0x1234, 0x5678)
838            .unwrap();
839        assert_eq!(psi.service_identifier(), Some(0x1234));
840        assert_eq!(psi.instance_identifier(), Some(0x5678));
841
842        psi.set_sd_server_config(&SdConfig {
843            service_major_version: 1,
844            service_minor_version: 2,
845            initial_delay_max_value: 0.0,
846            initial_delay_min_value: 0.0,
847            initial_repetitions_base_delay: Some(11.1),
848            initial_repetitions_max: 0,
849            offer_cyclic_delay: Some(0.999),
850            request_response_delay_max_value: 0.0,
851            request_response_delay_min_value: 0.0,
852            ttl: 22,
853        })
854        .unwrap();
855        assert_eq!(psi.sd_server_config().unwrap().ttl, 22);
856        assert_eq!(psi.sd_server_config().unwrap().service_major_version, 1);
857        assert_eq!(psi.sd_server_config().unwrap().service_minor_version, 2);
858        assert_eq!(psi.sd_server_config().unwrap().initial_delay_max_value, 0.0);
859        assert_eq!(psi.sd_server_config().unwrap().initial_delay_min_value, 0.0);
860        assert_eq!(
861            psi.sd_server_config().unwrap().initial_repetitions_base_delay,
862            Some(11.1)
863        );
864        assert_eq!(psi.sd_server_config().unwrap().initial_repetitions_max, 0);
865        assert_eq!(psi.sd_server_config().unwrap().offer_cyclic_delay, Some(0.999));
866        assert_eq!(psi.sd_server_config().unwrap().request_response_delay_max_value, 0.0);
867        assert_eq!(psi.sd_server_config().unwrap().request_response_delay_min_value, 0.0);
868        assert_eq!(psi.sd_server_config().unwrap().ttl, 22);
869
870        assert_eq!(psi.event_handlers().count(), 0);
871        let eh = psi.create_event_handler("event").unwrap();
872        assert_eq!(psi.event_handlers().count(), 1);
873        let config = SdEventConfig {
874            request_response_delay_max_value: 0.99,
875            request_response_delay_min_value: 0.0,
876            ttl: 22,
877        };
878        eh.set_sd_server_config(&config).unwrap();
879        assert_eq!(eh.sd_server_config().unwrap().ttl, 22);
880        assert_eq!(eh.sd_server_config().unwrap().request_response_delay_max_value, 0.99);
881        assert_eq!(eh.sd_server_config().unwrap().request_response_delay_min_value, 0.0);
882
883        let rg = system
884            .create_so_ad_routing_group(
885                "routing_group",
886                &package,
887                Some(EventGroupControlType::ActivationMulticast),
888            )
889            .unwrap();
890        eh.add_routing_group(&rg).unwrap();
891        assert_eq!(eh.routing_groups().count(), 1);
892        assert_eq!(eh.routing_groups().next().unwrap(), rg);
893        assert_eq!(eh.consumed_event_groups().count(), 0);
894
895        let csi = socket_address
896            .create_consumed_service_instance("consumed_service", &psi)
897            .unwrap();
898        assert_eq!(csi.provided_service_instance().unwrap(), psi);
899        csi.set_sd_client_config(&SdConfig {
900            service_major_version: 1,
901            service_minor_version: 2,
902            initial_delay_max_value: 0.0,
903            initial_delay_min_value: 0.0,
904            initial_repetitions_base_delay: Some(0.42),
905            initial_repetitions_max: 0,
906            offer_cyclic_delay: None,
907            request_response_delay_max_value: 0.0,
908            request_response_delay_min_value: 0.0,
909            ttl: 22,
910        })
911        .unwrap();
912        assert_eq!(csi.sd_client_config().unwrap().ttl, 22);
913        assert_eq!(csi.sd_client_config().unwrap().service_major_version, 1);
914        assert_eq!(csi.sd_client_config().unwrap().service_minor_version, 2);
915        assert_eq!(csi.sd_client_config().unwrap().initial_delay_max_value, 0.0);
916        assert_eq!(csi.sd_client_config().unwrap().initial_delay_min_value, 0.0);
917        assert_eq!(
918            csi.sd_client_config().unwrap().initial_repetitions_base_delay,
919            Some(0.42)
920        );
921        assert_eq!(csi.sd_client_config().unwrap().initial_repetitions_max, 0);
922        assert_eq!(csi.sd_client_config().unwrap().request_response_delay_max_value, 0.0);
923        assert_eq!(csi.sd_client_config().unwrap().request_response_delay_min_value, 0.0);
924        assert_eq!(csi.sd_client_config().unwrap().ttl, 22);
925
926        assert_eq!(csi.consumed_event_groups().count(), 0);
927        let ceg = csi.create_consumed_event_group("consumed_event", 0x1234, &eh).unwrap();
928        assert_eq!(csi.consumed_event_groups().count(), 1);
929        assert_eq!(csi.consumed_event_groups().next().unwrap(), ceg);
930        assert_eq!(ceg.event_group_identifier(), Some(0x1234));
931        // when the consumed event group is created, it is automatically added to the event handler
932        assert_eq!(eh.consumed_event_groups().count(), 1);
933
934        let config = SdEventConfig {
935            request_response_delay_max_value: 0.99,
936            request_response_delay_min_value: 0.0,
937            ttl: 22,
938        };
939        ceg.set_sd_client_config(&config).unwrap();
940        assert_eq!(ceg.sd_client_config().unwrap().ttl, 22);
941        assert_eq!(ceg.sd_client_config().unwrap().request_response_delay_max_value, 0.99);
942        assert_eq!(ceg.sd_client_config().unwrap().request_response_delay_min_value, 0.0);
943
944        assert_eq!(ceg.application_endpoint().unwrap(), socket_address);
945        ceg.set_application_endpoint(&socket_address).unwrap();
946        assert_eq!(ceg.application_endpoint().unwrap(), socket_address);
947
948        ceg.add_routing_group(&rg).unwrap();
949        assert_eq!(ceg.routing_groups().count(), 1);
950        assert_eq!(ceg.routing_groups().next().unwrap(), rg);
951        assert_eq!(ceg.event_handlers().len(), 1);
952        assert_eq!(ceg.event_handlers()[0], eh);
953    }
954
955    #[test]
956    fn element_conversion() {
957        let model = AutosarModelAbstraction::create("file.arxml", AutosarVersion::Autosar_00047);
958
959        let socket_address = helper_create_test_objects(&model);
960        let psi = socket_address
961            .create_provided_service_instance("provided_service", 0x1234, 0x5678)
962            .unwrap();
963        let eh = psi.create_event_handler("event").unwrap();
964
965        let csi = socket_address
966            .create_consumed_service_instance("consumed_service", &psi)
967            .unwrap();
968        let ceg = csi.create_consumed_event_group("consumed_event", 0x1234, &eh).unwrap();
969
970        let psi2 = ProvidedServiceInstanceV1::try_from(psi.element().clone()).unwrap();
971        assert_eq!(psi2, psi);
972
973        let eh2 = EventHandlerV1::try_from(eh.element().clone()).unwrap();
974        assert_eq!(eh2, eh);
975
976        let csi2 = ConsumedServiceInstanceV1::try_from(csi.element().clone()).unwrap();
977        assert_eq!(csi2, csi);
978
979        let ceg2 = ConsumedEventGroupV1::try_from(ceg.element().clone()).unwrap();
980        assert_eq!(ceg2, ceg);
981    }
982}