asterix_parser/asterix/message/
parser.rs

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        // todo: check error in message length, currently just informing by printing in console.
70        // Messages comming from recording are presenting more octets that calculated by analysing
71        // the message content.
72        /* return Err(ParseError::BadMessageInformedLength { 
73                informed: octets_self_intormed_length,  
74                current: octets.len()
75            }.into()); */
76
77        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, // to calculate,
117                    };
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        // println!("Found bits for data item [{}], bits{}", data_item_entry.1.name, bits.to_string());
129        frn_bits.insert(*data_item_entry.0, bits);
130
131        calc_len_current_index += data_item_length/8;
132    }
133
134    // assert_eq!(octets_self_intormed_length, calc_len_current_index);
135    // process_items(&attribute_prefix, &mut attributes_map, octets, &mut current_index, &data_items_map);
136    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(), /*
142        data_items_store: todo!(),  */
143        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                // if fx bit is true then we have more data_items to check
193                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            // println!("Bit[{bit_count}]:{bit}");
205            bit_count += 1;
206        }
207    }
208
209    while frn < expected_frns {
210        frn += 1;
211        fspec_info.fspec.insert(frn, false);
212    }
213
214    /* for fspecitem in &fspec_info.fspec {
215        println!("{}: {}", fspecitem.0, fspecitem.1)
216    } */
217
218    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                // if fx bit is true then we have more data_items to check
238                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            // println!("Bit[{bit_count}]:{bit}");
250            bit_count += 1;
251        }
252    }
253
254    while frn < expected_frns {
255        frn += 1;
256        fspec_info.fspec.insert(frn, false);
257    }
258
259    /* for fspecitem in &fspec_info.fspec {
260        println!("{}: {}", fspecitem.0, fspecitem.1)
261    } */
262
263    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    /* let mut data_item_code = match uap_items.first() {
307        Some(c) => c.clone(),
308        None => { return Err(ParseError::UapDefinitionsEmpty.into()); },
309    }; */
310
311    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 mut local_len_current_index = calc_len_current_index;
348
349    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    // describe_fspec(&fspec_info);
353
354    let mut item_count = 1_u8;
355    let mut items_length =  usize::from(fspec_info.len)*8; // 8 bits in an fspec octet;
356    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 multiplier_bits = match rep {
384    //     ElementValueType::Fx => 0_usize,
385    //     ElementValueType::Regular { size } => usize::from(*size),
386    //     _ => { return Err(ParseError::ParserUnforeseenDependecyRelation.into())},
387    // };
388    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; // repetition factor subitem is composed of one octet 
399            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        // Regular style repetition
407        let multiplier_len = multiplier_bits.unwrap(); // todo: is it safe? 
408        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        // Fx style repetition
418        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            // end of octed, will check fx value to continue or not
447            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)?, // to calculate,
472                                _ => { 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 // would be 0_usize, but it happens that in exteded data item, the fx bit is falling into this category, 
486                        // because it is null in .json definition file
487    };
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                        // Direct Element on a dataitem has no name, so we will give one based on the title
507                        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                        // attribute.bits.reverse();
512                        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:_ } => (), // todo: TBD if SP and RE items will be needed
545            },
546        }
547    }
548
549    Ok(found_attributes)
550}
551
552fn get_default_attribute_name(title: &str) -> String {
553    // some attributes will have no name (e.g. Repetitive items) but we need to have a name for
554    // having them in the attributes map. So we will use a portion of title, converted to uppercase
555    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                            // attribute.bits.reverse();
740                            *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                                    // attribute.bits.reverse();
791                                    *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            // end of octed, will check fx value to continue or not
820            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; // One octet representing the multiplier
852            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        // Regular style repetition
864        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        // Fx style repetition
875        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; // first element is mandatory
882                            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    // extended_attributes.push(new_attr);
915
916    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; // 8 bits in an fspec octet;
931    let mut item_count = 1_u8;
932    for item in items {
933        
934        // let strx = format!("{:?}", fspec_info.fspec);
935        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                                        // attribute.bits.reverse();
960                                        *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                                        // attribute.bits.reverse();
967                                        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
1052/// .
1053/// Avoid having attribute name repeated, if the repetition gerenrates it, by adding _{count} suffix
1054/// Repeated attribute names would break the attributes BTreeMap
1055/// 
1056/// # Errors : ParseError::ParserUnforeseenDependecyRelation
1057///
1058/// This function will return an error if .
1059fn ensure_no_repeated_attribute_names(
1060    group_attributes: &Vec<Attribute>) -> anyhow::Result<Vec<Attribute>>  {
1061
1062    // Avoid having attribute name duplicated, if the repetition gerenrates it by adding _{count}
1063    // Duplicate attribute names would break the attributes BTreeMap
1064
1065    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                        // this should never happen as we've found the element with the find command above
1080                    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}