1use crate::communication::{SoAdRoutingGroup, SocketAddress};
2use crate::{AbstractionElement, AutosarAbstractionError, IdentifiableAbstractionElement};
3use autosar_data::{Element, ElementName};
4
5#[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 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 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 #[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 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 #[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 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 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 pub fn set_sd_server_config(&self, sd_server_config: &SdConfig) -> Result<(), AutosarAbstractionError> {
112 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 #[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#[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 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 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 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 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 pub fn set_sd_server_config(&self, server_config: &SdEventConfig) -> Result<(), AutosarAbstractionError> {
307 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 #[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 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#[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 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 #[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 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 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 pub fn set_sd_client_config(&self, sd_client_config: &SdConfig) -> Result<(), AutosarAbstractionError> {
450 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 Ok(())
482 }
483
484 #[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 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#[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 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 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 #[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 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 #[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 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 #[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 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 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 pub fn set_sd_client_config(&self, sd_client_config: &SdEventConfig) -> Result<(), AutosarAbstractionError> {
687 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 #[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#[derive(Debug, Clone, PartialEq)]
740pub struct SdConfig {
741 pub service_major_version: u32,
743 pub service_minor_version: u32,
745 pub initial_delay_max_value: f64,
747 pub initial_delay_min_value: f64,
749 pub initial_repetitions_base_delay: Option<f64>,
751 pub initial_repetitions_max: u32,
753 pub offer_cyclic_delay: Option<f64>,
755 pub request_response_delay_max_value: f64,
757 pub request_response_delay_min_value: f64,
759 pub ttl: u32,
761}
762
763#[derive(Debug, Clone, PartialEq)]
765pub struct SdEventConfig {
766 pub request_response_delay_max_value: f64,
768 pub request_response_delay_min_value: f64,
770 pub ttl: u32,
772}
773
774#[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 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 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}