1
2use bitvec::prelude::*;
3use regex::Regex;
4use std::collections::BTreeMap;
5
6use crate::asterix::message::AsterixMessage;
7use crate::asterix::category::{CategoryIndex, CategoryKey};
8use crate::asterix::uap::providers::Provider;
9use crate::asterix::uap_json::enums::{ConstraintType, DataItemType, DataItemValueType};
10use crate::asterix::uap_json::errors::ParseError;
11use crate::asterix::uap_json::structures::{DataRecord, Edition, FSpecInfo};
12use crate::asterix::category::Category;
13use crate::asterix::uap_json::enums::{AttributeConstraintLimit, AttributeItem, AttributeLsb, AttributeType, AttributeValueType, DataType, DenominatorType, ElementType, ElementValueType, LsbType, Uap};
14use crate::asterix::uap_json::structures::{Attribute, AttributeConstraint, DataItemRule};
15use crate::asterix::Context;
16
17pub fn parse_record(
18 octets: &Vec<u8>,
19 informed_provider: Option<Provider>,
20 informed_edition: Option<Edition>,
21 debugging: bool) -> anyhow::Result<AsterixMessage> {
22
23 let provider = informed_provider.unwrap_or(Provider::Standard);
24 let message_category = octets[0];
25 let context = Context::new()?;
26
27 let cat_idx = match CategoryIndex::from_u8(message_category){
28 Some(c) => c.clone(),
29 None => {
30 return Err(ParseError::CategoryNotFound { category_code: format!("{:03}", message_category) }.into());
31 }
32 };
33
34 let edition = informed_edition.unwrap_or(context.find_newest_edition_for_category(&cat_idx)?);
35 let cat_key = CategoryKey {
36 index: cat_idx,
37 edition: edition,
38 provider: provider
39 };
40
41 let data_record = context.find_definition(cat_key)?;
42 let message = parse_message(&data_record, &octets, debugging)?;
43
44 Ok(message)
45}
46
47pub fn parse_message(data_record: &DataRecord, octets: &Vec<u8>, debugging: bool) -> anyhow::Result<AsterixMessage> {
48 let mut attributes_map = BTreeMap::<String, Attribute>::new();
49 let asterix_context = Context::new()?;
50 let cat_index = match CategoryIndex::from_u8(data_record.number) {
51 Some(c) => c,
52 None => return Err(ParseError::CategoryNotFound { category_code: data_record.number.to_string() }.into())
53 };
54
55 let category_key = CategoryKey {
56 index: cat_index,
57 edition: data_record.edition.clone(),
58 provider: Provider::Standard };
59 let category = get_category(asterix_context, category_key, octets[0])?;
60
61 let mut category_attribute = Attribute::default();
62 category_attribute.name = category.key.index.as_string();
63 category_attribute.description = Some(category.description);
64 attributes_map.insert("message_category".to_string(), category_attribute);
65
66 let octets_self_intormed_length = octets[1] as usize * 256 + octets[2] as usize;
67
68 if octets_self_intormed_length != octets.len() && debugging {
69 println!("======================== WARNING =======================");
78 println!("MESSAGE LENGTH DOES NOT CORRESPOND TO CALCULATED LENGTH!");
79 println!("======================== WARNING =======================");
80 }
81
82 let category_prefix = format!("{}", category.key.index.as_str());
83
84 let mut current_index = 3 as usize;
85 let expected_frns = data_record.catalogue.len() as u8;
86 let fspec_info: FSpecInfo = get_fspec_from_octets(octets, current_index, expected_frns);
87 current_index += fspec_info.len as usize;
88
89
90 let data_items_map = find_present_data_item_definitions(
91 &fspec_info.fspec,
92 &data_record.uap,
93 &data_record.catalogue)?;
94
95 let mut frn_bits = BTreeMap::<u8, BitVec<u8,Msb0>>::new();
96
97 let mut calc_len_current_index = usize::from(current_index);
98 for data_item_entry in &data_items_map {
99 let data_item_length =
100 match &data_item_entry.1.rule {
101 DataItemType::ContextFree { value } => {
102 let primary_field_length = match value {
103 DataItemValueType::Element { rule:_, size } => usize::from(*size),
104 DataItemValueType::Group { items } => {
105 find_group_length_in_bits(items)?
106 },
107 DataItemValueType::Extended { items } => {
108 find_extended_length_in_bits(items, octets, calc_len_current_index)?
109 },
110 DataItemValueType::Repetitive { rep, variation} => {
111 find_repetitive_length_in_bits(rep, variation, octets, calc_len_current_index)?
112 },
113 DataItemValueType::Compound { fspec:_, items } => {
114 find_compound_length_in_bits(items, octets, calc_len_current_index)?
115 },
116 DataItemValueType::Explicit { expl:_ } => 0_usize, };
118
119 primary_field_length
120 },
121 };
122 assert_eq!(0, data_item_length%8);
123
124 let start_octet = calc_len_current_index;
125 let end_octet = start_octet + (data_item_length/8);
126 let bits = octets[start_octet..end_octet].view_bits::<Msb0>().to_bitvec();
127
128 frn_bits.insert(*data_item_entry.0, bits);
130
131 calc_len_current_index += data_item_length/8;
132 }
133
134 attributes_map = find_message_attributes(&category_prefix, &data_items_map, &frn_bits)?;
137
138 let asterix_message: AsterixMessage = AsterixMessage {
139 code: format!("{:03}", &data_record.number),
140 description: data_record.title.clone(),
141 provider: Provider::Standard.to_string(), attributes_map: attributes_map
144 };
145
146 if debugging {
147 describe_fspec(&fspec_info);
148 list_present_data_item_definitions(&data_items_map);
149 describe_message_attributes(asterix_message.attributes_map.clone());
150 }
151 Ok(asterix_message)
152}
153
154
155fn find_group_length_in_bits(items: &Vec<Option<AttributeItem>>) -> anyhow::Result<usize> {
156 let mut len = 0_usize;
157 for item in items {
158 match item {
159 Some(aitem) => {
160 match aitem {
161 AttributeItem::SpareEntry { length, spare:_ } => { len += length; },
162 AttributeItem::AttributeEntry(aentry) => {
163 match &aentry.rule {
164 AttributeType::ContextFree { value } => match value {
165 AttributeValueType::Element { rule: _, size } => { len += usize::from(*size); },
166 _ => { return Err(ParseError::ParserUnforeseenDependecyRelation.into())}
167 },
168 }
169 },
170 }
171 },
172 None => (),
173 }
174 }
175
176 Ok(len)
177}
178
179fn get_fspec_from_octets(octets: &[u8], current_index: usize, expected_frns: u8) -> FSpecInfo {
180 let mut fx = true;
181 let mut frn:u8 = 0;
182 let mut fspec_info = FSpecInfo::default();
183 let mut local_current_index = current_index;
184 fspec_info.len = 1;
185 while fx {
186 let octet = octets[local_current_index];
187 let fx_octet = octet.view_bits::<Msb0>().to_bitvec();
188
189 let mut bit_count = 0;
190 for bit in fx_octet {
191 if bit_count == 7 {
192 fx = bit;
194 if bit {
195 local_current_index += 1;
196 fspec_info.len += 1;
197 }
198 }
199 else {
200 frn += 1;
201 fspec_info.fspec.insert(frn, bit);
202 }
203
204 bit_count += 1;
206 }
207 }
208
209 while frn < expected_frns {
210 frn += 1;
211 fspec_info.fspec.insert(frn, false);
212 }
213
214 fspec_info
219}
220
221
222fn get_fspec_from_bits(data_item_bits: BitVec<u8, Msb0>, frn_consumed_bits: usize, expected_frns: u8) -> FSpecInfo {
223 let mut fx = true;
224 let mut frn:u8 = 0;
225 let mut fspec_info = FSpecInfo::default();
226 let mut local_current_index = frn_consumed_bits;
227 fspec_info.len = 1;
228 while fx {
229 let start_bit = local_current_index.clone();
230 let end_bit = &local_current_index + 8;
231
232 let fx_octet = data_item_bits[start_bit..end_bit].to_bitvec();
233
234 let mut bit_count = 0;
235 for bit in fx_octet {
236 if bit_count == 7 {
237 fx = bit;
239 if bit {
240 local_current_index += 1;
241 fspec_info.len += 1;
242 }
243 }
244 else {
245 frn += 1;
246 fspec_info.fspec.insert(frn, bit);
247 }
248
249 bit_count += 1;
251 }
252 }
253
254 while frn < expected_frns {
255 frn += 1;
256 fspec_info.fspec.insert(frn, false);
257 }
258
259 fspec_info
264}
265
266fn get_category(context:Context, category_key: CategoryKey, category_octet: u8) -> anyhow::Result<Category> {
267 let category: Category = match context.categories.get(&category_key) {
268 Some(c) => c.clone(),
269 None => return Err((ParseError::CategoryNotFound { category_code: category_octet.to_string()}).into())
270 };
271
272 Ok(category.clone())
273}
274
275fn describe_fspec(fspec_info: &FSpecInfo) {
276 println!("FRN configuration: ");
277
278 let mut frnh = String::new();
279 let mut frnx = String::new();
280 let mut frnl: String = String::new();
281 for frn in &fspec_info.fspec {
282 frnh += format!("| {:02}", frn.0).as_str();
283 frnx += format!("| {:2}", if *frn.1 {"X"} else {" "}).as_str();
284 frnl += "+---";
285 }
286 frnl += "+";
287 frnh += "|";
288 frnx += "|";
289
290 println!("{}", frnl);
291 println!("{}", frnh);
292 println!("{}", frnl);
293 println!("{}", frnx);
294 println!("{}", frnl);
295}
296
297fn find_present_data_item_definitions<'a> (
298 fspec: &'a BTreeMap<u8, bool>,
299 uap: &Uap,
300 catalogue: &'a [DataItemRule]) -> anyhow::Result<BTreeMap<u8, &'a DataItemRule>> {
301 let mut data_items_map = BTreeMap::<u8, &DataItemRule>::new();
302 let uap_items = match &uap {
303 Uap::Uap { items } => items,
304 };
305
306 for frn in fspec.into_iter().filter(| x | *x.1 ) {
312 let index = (frn.0 - 1) as usize;
313 let uap_data_item = format!("{}", &uap_items[usize::from(index)]);
314
315 let catalog_entry
316 = catalogue.into_iter()
317 .find(|x| x.name == uap_data_item);
318
319 let data_item_def
320 = match catalog_entry {
321 Some(d) => d,
322 None => { return Err(ParseError::UapDefinitionNotFound { uap_name: uap_data_item}.into()); },
323 };
324
325 data_items_map.insert(*frn.0, data_item_def);
326 }
327
328 Ok(data_items_map)
329}
330
331fn list_present_data_item_definitions(data_items_map: &BTreeMap<u8, &DataItemRule>) {
332 println!();
333 println!("Data items present in the given message");
334 for present_data_item in data_items_map {
335 let p_frn = present_data_item.0;
336 let p_data_item_rule = present_data_item.1;
337 println!("FRN: {:02}: {}, {}", p_frn, p_data_item_rule.name, p_data_item_rule.title );
338 }
339 println!();
340}
341
342fn find_compound_length_in_bits(
343 items: &Vec<Option<AttributeItem>>,
344 octets: &Vec<u8>,
345 calc_len_current_index: usize) -> anyhow::Result<usize> {
346
347 let minimum_expected_frns = 7_u8;
350 let fspec_info: FSpecInfo = get_fspec_from_octets(octets, calc_len_current_index, minimum_expected_frns);
351
352 let mut item_count = 1_u8;
355 let mut items_length = usize::from(fspec_info.len)*8; for item in items {
357 match item {
358 Some(_) => (),
359 None => {
360 item_count += 1;
361 continue;
362 },
363 };
364
365 if fspec_info.fspec[&item_count] == false {
366 item_count += 1;
367 continue;
368 }
369
370 item_count += 1;
371 items_length += find_attribute_item_length_in_bits(item)?
372 }
373
374 Ok(items_length)
375}
376
377fn find_repetitive_length_in_bits(
378 rep: &ElementValueType,
379 variation: &AttributeValueType,
380 octets: &Vec<u8>,
381 calc_len_current_index: usize) -> anyhow::Result<usize> {
382
383 let mut return_size: usize;
389 let mut multiplier: usize = 0;
390 let multiplier_bits: Option<usize>;
391 match rep {
392 ElementValueType::Fx => multiplier_bits = None,
393 ElementValueType::Regular { size } => {
394 let element_len = usize::from(*size);
395 multiplier_bits = Some(element_len);
396 assert_eq!(0, multiplier%8);
397 let start_octet = calc_len_current_index;
398 let end_octet = start_octet + 1; let bitslice = octets[start_octet..end_octet].view_bits::<Msb0>();
400 multiplier = bitslice.load::<usize>();
401 },
402 _ => { return Err(ParseError::ParserUnforeseenDependecyRelation.into())},
403 };
404
405 if multiplier_bits.is_some() {
406 let multiplier_len = multiplier_bits.unwrap(); let repetitive_len =
409 match variation {
410 AttributeValueType::Group { items } => {
411 find_group_length_in_bits(items)?
412 },
413 _ => { return Err(ParseError::ParserUnforeseenDependecyRelation.into())},
414 };
415 return_size = multiplier_len + repetitive_len * multiplier;
416 } else {
417 return_size = 0;
419 let mut local_octet_offset = calc_len_current_index;
420 let mut fx_bit = true;
421 while fx_bit {
422 let fx_octet = octets[local_octet_offset].view_bits::<Msb0>();
423 fx_bit = fx_octet[0];
424 return_size += 8;
425 local_octet_offset += 1;
426 }
427 }
428
429 Ok(return_size)
430}
431
432fn find_extended_length_in_bits(
433 items: &Vec<Option<AttributeItem>>,
434 octets: &Vec<u8>,
435 calc_len_current_index: usize) -> anyhow::Result<usize> {
436 let mut local_current_index = calc_len_current_index;
437 let mut item_len = 0_usize;
438 let mut fx_set = true;
439 for item in items {
440 if !fx_set {
441 break
442 }
443 item_len += find_attribute_item_length_in_bits(&item)?;
444
445 if item_len%8 == 0 {
446 let bits = octets[local_current_index].view_bits::<Msb0>().to_bitvec();
448 if bits[7] == true {
449 local_current_index += 1;
450 } else {
451 fx_set = false;
452 }
453 }
454 }
455
456 Ok(item_len)
457}
458
459fn find_attribute_item_length_in_bits(item: &Option<AttributeItem>) -> anyhow::Result<usize> {
460 let item_length = match item {
461 Some(i) => {
462 let entry_len = match i {
463 AttributeItem::SpareEntry { length, spare } => {
464 if *spare {*length } else { 0_usize }
465 },
466 AttributeItem::AttributeEntry(e) => {
467 let a_len = match &e.rule {
468 AttributeType::ContextFree { value } => {
469 let len = match value {
470 AttributeValueType::Element { rule:_, size } => usize::from(*size),
471 AttributeValueType::Group { items } => find_group_length_in_bits(items)?, _ => { return Err(ParseError::ParserUnforeseenDependecyRelation.into())}
473 };
474
475 len
476 },
477 };
478
479 a_len
480 },
481 };
482
483 entry_len
484 },
485 None => 1_usize };
488
489 Ok(item_length)
490}
491
492fn find_message_attributes(
493 category_prefix: &String,
494 data_items_map: &BTreeMap<u8, &DataItemRule>,
495 frn_bits: &BTreeMap<u8, BitVec<u8, Msb0>>) -> anyhow::Result<BTreeMap<String, Attribute>> {
496 let mut found_attributes = BTreeMap::<String, Attribute>::new();
497 for data_item_entry in data_items_map {
498 let data_item_prefix = format!("I{}", &data_item_entry.1.name);
499 let data_item_bits = frn_bits[data_item_entry.0].to_bitvec();
500 let default_attribute_name:String = get_default_attribute_name(&data_item_entry.1.title);
501 let mut frn_consumed_bits = 0_usize;
502 match &data_item_entry.1.rule {
503 DataItemType::ContextFree { value } => match value {
504 DataItemValueType::Element { rule, size } => {
505 let mut attribute = Attribute::default();
506 attribute.name = format!("{}_{}_{}", *category_prefix, data_item_prefix.as_str() ,
508 data_item_entry.1.title.replace(" ", "_").to_uppercase().as_str());
509 let last_bit = frn_consumed_bits + *size as usize;
510 attribute.bits = data_item_bits[frn_consumed_bits..last_bit].to_bitvec();
511 fill_dataitem_element_attributes(rule, &mut attribute);
513 found_attributes.insert(attribute.name.to_owned(), attribute);
514 },
515 DataItemValueType::Group { items } => {
516 let group_attributes =
517 fill_group_attributes(&category_prefix, &data_item_prefix, items, &mut frn_consumed_bits, data_item_bits)?;
518 for attribute in group_attributes {
519 found_attributes.insert(attribute.name.to_owned(), attribute);
520 }
521 },
522 DataItemValueType::Extended { items } => {
523 let group_attributes =
524 fill_extended_attributes(&category_prefix, &data_item_prefix, items, &mut frn_consumed_bits, data_item_bits)?;
525 for attribute in group_attributes {
526 found_attributes.insert(attribute.name.to_owned(), attribute);
527 }
528 },
529 DataItemValueType::Repetitive { rep, variation } => {
530 let repetitive_attributes =
531 fill_repetitive_attributes(&category_prefix, &data_item_prefix, rep, variation,
532 &mut frn_consumed_bits, data_item_bits, &default_attribute_name)?;
533 for attribute in repetitive_attributes {
534 found_attributes.insert(attribute.name.to_owned(), attribute);
535 }
536 },
537 DataItemValueType::Compound { fspec:_, items } => {
538 let compound_attributes =
539 fill_compound_attributes(&category_prefix, &data_item_prefix, items, &mut frn_consumed_bits, &data_item_bits)?;
540 for attribute in compound_attributes {
541 found_attributes.insert(attribute.name.to_owned(), attribute);
542 }
543 },
544 DataItemValueType::Explicit { expl:_ } => (), },
546 }
547 }
548
549 Ok(found_attributes)
550}
551
552fn get_default_attribute_name(title: &str) -> String {
553 let default_name: String;
556 let temporary_name: String;
557 if title.len() > 30 {
558 let first_space_index = title.find(" ").unwrap_or(30_usize);
559 temporary_name = title[0..first_space_index].to_owned();
560 } else {
561 temporary_name = title.to_owned();
562 }
563
564 let re = Regex::new(r"[^a-zA-Z0-9_]").unwrap();
565 default_name = match re.replace_all(temporary_name.as_str(), "_") {
566 std::borrow::Cow::Borrowed(b) => b.to_owned().to_uppercase(),
567 std::borrow::Cow::Owned(o) => o.to_uppercase(),
568 };
569
570 default_name
571}
572
573
574fn fill_dataitem_element_attributes(
575 rule: &ElementType,
576 attribute: &mut Attribute) {
577 match rule {
578 ElementType::ContextFree { value } => match value {
579 ElementValueType::Fx => (),
580 ElementValueType::Integer { constraints:_, signed:_} => (),
581 ElementValueType::Quantity { constraints, lsb, signed, unit }
582 => {
583 let mut found_constraints = Vec::<AttributeConstraint>::new();
584 for constraint in constraints {
585 let constraint_value = match constraint.value {
586 DataType::Integer { value } => value,
587 };
588 let attribute_constraint = AttributeConstraint {
589 constraint_type: constraint.constraint_type,
590 limit_value: AttributeConstraintLimit::SignedInteger { value: constraint_value }
591 };
592 found_constraints.push(attribute_constraint);
593 }
594 if found_constraints.len() > 0 {
595 attribute.constraints = Some(found_constraints);
596 }
597 attribute.signed = Some(*signed);
598 let lsb =
599 match lsb {
600 LsbType::Integer { value } => AttributeLsb::Integer { value: *value },
601 LsbType::Div { denominator, numerator } => {
602 let num = match numerator {
603 DataType::Integer { value } => *value as f64,
604 };
605 let den = match denominator {
606 DenominatorType::Pow { base, exponent } => {
607 base.powf(*exponent)
608 },
609 };
610 AttributeLsb::Real { value: num/den }
611 },
612 };
613 attribute.lsb = Some(lsb);
614 attribute.unit = Some(unit.to_owned());
615 match &attribute.lsb {
616 Some(l) => {
617 match l {
618 AttributeLsb::Integer { value } => {
619 let mut signed = false;
620 if attribute.signed.is_some() {
621 signed = match attribute.signed {
622 Some(b) => b,
623 None => false,
624 }
625 }
626 if signed {
627 let signed_value = attribute.bits.load::<i32>();
628 attribute.value_type = l.as_ref().to_owned();
629 attribute.stringfied_value = Some(format!("{}", *value * signed_value));
630 } else {
631 let unsigned_value = attribute.bits.load::<u32>();
632 attribute.value_type = l.as_ref().to_owned();
633 attribute.stringfied_value = Some(format!("{}", *value as u64 * unsigned_value as u64));
634 }
635 },
636 AttributeLsb::Real { value } => {
637 let mut signed = false;
638 if attribute.signed.is_some() {
639 signed = match attribute.signed {
640 Some(b) => b,
641 None => false,
642 }
643 }
644 if signed {
645 let attribute_value = attribute.bits.load::<i32>();
646 attribute.value_type = l.as_ref().to_owned();
647 attribute.stringfied_value = Some(format!("{:17.9}", *value * f64::from(attribute_value)));
648 } else {
649 let attribute_value = attribute.bits.load::<u32>();
650 attribute.value_type = l.as_ref().to_owned();
651 attribute.stringfied_value = Some(format!("{:17.9}", *value * f64::from(attribute_value)));
652 }
653 },
654 }
655
656 },
657 None => (),
658 }
659 },
660 ElementValueType::Raw => attribute.value_type = "Raw".to_owned(),
661 ElementValueType::Regular { size:_ } => attribute.value_type = "Regular".to_owned(),
662 ElementValueType::String { variation } => {
663 attribute.value_type = variation.to_string();
664 if attribute.value_type == "StringICAO" {
665 attribute.stringfied_value = convert_bits_to_icao_string(&attribute.bits);
666 }
667 },
668 ElementValueType::Table { values } => {
669 let attribute_value = attribute.bits.load::<u16>();
670 let converted_value = i32::from(attribute_value);
671 for vec_item in values {
672 if converted_value == vec_item.0{
673 attribute.stringfied_value = Some(vec_item.1.clone());
674 }
675 }
676 attribute.value_type = "Tabulated value".to_owned()
677 },
678 },
679 }
680}
681
682fn convert_bits_to_icao_string(bits: &BitVec<u8, Msb0>) -> Option<String> {
683 assert_eq!(0, bits.len()%6);
684 let mut string_icao = String::new();
685 let mut count = 0;
686 while count < bits.len() {
687 let char_bits = bits[count..count+6].to_bitvec();
688 let char_index = convert_bits_to_usize(&char_bits);
689 string_icao.push(crate::asterix::message::MAP_ICAO_CHARACTERS[char_index]);
690 println!("{}",char_index);
691 println!("{}",string_icao);
692 count += 6;
693 }
694
695 Some(string_icao)
696}
697
698fn convert_bits_to_usize(char_bits: &BitVec<u8, Msb0>) -> usize {
699 let mut ret:usize = 0;
700 ret += (if char_bits[0] { 1 } else { 0 }) * 0b100000;
701 ret += (if char_bits[1] { 1 } else { 0 }) * 0b10000;
702 ret += (if char_bits[2] { 1 } else { 0 }) * 0b1000;
703 ret += (if char_bits[3] { 1 } else { 0 }) * 0b100;
704 ret += (if char_bits[4] { 1 } else { 0 }) * 0b10;
705 ret += (if char_bits[5] { 1 } else { 0 }) * 0b1;
706
707 ret
708}
709
710fn fill_group_attributes(
711 category_prefix: &str,
712 data_item_prefix: &str,
713 items: &Vec<Option<AttributeItem>>,
714 frn_consumed_bits: &mut usize,
715 data_item_bits: BitVec<u8, Msb0>) -> anyhow::Result<Vec<Attribute>> {
716 let mut group_attributes = Vec::<Attribute>::new();
717 for item in items {
718 let inner_item = match item {
719 Some(e) => e,
720 None => continue,
721 };
722
723 match inner_item {
724 AttributeItem::SpareEntry { length, spare:_ } => {
725 *frn_consumed_bits += length;
726 continue
727 } ,
728 AttributeItem::AttributeEntry(v) => {
729 let mut attribute = Attribute::default();
730 attribute.name = format!("{}_{}_{}", category_prefix, data_item_prefix, v.name);
731 attribute.title = v.title.to_owned();
732 attribute.description = v.description.to_owned();
733 match &v.rule {
734 AttributeType::ContextFree { value } => match value {
735 AttributeValueType::Element { rule, size } => {
736 let start_bit = *frn_consumed_bits;
737 let last_bit = *frn_consumed_bits + *size as usize;
738 attribute.bits = data_item_bits[start_bit..last_bit].to_bitvec();
739 *frn_consumed_bits = last_bit;
741 fill_dataitem_element_attributes(rule, &mut attribute);
742 },
743 _ => { return Err(ParseError::ParserUnforeseenDependecyRelation.into())}
744 },
745 }
746 group_attributes.push(attribute);
747
748 },
749 };
750 }
751
752 Ok(group_attributes)
753}
754
755fn fill_extended_attributes(
756 category_prefix: &str,
757 data_item_prefix: &str,
758 items: &Vec<Option<AttributeItem>>,
759 frn_consumed_bits: &mut usize,
760 data_item_bits: BitVec<u8, Msb0>) -> anyhow::Result<Vec<Attribute>> {
761 let mut fx_set = true;
762 let mut extended_attributes = Vec::<Attribute>::new();
763 for item in items {
764 if !fx_set {
765 break
766 }
767
768 match item {
769 Some(i) => match i {
770 AttributeItem::SpareEntry { length, spare:_ } => *frn_consumed_bits += *length,
771 AttributeItem::AttributeEntry(a) => {
772 let mut attribute = Attribute::default();
773 attribute.name = format!("{}_{}_{}", category_prefix, data_item_prefix, a.name);
774 attribute.title = a.title.to_owned();
775 attribute.description = a.description.to_owned();
776
777 match &a.rule {
778 AttributeType::ContextFree { value }
779 => match value {
780 AttributeValueType::Element { rule, size } => {
781 let start_bit = *frn_consumed_bits;
782 let last_bit = *frn_consumed_bits + *size as usize;
783 attribute.bits = data_item_bits[start_bit..last_bit].to_bitvec();
784 let bitslice = match data_item_bits.get(start_bit..last_bit) {
785 Some(b) => b,
786 _ => { return Err(ParseError::InvalidElementFieldLength { size: *size as usize }.into())}
787 };
788 let attribute_value = bitslice.load::<u16>();
789 let converted_value = i32::from(attribute_value);
790 *frn_consumed_bits = last_bit;
792 match rule {
793 ElementType::ContextFree { value } => {
794 match value {
795 ElementValueType::Table { values } => {
796 for vec_item in values {
797 if converted_value == vec_item.0{
798 attribute.stringfied_value = Some(vec_item.1.clone());
799 }
800 }
801 attribute.value_type = "Tabulated value".to_owned()
802 },
803 _ => { return Err(ParseError::ParserUnforeseenDependecyRelation.into())}
804 }
805 },
806 }
807 },
808 _ => { return Err(ParseError::ParserUnforeseenDependecyRelation.into())}
809 },
810 }
811
812 extended_attributes.push(attribute);
813 },
814 },
815 None => *frn_consumed_bits += 1,
816 }
817
818 if *frn_consumed_bits%8 == 0 {
819 let _bitstr = data_item_bits.to_string();
821 let fx_bit = data_item_bits[*frn_consumed_bits-1];
822 if !fx_bit {
823 fx_set = false;
824 }
825 }
826 }
827
828 Ok(extended_attributes)
829}
830
831fn fill_repetitive_attributes(
832 category_prefix: &str,
833 data_item_prefix: &str,
834 rep: &ElementValueType,
835 variation: &AttributeValueType,
836 frn_consumed_bits: &mut usize,
837 data_item_bits: BitVec<u8, Msb0>,
838 default_attribute_name: &String) -> anyhow::Result<Vec<Attribute>> {
839
840 let mut repetitive_attributes = Vec::<Attribute>::new();
841
842 let mut _multiplier: usize = 0;
843 let element_len: Option<usize>;
844
845 match rep {
846 ElementValueType::Fx => element_len = None,
847 ElementValueType::Regular { size } => {
848 let definition_size = usize::from(*size);
849 element_len = Some(definition_size);
850 let start_bit = *frn_consumed_bits;
851 let end_bit = start_bit + 8; let multiplier_bit_vec = data_item_bits[start_bit..end_bit].to_bitvec();
853 _multiplier = multiplier_bit_vec.load::<usize>();
854 assert_eq!(0, definition_size%8);
855 *frn_consumed_bits += 8;
856 },
857 _ => { return Err(ParseError::ParserUnforeseenDependecyRelation.into())},
858 };
859
860 let mut group_attributes: Vec<Attribute> = Vec::<Attribute>::new();
861
862 if element_len.is_some() {
863 match variation {
865 AttributeValueType::Group { items } => {
866 group_attributes.extend(
867 fill_group_attributes(category_prefix, data_item_prefix, items, &mut *frn_consumed_bits, data_item_bits)?);
868 },
869 _ => { return Err(ParseError::ParserUnforeseenDependecyRelation.into())},
870 };
871 let unique_group_attributes = ensure_no_repeated_attribute_names(&group_attributes)?;
872 repetitive_attributes.extend( unique_group_attributes);
873 } else {
874 match variation {
876 AttributeValueType::Element { rule, size }=> {
877 let repetitive_element_size = usize::from(*size);
878 match rule {
879 ElementType::ContextFree { value } => match value {
880 ElementValueType::Table { values } => {
881 let mut fx_bit = true; while fx_bit {
883 let mut attribute = Attribute::default();
884 attribute.name = format!("{}_{}_{}", category_prefix, data_item_prefix, default_attribute_name);
885 let start_bit = *frn_consumed_bits;
886 let end_bit = start_bit + repetitive_element_size;
887 let element_bit_vec = data_item_bits[start_bit..end_bit].to_bitvec();
888 *frn_consumed_bits += repetitive_element_size;
889 let element_value = element_bit_vec.load::<u16>();
890 let converted_value = element_value as i32;
891 fx_bit = data_item_bits[*frn_consumed_bits];
892 *frn_consumed_bits += 1;
893 for vec_item in values {
894 if converted_value == vec_item.0{
895 attribute.stringfied_value = Some(vec_item.1.clone());
896 }
897 }
898 attribute.value_type = "Tabulated value".to_owned();
899 repetitive_attributes.push(attribute);
900 }
901
902 },
903 _ => { return Err(ParseError::ParserUnforeseenDependecyRelation.into())},
904 },
905 }
906 },
907 _ => { return Err(ParseError::ParserUnforeseenDependecyRelation.into())},
908 };
909 }
910
911 let unique_group_attributes = ensure_no_repeated_attribute_names(&group_attributes)?;
912 repetitive_attributes.extend( unique_group_attributes);
913
914 Ok(repetitive_attributes)
917}
918
919fn fill_compound_attributes(
920 category_prefix: &str,
921 data_item_prefix: &str,
922 items: &[Option<AttributeItem>],
923 frn_consumed_bits: &mut usize,
924 data_item_bits: &BitVec<u8, Msb0>) -> anyhow::Result<Vec<Attribute>> {
925 let mut compound_attributes = Vec::<Attribute>::new();
926
927 let minimum_expected_frns = 7_u8;
928 let fspec_info: FSpecInfo = get_fspec_from_bits(data_item_bits.clone(), *frn_consumed_bits, minimum_expected_frns);
929
930 *frn_consumed_bits = usize::from(fspec_info.len)*8; let mut item_count = 1_u8;
932 for item in items {
933
934 if fspec_info.fspec[&item_count] == false {
936 item_count += 1;
937 continue;
938 }
939
940 match item {
941 Some(e) => {
942 match e {
943 AttributeItem::SpareEntry { length, spare:_ } => {
944 *frn_consumed_bits += length;
945 continue
946 },
947 AttributeItem::AttributeEntry(v) => {
948 let mut attribute = Attribute::default();
949 attribute.name = format!("{}_{}_{}", category_prefix, data_item_prefix, v.name);
950 attribute.title = v.title.to_owned();
951 attribute.description = v.description.to_owned();
952 match &v.rule {
953 AttributeType::ContextFree { value }
954 => match value {
955 AttributeValueType::Element { rule, size } => {
956 let start_bit = *frn_consumed_bits;
957 let last_bit = *frn_consumed_bits + *size as usize;
958 attribute.bits = data_item_bits[start_bit..last_bit].to_bitvec();
959 *frn_consumed_bits = last_bit;
961 fill_dataitem_element_attributes(rule, &mut attribute);
962 compound_attributes.push(attribute);
963 item_count += 1;
964 },
965 AttributeValueType::Group { items }=> {
966 let compound_grouped_attributes =
968 fill_group_attributes(category_prefix, data_item_prefix, items,
969 frn_consumed_bits, data_item_bits.clone())?;
970 compound_attributes.extend(compound_grouped_attributes);
971 item_count += 1;
972 },
973 _ => { return Err(ParseError::ParserUnforeseenDependecyRelation.into())}
974 },
975 }
976 },
977 }
978 },
979 None => {
980 item_count += 1;
981 continue;
982 },
983 };
984 }
985
986 Ok(compound_attributes)
987}
988
989pub fn describe_message_attributes(message: BTreeMap<String, Attribute>) {
990 for attribute in message {
991 println!();
992 println!("key:[{}], bits length[{:02}] - bits:{}]", attribute.0, attribute.1.bits.len(), attribute.1.bits);
993 print!(" Title: {:?}", attribute.1.title);
994 if attribute.1.description.is_some()
995 {
996 print!(", description{:?}", attribute.1.description);
997 }
998 println!();
999
1000 if attribute.1.signed.is_some() {
1001 println!(" Signed: {}", attribute.1.signed.unwrap());
1002 }
1003
1004 println!(" Type: {}", attribute.1.value_type);
1005
1006 if attribute.1.stringfied_value.is_some() {
1007 println!(" Stringfied value: {}", attribute.1.stringfied_value.unwrap());
1008 }
1009
1010 if attribute.1.unit.is_some() {
1011 println!(" Unit: {}", attribute.1.unit.unwrap());
1012 }
1013
1014 if attribute.1.constraints.is_some() {
1015 match attribute.1.constraints {
1016 Some(c) => {
1017 for constraint in c {
1018 let constraint_str =
1019 match constraint.constraint_type {
1020 ConstraintType::Less => { stringify!(ConstraintType::Less ) },
1021 ConstraintType::Great => { stringify!(ConstraintType::Great ) },
1022 ConstraintType::LessOrEqual => { stringify!(ConstraintType::LessOrEqual ) },
1023 ConstraintType::GreatOrEqual => { stringify!(ConstraintType::GreatOrEqual ) },
1024 };
1025 let constraint_value =
1026 match constraint.limit_value {
1027 AttributeConstraintLimit::SignedInteger { value } => value.to_string(),
1028 };
1029 println!(" Constraint: {} {} ", constraint_str, constraint_value);
1030 }
1031 },
1032 None => (),
1033 }
1034 }
1035 if attribute.1.lsb.is_some() {
1036 match attribute.1.lsb {
1037 Some(e) => {
1038 let lsb_value = match e {
1039 AttributeLsb::Integer { value } => value.to_string(),
1040 AttributeLsb::Real { value } => format!("{:15.7}", value),
1041 };
1042
1043 println!(" LSB: {} ", lsb_value);
1044 },
1045 None => (),
1046 }
1047 }
1048 }
1049}
1050
1051
1052fn ensure_no_repeated_attribute_names(
1060 group_attributes: &Vec<Attribute>) -> anyhow::Result<Vec<Attribute>> {
1061
1062 let mut unique_group_attributes = Vec::<Attribute>::new();
1066 let mut attr_name_vec = Vec::<(String, usize)>::new();
1067
1068 for attr in group_attributes {
1069 let mut new_attr = attr.clone();
1070 match attr_name_vec.clone()
1071 .into_iter()
1072 .find(|x| x.0 == attr.name) {
1073 Some(x_attr) => {
1074 let mut counter = x_attr.1;
1075 counter += 1;
1076 let x = attr_name_vec.iter().position(|x| *x == x_attr);
1077 let index = match x {
1078 Some(i) => i,
1079 None => return Err(ParseError::ParserUnforeseenDependecyRelation.into()),
1081 };
1082 attr_name_vec.remove(index);
1083 new_attr.name = format!("{}_{}", attr.name, counter);
1084 attr_name_vec.push((attr.name.clone(), counter));
1085 unique_group_attributes.push(new_attr);
1086 },
1087 None => {
1088 attr_name_vec.push((attr.name.clone(), 0_usize ));
1089 unique_group_attributes.push(attr.clone());
1090 },
1091 };
1092 }
1093
1094 Ok(unique_group_attributes)
1095}
1096
1097#[cfg(test)]
1098pub mod tests {
1099 use crate::asterix::uap_json::structures::Attribute;
1100
1101 use super::ensure_no_repeated_attribute_names;
1102 #[test]
1103 fn ut_test_repeated_attributs_are_resolved() -> anyhow::Result<()> {
1104 let mut group_attributes = Vec::<crate::asterix::uap_json::structures::Attribute>::new();
1105 let mut attr1 = Attribute::default();
1106 let mut attr2 = Attribute::default();
1107 let mut attr3 = Attribute::default();
1108 let mut attr4 = Attribute::default();
1109
1110 attr1.name = "ATTR".to_owned();
1111 attr2.name = "ATTR".to_owned();
1112 attr3.name = "SOME".to_owned();
1113 attr4.name = "ATTR".to_owned();
1114
1115 group_attributes.push(attr1);
1116 group_attributes.push(attr2);
1117 group_attributes.push(attr3);
1118 group_attributes.push(attr4);
1119
1120 let unique_attributes = ensure_no_repeated_attribute_names(&group_attributes)?;
1121
1122 assert_eq!(4, unique_attributes.len());
1123 assert_eq!("ATTR".to_owned(), unique_attributes[0].name);
1124 assert_eq!("ATTR_1".to_owned(), unique_attributes[1].name);
1125 assert_eq!("SOME".to_owned(), unique_attributes[2].name);
1126 assert_eq!("ATTR_2".to_owned(), unique_attributes[3].name);
1127
1128 Ok(())
1129 }
1130}