1use crate::common::iff::model::{
2 ChangeOptionsRecord, DamageStatus, DapSource, DapValue, EnabledStatus, EnhancedMode1Code,
3 FundamentalOperationalData, Iff, IffDataRecord, IffDataSpecification,
4 IffFundamentalParameterData, IffLayer2, IffLayer3, IffLayer4, IffLayer5, IffPresence,
5 InformationLayers, LatLonAltSource, LayerHeader, LayersPresenceApplicability,
6 MalfunctionStatus, Mode5BasicData, Mode5InterrogatorBasicData, Mode5InterrogatorStatus,
7 Mode5MessageFormats, Mode5TransponderBasicData, Mode5TransponderStatus,
8 Mode5TransponderSupplementalData, ModeSAltitude, ModeSBasicData, ModeSInterrogatorBasicData,
9 ModeSInterrogatorStatus, ModeSLevelsPresent, ModeSTransponderBasicData, ModeSTransponderStatus,
10 OnOffStatus, OperationalStatus, ParameterCapable, SquitterStatus, SystemId, SystemSpecificData,
11 SystemStatus, BASE_IFF_DATA_RECORD_LENGTH_OCTETS,
12};
13use crate::common::model::PduBody;
14use crate::common::parser::{beam_data, entity_id, event_id, simulation_address, vec3_f32};
15use crate::common::DisError;
16use crate::constants::EIGHT_OCTETS;
17use crate::enumerations::{
18 AircraftIdentificationType, AircraftPresentDomain, CapabilityReport, DataCategory,
19 IffApplicableModes, IffSystemMode, IffSystemName, IffSystemType, NavigationSource,
20 VariableRecordType,
21};
22use nom::bytes::complete::take;
23use nom::multi::count;
24use nom::number::complete::{be_f32, be_u16, be_u32, be_u8};
25use nom::IResult;
26
27pub(crate) fn iff_body(input: &[u8]) -> IResult<&[u8], PduBody> {
28 let (input, entity_id) = entity_id(input)?;
29 let (input, event_id) = event_id(input)?;
30 let (input, antenna_location) = vec3_f32(input)?;
31 let (input, system_id) = system_id(input)?;
32 let (input, system_designator) = be_u8(input)?;
33 let (input, system_specific_data) = be_u8(input)?;
34 let (input, fundamental_data) = fundamental_operational_data(input)?;
35
36 let builder = Iff::builder();
37
38 let (input, builder) = if fundamental_data.information_layers.layer_2
39 == LayersPresenceApplicability::PresentApplicable
40 {
41 let (input, layer_2) = iff_layer_2(input)?;
42 (input, builder.with_layer_2(layer_2))
43 } else {
44 (input, builder)
45 };
46 let (input, builder) = if fundamental_data.information_layers.layer_3
47 == LayersPresenceApplicability::PresentApplicable
48 {
49 let (input, layer_3) = iff_layer_3(&system_id.system_type)(input)?;
50 (input, builder.with_layer_3(layer_3))
51 } else {
52 (input, builder)
53 };
54 let (input, builder) = if fundamental_data.information_layers.layer_4
55 == LayersPresenceApplicability::PresentApplicable
56 {
57 let (input, layer_4) = iff_layer_4(&system_id.system_type)(input)?;
58 (input, builder.with_layer_4(layer_4))
59 } else {
60 (input, builder)
61 };
62 let (input, builder) = if fundamental_data.information_layers.layer_5
63 == LayersPresenceApplicability::PresentApplicable
64 {
65 let (input, layer_5) = iff_layer_5(input)?;
66 (input, builder.with_layer_5(layer_5))
67 } else {
68 (input, builder)
69 };
70
71 let builder = builder
72 .with_emitting_entity_id(entity_id)
73 .with_event_id(event_id)
74 .with_relative_antenna_location(antenna_location)
75 .with_system_id(system_id)
76 .with_system_designator(system_designator)
77 .with_system_specific_data(system_specific_data)
78 .with_fundamental_operational_data(fundamental_data);
79
80 Ok((input, builder.build().into_pdu_body()))
81}
82
83fn iff_layer_2(input: &[u8]) -> IResult<&[u8], IffLayer2> {
84 let (input, layer_header) = layer_header(input)?;
85 let (input, beam_data) = beam_data(input)?;
86 let (input, operational_parameter_1) = be_u8(input)?;
87 let (input, operational_parameter_2) = be_u8(input)?;
88 let (input, num_params) = be_u16(input)?;
89 let (input, fundamental_parameters) =
90 count(iff_fundamental_parameter_data, num_params.into())(input)?;
91
92 Ok((
93 input,
94 IffLayer2::builder()
95 .with_header(layer_header)
96 .with_beam_data(beam_data)
97 .with_operational_parameter_1(operational_parameter_1)
98 .with_operational_parameter_2(operational_parameter_2)
99 .with_iff_fundamental_parameters(fundamental_parameters)
100 .build(),
101 ))
102}
103
104fn iff_layer_3(system_type: &IffSystemType) -> impl Fn(&[u8]) -> IResult<&[u8], IffLayer3> + '_ {
105 move |input: &[u8]| {
106 let (input, layer_header) = layer_header(input)?;
107 let (input, reporting_simulation) = simulation_address(input)?;
108 let (input, basic_data) = mode_5_basic_data(system_type)(input)?;
109 let (input, _padding) = be_u16(input)?;
110 let (input, data_specification) = iff_data_specification(input)?;
111
112 Ok((
113 input,
114 IffLayer3::builder()
115 .with_header(layer_header)
116 .with_reporting_simulation(reporting_simulation)
117 .with_mode_5_basic_data(basic_data.unwrap_or(Mode5BasicData::new_transponder(
119 Mode5TransponderBasicData::default(),
120 )))
121 .with_iff_data_specification(data_specification)
122 .build(),
123 ))
124 }
125}
126
127fn iff_layer_4(system_type: &IffSystemType) -> impl Fn(&[u8]) -> IResult<&[u8], IffLayer4> + '_ {
128 move |input: &[u8]| {
129 let (input, layer_header) = layer_header(input)?;
130 let (input, reporting_simulation) = simulation_address(input)?;
131 let (input, basic_data) = mode_s_basic_data(system_type)(input)?;
132 let (input, _padding) = be_u16(input)?;
133 let (input, data_specification) = iff_data_specification(input)?;
134
135 Ok((
136 input,
137 IffLayer4::builder()
138 .with_header(layer_header)
139 .with_reporting_simulation(reporting_simulation)
140 .with_mode_s_basic_data(basic_data.unwrap_or(ModeSBasicData::Transponder(
142 ModeSTransponderBasicData::default(),
143 )))
144 .with_iff_data_specification(data_specification)
145 .build(),
146 ))
147 }
148}
149
150fn iff_layer_5(input: &[u8]) -> IResult<&[u8], IffLayer5> {
151 let (input, layer_header) = layer_header(input)?;
152 let (input, reporting_simulation) = simulation_address(input)?;
153 let (input, _padding) = be_u16(input)?;
154 let (input, applicable_layers) = information_layers(input)?;
155 let (input, data_category) = be_u8(input)?;
156 let data_category = DataCategory::from(data_category);
157 let (input, _padding) = be_u16(input)?;
158 let (input, data_specification) = iff_data_specification(input)?;
159
160 Ok((
161 input,
162 IffLayer5::builder()
163 .with_header(layer_header)
164 .with_reporting_simulation(reporting_simulation)
165 .with_applicable_layers(applicable_layers)
166 .with_data_category(data_category)
167 .with_iff_data_specification(data_specification)
168 .build(),
169 ))
170}
171
172fn change_options_record(input: &[u8]) -> IResult<&[u8], ChangeOptionsRecord> {
173 let (input, record) = be_u8(input)?;
174
175 Ok((input, ChangeOptionsRecord::from(record)))
176}
177
178fn fundamental_operational_data(input: &[u8]) -> IResult<&[u8], FundamentalOperationalData> {
179 let (input, system_status) = system_status(input)?;
180 let (input, data_field_1) = be_u8(input)?;
181 let (input, information_layers) = information_layers(input)?;
182 let (input, data_field_2) = be_u8(input)?;
183 let (input, parameter_1) = be_u16(input)?;
184 let (input, parameter_2) = be_u16(input)?;
185 let (input, parameter_3) = be_u16(input)?;
186 let (input, parameter_4) = be_u16(input)?;
187 let (input, parameter_5) = be_u16(input)?;
188 let (input, parameter_6) = be_u16(input)?;
189
190 Ok((
191 input,
192 FundamentalOperationalData::builder()
193 .with_system_status(system_status)
194 .with_data_field_1(data_field_1)
195 .with_information_layers(information_layers)
196 .with_data_field_2(data_field_2)
197 .with_parameter_1(parameter_1)
198 .with_parameter_2(parameter_2)
199 .with_parameter_3(parameter_3)
200 .with_parameter_4(parameter_4)
201 .with_parameter_5(parameter_5)
202 .with_parameter_6(parameter_6)
203 .build(),
204 ))
205}
206
207fn iff_data_record(input: &[u8]) -> IResult<&[u8], IffDataRecord> {
208 let (input, record_type) = be_u32(input)?;
209 let record_type = VariableRecordType::from(record_type);
210 let (input, record_length) = be_u16(input)?;
211 let (input, field) =
212 take(record_length.saturating_sub(BASE_IFF_DATA_RECORD_LENGTH_OCTETS))(input)?;
213
214 Ok((
215 input,
216 IffDataRecord::builder()
217 .with_record_type(record_type)
218 .with_record_specific_field(field.to_vec())
219 .build(),
220 ))
221}
222
223fn iff_data_specification(input: &[u8]) -> IResult<&[u8], IffDataSpecification> {
224 let (input, num_records) = be_u16(input)?;
225 let (input, records) = count(iff_data_record, num_records.into())(input)?;
226
227 Ok((
228 input,
229 IffDataSpecification::builder()
230 .with_iff_data_records(records)
231 .build(),
232 ))
233}
234
235fn information_layers(input: &[u8]) -> IResult<&[u8], InformationLayers> {
236 let (input, record) = be_u8(input)?;
237
238 Ok((input, InformationLayers::from(record)))
239}
240
241fn iff_fundamental_parameter_data(input: &[u8]) -> IResult<&[u8], IffFundamentalParameterData> {
242 let (input, erp) = be_f32(input)?;
243 let (input, frequency) = be_f32(input)?;
244 let (input, pgrf) = be_f32(input)?;
245 let (input, pulse_width) = be_f32(input)?;
246 let (input, burst_length) = be_f32(input)?;
247 let (input, applicable_modes) = be_u8(input)?;
248 let applicable_modes = IffApplicableModes::from(applicable_modes);
249 let (input, system_specific_data) = system_specific_data(input)?;
250
251 Ok((
252 input,
253 IffFundamentalParameterData::builder()
254 .with_erp(erp)
255 .with_frequency(frequency)
256 .with_pgrf(pgrf)
257 .with_pulse_width(pulse_width)
258 .with_burst_length(burst_length)
259 .with_applicable_modes(applicable_modes)
260 .with_system_specific_data(system_specific_data)
261 .build(),
262 ))
263}
264
265fn layer_header(input: &[u8]) -> IResult<&[u8], LayerHeader> {
266 let (input, layer_number) = be_u8(input)?;
267 let (input, layer_specific_information) = be_u8(input)?;
268 let (input, length) = be_u16(input)?;
269
270 Ok((
271 input,
272 LayerHeader::builder()
273 .with_layer_number(layer_number)
274 .with_layer_specific_information(layer_specific_information)
275 .with_length(length)
276 .build(),
277 ))
278}
279
280fn system_specific_data(input: &[u8]) -> IResult<&[u8], SystemSpecificData> {
281 let (input, part_1) = be_u8(input)?;
282 let (input, part_2) = be_u8(input)?;
283 let (input, part_3) = be_u8(input)?;
284
285 Ok((
286 input,
287 SystemSpecificData::builder()
288 .with_part_1(part_1)
289 .with_part_2(part_2)
290 .with_part_3(part_3)
291 .build(),
292 ))
293}
294
295fn system_id(input: &[u8]) -> IResult<&[u8], SystemId> {
296 let (input, system_type) = be_u16(input)?;
297 let system_type = IffSystemType::from(system_type);
298 let (input, system_name) = be_u16(input)?;
299 let system_name = IffSystemName::from(system_name);
300 let (input, system_mode) = be_u8(input)?;
301 let system_mode = IffSystemMode::from(system_mode);
302 let (input, change_options_record) = change_options_record(input)?;
303
304 Ok((
305 input,
306 SystemId::builder()
307 .with_system_type(system_type)
308 .with_system_name(system_name)
309 .with_system_mode(system_mode)
310 .with_change_options(change_options_record)
311 .build(),
312 ))
313}
314
315fn dap_source(input: &[u8]) -> IResult<&[u8], DapSource> {
316 let (input, record) = be_u8(input)?;
317
318 Ok((input, DapSource::from(record)))
319}
320
321impl From<u8> for DapValue {
322 fn from(value: u8) -> Self {
323 match value {
324 0 => DapValue::ComputeLocally,
325 _ => DapValue::DataRecordAvailable,
326 }
327 }
328}
329
330fn enhanced_mode_1_code(input: &[u8]) -> IResult<&[u8], EnhancedMode1Code> {
331 let (input, record) = be_u16(input)?;
332
333 Ok((input, EnhancedMode1Code::from(record)))
334}
335
336fn system_status(input: &[u8]) -> IResult<&[u8], SystemStatus> {
337 let (input, record) = be_u8(input)?;
338
339 Ok((input, SystemStatus::from(record)))
340}
341
342#[allow(clippy::match_same_arms)]
344fn mode_5_basic_data(
345 system_type: &IffSystemType,
346) -> impl Fn(&[u8]) -> IResult<&[u8], Result<Mode5BasicData, DisError>> + '_ {
347 move |input: &[u8]| match system_type {
348 IffSystemType::MarkXXIIATCRBSTransponder
349 | IffSystemType::SovietTransponder
350 | IffSystemType::RRBTransponder
351 | IffSystemType::MarkXIIATransponder
352 | IffSystemType::Mode5Transponder
353 | IffSystemType::ModeSTransponder => {
354 let (input, basic_data) = mode_5_transponder_basic_data(input)?;
355 Ok((input, Ok(Mode5BasicData::Transponder(basic_data))))
356 }
357 IffSystemType::MarkXXIIATCRBSInterrogator
358 | IffSystemType::SovietInterrogator
359 | IffSystemType::MarkXIIAInterrogator
360 | IffSystemType::Mode5Interrogator
361 | IffSystemType::ModeSInterrogator => {
362 let (input, basic_data) = mode_5_interrogator_basic_data(input)?;
363 Ok((input, Ok(Mode5BasicData::Interrogator(basic_data))))
364 }
365 IffSystemType::MarkXIIACombinedInterrogatorTransponder_CIT_
366 | IffSystemType::MarkXIICombinedInterrogatorTransponder_CIT_
367 | IffSystemType::TCASACASTransceiver => {
368 Ok((input, Err(DisError::IffUndeterminedSystemType)))
369 }
370 IffSystemType::NotUsed_InvalidValue_ => Ok((input, Err(DisError::IffIncorrectSystemType))),
371 IffSystemType::Unspecified(_) => Ok((input, Err(DisError::IffIncorrectSystemType))),
372 }
373}
374
375fn mode_5_interrogator_basic_data(input: &[u8]) -> IResult<&[u8], Mode5InterrogatorBasicData> {
376 let (input, status) = mode_5_interrogator_status(input)?;
377 let (input, _padding) = be_u8(input)?;
378 let (input, _padding) = be_u16(input)?;
379 let (input, message_formats) = mode_5_message_formats(input)?;
380 let (input, entity_id) = entity_id(input)?;
381 let (input, _padding) = be_u16(input)?;
382
383 Ok((
384 input,
385 Mode5InterrogatorBasicData::builder()
386 .with_status(status)
387 .with_mode_5_message_formats_present(message_formats)
388 .with_interrogated_entity_id(entity_id)
389 .build(),
390 ))
391}
392
393fn mode_5_interrogator_status(input: &[u8]) -> IResult<&[u8], Mode5InterrogatorStatus> {
394 let (input, record) = be_u8(input)?;
395
396 Ok((input, Mode5InterrogatorStatus::from(record)))
397}
398
399fn mode_5_message_formats(input: &[u8]) -> IResult<&[u8], Mode5MessageFormats> {
400 let (input, record) = be_u32(input)?;
401
402 Ok((input, Mode5MessageFormats::from(record)))
403}
404
405fn mode_5_transponder_basic_data(input: &[u8]) -> IResult<&[u8], Mode5TransponderBasicData> {
406 let (input, status) = mode_5_transponder_status(input)?;
407 let (input, pin) = be_u16(input)?;
408 let (input, message_formats_present) = mode_5_message_formats(input)?;
409 let (input, enhanced_mode_1) = enhanced_mode_1_code(input)?;
410 let (input, national_origin) = be_u16(input)?;
411 let (input, supplemental_data) = mode_5_transponder_supplemental_data(input)?;
412 let (input, navigation_source) = be_u8(input)?;
413 let navigation_source = NavigationSource::from(navigation_source);
414 let (input, figure_of_merit) = be_u8(input)?;
415 let (input, _padding) = be_u8(input)?;
416
417 Ok((
418 input,
419 Mode5TransponderBasicData::builder()
420 .with_status(status)
421 .with_pin(pin)
422 .with_mode_5_message_formats_present(message_formats_present)
423 .with_enhanced_mode_1(enhanced_mode_1)
424 .with_national_origin(national_origin)
425 .with_supplemental_data(supplemental_data)
426 .with_navigation_source(navigation_source)
427 .with_figure_of_merit(figure_of_merit)
428 .build(),
429 ))
430}
431
432fn mode_5_transponder_supplemental_data(
433 input: &[u8],
434) -> IResult<&[u8], Mode5TransponderSupplementalData> {
435 let (input, record) = be_u8(input)?;
436
437 Ok((input, Mode5TransponderSupplementalData::from(record)))
438}
439
440fn mode_5_transponder_status(input: &[u8]) -> IResult<&[u8], Mode5TransponderStatus> {
441 let (input, record) = be_u16(input)?;
442
443 Ok((input, Mode5TransponderStatus::from(record)))
444}
445
446fn mode_s_altitude(input: &[u8]) -> IResult<&[u8], ModeSAltitude> {
447 let (input, record) = be_u16(input)?;
448
449 Ok((input, ModeSAltitude::from(record)))
450}
451
452#[allow(clippy::match_same_arms)]
454fn mode_s_basic_data(
455 system_type: &IffSystemType,
456) -> impl Fn(&[u8]) -> IResult<&[u8], Result<ModeSBasicData, DisError>> + '_ {
457 move |input: &[u8]| match system_type {
458 IffSystemType::MarkXXIIATCRBSTransponder
459 | IffSystemType::SovietTransponder
460 | IffSystemType::RRBTransponder
461 | IffSystemType::MarkXIIATransponder
462 | IffSystemType::Mode5Transponder
463 | IffSystemType::ModeSTransponder => {
464 let (input, basic_data) = mode_s_transponder_basic_data(input)?;
465 Ok((input, Ok(ModeSBasicData::Transponder(basic_data))))
466 }
467 IffSystemType::MarkXXIIATCRBSInterrogator
468 | IffSystemType::SovietInterrogator
469 | IffSystemType::MarkXIIAInterrogator
470 | IffSystemType::Mode5Interrogator
471 | IffSystemType::ModeSInterrogator => {
472 let (input, basic_data) = mode_s_interrogator_basic_data(input)?;
473 Ok((input, Ok(ModeSBasicData::Interrogator(basic_data))))
474 }
475 IffSystemType::MarkXIIACombinedInterrogatorTransponder_CIT_
476 | IffSystemType::MarkXIICombinedInterrogatorTransponder_CIT_
477 | IffSystemType::TCASACASTransceiver => {
478 Ok((input, Err(DisError::IffUndeterminedSystemType)))
479 }
480 IffSystemType::NotUsed_InvalidValue_ => Ok((input, Err(DisError::IffIncorrectSystemType))),
481 IffSystemType::Unspecified(_) => Ok((input, Err(DisError::IffIncorrectSystemType))),
482 }
483}
484
485fn mode_s_interrogator_basic_data(input: &[u8]) -> IResult<&[u8], ModeSInterrogatorBasicData> {
486 const PAD_168_BITS_IN_OCTETS: usize = 21;
487
488 let (input, status) = mode_s_interrogator_status(input)?;
489 let (input, _padding_1_octet) = be_u8(input)?;
490 let (input, levels_present) = mode_s_levels_present(input)?;
491 let (input, _padding_21_octets) = take(PAD_168_BITS_IN_OCTETS)(input)?;
492
493 Ok((
494 input,
495 ModeSInterrogatorBasicData::builder()
496 .with_mode_s_interrogator_status(status)
497 .with_mode_s_levels_present(levels_present)
498 .build(),
499 ))
500}
501
502fn mode_s_interrogator_status(input: &[u8]) -> IResult<&[u8], ModeSInterrogatorStatus> {
503 let (input, record) = be_u8(input)?;
504
505 Ok((input, ModeSInterrogatorStatus::from(record)))
506}
507
508fn mode_s_levels_present(input: &[u8]) -> IResult<&[u8], ModeSLevelsPresent> {
509 let (input, record) = be_u8(input)?;
510
511 Ok((input, ModeSLevelsPresent::from(record)))
512}
513
514fn mode_s_transponder_basic_data(input: &[u8]) -> IResult<&[u8], ModeSTransponderBasicData> {
515 let (input, status) = mode_s_transponder_status(input)?;
516 let (input, levels_present) = mode_s_levels_present(input)?;
517 let (input, aircraft_present_domain) = be_u8(input)?;
518 let aircraft_present_domain = AircraftPresentDomain::from(aircraft_present_domain);
519
520 let mut buf: [u8; EIGHT_OCTETS] = [0; EIGHT_OCTETS];
521 let (input, ()) = nom::multi::fill(be_u8, &mut buf)(input)?;
522
523 let mut aircraft_id = String::from_utf8_lossy(&buf[..]).into_owned();
524 aircraft_id.truncate(
525 aircraft_id
526 .trim_end()
527 .trim_end_matches(|c: char| !c.is_alphanumeric())
528 .len(),
529 );
530
531 let (input, aircraft_address) = be_u32(input)?;
532 let (input, aircraft_identification_type) = be_u8(input)?;
533 let aircraft_identification_type =
534 AircraftIdentificationType::from(aircraft_identification_type);
535 let (input, dap_source) = dap_source(input)?;
536 let (input, altitude) = mode_s_altitude(input)?;
537 let (input, capability_report) = be_u8(input)?;
538 let capability_report = CapabilityReport::from(capability_report);
539
540 Ok((
541 input,
542 ModeSTransponderBasicData::builder()
543 .with_status(status)
544 .with_levels_present(levels_present)
545 .with_aircraft_present_domain(aircraft_present_domain)
546 .with_aircraft_identification(aircraft_id)
547 .with_aircraft_address(aircraft_address)
548 .with_aircraft_identification_type(aircraft_identification_type)
549 .with_dap_source(dap_source)
550 .with_altitude(altitude)
551 .with_capability_report(capability_report)
552 .build(),
553 ))
554}
555
556fn mode_s_transponder_status(input: &[u8]) -> IResult<&[u8], ModeSTransponderStatus> {
557 let (input, record) = be_u16(input)?;
558
559 Ok((input, ModeSTransponderStatus::from(record)))
560}
561
562impl From<u8> for OnOffStatus {
563 fn from(value: u8) -> Self {
564 match value {
565 0 => OnOffStatus::Off,
566 _ => OnOffStatus::On,
567 }
568 }
569}
570
571impl From<u8> for DamageStatus {
572 fn from(value: u8) -> Self {
573 match value {
574 0 => DamageStatus::NoDamage,
575 _ => DamageStatus::Damaged,
576 }
577 }
578}
579
580impl From<u8> for MalfunctionStatus {
581 fn from(value: u8) -> Self {
582 match value {
583 0 => MalfunctionStatus::NoMalfunction,
584 _ => MalfunctionStatus::Malfunction,
585 }
586 }
587}
588
589impl From<u8> for EnabledStatus {
590 fn from(value: u8) -> Self {
591 match value {
592 0 => EnabledStatus::NotEnabled,
593 _ => EnabledStatus::Enabled,
594 }
595 }
596}
597
598impl From<u8> for LatLonAltSource {
599 fn from(value: u8) -> Self {
600 match value {
601 0 => LatLonAltSource::ComputeLocally,
602 _ => LatLonAltSource::TransponderLocationDataRecordPresent,
603 }
604 }
605}
606
607impl From<u8> for IffPresence {
608 fn from(value: u8) -> Self {
609 match value {
610 0 => IffPresence::NotPresent,
611 _ => IffPresence::Present,
612 }
613 }
614}
615
616impl From<u8> for SquitterStatus {
617 fn from(value: u8) -> Self {
618 match value {
619 0 => SquitterStatus::Off,
620 _ => SquitterStatus::On,
621 }
622 }
623}
624
625impl From<u8> for ParameterCapable {
626 fn from(value: u8) -> Self {
627 match value {
628 0 => ParameterCapable::Capable,
629 _ => ParameterCapable::NotCapable,
630 }
631 }
632}
633
634impl From<u8> for OperationalStatus {
635 fn from(value: u8) -> Self {
636 match value {
637 0 => OperationalStatus::Operational,
638 _ => OperationalStatus::SystemFailed,
639 }
640 }
641}
642
643impl From<u8> for LayersPresenceApplicability {
644 fn from(value: u8) -> Self {
645 match value {
646 0 => LayersPresenceApplicability::NotPresentApplicable,
647 _ => LayersPresenceApplicability::PresentApplicable,
648 }
649 }
650}