diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/recording/FlightDataRecorder.cpp b/fbw-a32nx/src/wasm/fbw_a320/src/recording/FlightDataRecorder.cpp index a1361d86f34..0f4b68729e8 100644 --- a/fbw-a32nx/src/wasm/fbw_a320/src/recording/FlightDataRecorder.cpp +++ b/fbw-a32nx/src/wasm/fbw_a320/src/recording/FlightDataRecorder.cpp @@ -140,8 +140,9 @@ void FlightDataRecorder::writeConfiguration() { // create structure INIStructure iniStructure; iniStructure["FLIGHT_DATA_RECORDER"]["ENABLED"] = idIsEnabled->get() == 1 ? "true" : "false"; - iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_FILES"] = idMaximumFileCount->get(); - iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE"] = idMaximumSampleCounter->get(); + iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_FILES"] = std::to_string(static_cast(idMaximumFileCount->get())); + iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE"] = + std::to_string(static_cast(idMaximumSampleCounter->get())); // write file iniFile.write(iniStructure, true); diff --git a/fbw-a380x/src/wasm/fbw_a380/src/recording/FlightDataRecorder.cpp b/fbw-a380x/src/wasm/fbw_a380/src/recording/FlightDataRecorder.cpp index 2178045f2d6..ee4c13158c1 100644 --- a/fbw-a380x/src/wasm/fbw_a380/src/recording/FlightDataRecorder.cpp +++ b/fbw-a380x/src/wasm/fbw_a380/src/recording/FlightDataRecorder.cpp @@ -144,8 +144,9 @@ void FlightDataRecorder::writeConfiguration() { // create structure INIStructure iniStructure; iniStructure["FLIGHT_DATA_RECORDER"]["ENABLED"] = idIsEnabled->get() == 1 ? "true" : "false"; - iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_FILES"] = idMaximumFileCount->get(); - iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE"] = idMaximumSampleCounter->get(); + iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_FILES"] = std::to_string(static_cast(idMaximumFileCount->get())); + iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE"] = + std::to_string(static_cast(idMaximumSampleCounter->get())); // write file iniFile.write(iniStructure, true); diff --git a/tools/fdr2csv/a32nx/Cargo.lock b/tools/fdr2csv/Cargo.lock similarity index 96% rename from tools/fdr2csv/a32nx/Cargo.lock rename to tools/fdr2csv/Cargo.lock index 8ed72d478ee..0e746f040e1 100644 --- a/tools/fdr2csv/a32nx/Cargo.lock +++ b/tools/fdr2csv/Cargo.lock @@ -34,9 +34,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" @@ -234,20 +234,7 @@ dependencies = [ ] [[package]] -name = "fdr2csv-a32nx" -version = "0.1.0" -dependencies = [ - "bindgen", - "bytemuck", - "clap", - "csv", - "fdr2csv_common", - "flate2", - "serde", -] - -[[package]] -name = "fdr2csv_common" +name = "fdr2csv" version = "0.1.0" dependencies = [ "bindgen", @@ -471,18 +458,18 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "serde" -version = "1.0.213" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.213" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", @@ -503,9 +490,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.85" +version = "2.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "e89275301d38033efb81a6e60e3497e734dfcc62571f2854bf4b16690398824c" dependencies = [ "proc-macro2", "quote", diff --git a/tools/fdr2csv/common/Cargo.toml b/tools/fdr2csv/Cargo.toml similarity index 94% rename from tools/fdr2csv/common/Cargo.toml rename to tools/fdr2csv/Cargo.toml index 9a1dfd67d30..41d5b9e5e5d 100644 --- a/tools/fdr2csv/common/Cargo.toml +++ b/tools/fdr2csv/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "fdr2csv_common" +name = "fdr2csv" version = "0.1.0" authors = ["FlyByWire Simulations"] edition = "2021" diff --git a/tools/fdr2csv/a320_wrapper.hpp b/tools/fdr2csv/a320_wrapper.hpp new file mode 100644 index 00000000000..c3d2194f52c --- /dev/null +++ b/tools/fdr2csv/a320_wrapper.hpp @@ -0,0 +1,7 @@ +#include "../../fbw-a32nx/src/wasm/fbw_a320/src/model/AutopilotLaws_types.h" +#include "../../fbw-a32nx/src/wasm/fbw_a320/src/model/AutopilotStateMachine_types.h" +#include "../../fbw-a32nx/src/wasm/fbw_a320/src/model/Autothrust_types.h" +#include "../../fbw-a32nx/src/wasm/fbw_a320/src/model/ElacComputer_types.h" +#include "../../fbw-a32nx/src/wasm/fbw_a320/src/model/FacComputer_types.h" +#include "../../fbw-a32nx/src/wasm/fbw_a320/src/model/SecComputer_types.h" +#include "../../fbw-a32nx/src/wasm/fbw_a320/src/recording/RecordingDataTypes.h" \ No newline at end of file diff --git a/tools/fdr2csv/a32nx/Cargo.toml b/tools/fdr2csv/a32nx/Cargo.toml deleted file mode 100644 index 060a04f5a58..00000000000 --- a/tools/fdr2csv/a32nx/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "fdr2csv-a32nx" -version = "0.1.0" -authors = ["FlyByWire Simulations"] -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[build-dependencies] -bindgen = "0.69.5" - -[dependencies] -fdr2csv_common = { path = "../common" } - -clap = { version = "4.5.20", features = ["derive"] } -serde = { version = "1.0.213", features = ["derive"] } -bytemuck = { version = "1.19.0", features = ["derive"] } - -csv = "1.3.0" -flate2 = "1.0.34" - -[workspace] diff --git a/tools/fdr2csv/a32nx/build.rs b/tools/fdr2csv/a32nx/build.rs deleted file mode 100644 index f92c176c95d..00000000000 --- a/tools/fdr2csv/a32nx/build.rs +++ /dev/null @@ -1,45 +0,0 @@ -use std::env; -use std::path::PathBuf; - -use bindgen::callbacks::ParseCallbacks; - -#[derive(Debug)] -struct CustomDeriveCallback {} -impl CustomDeriveCallback { - fn new() -> CustomDeriveCallback { - CustomDeriveCallback {} - } -} -impl ParseCallbacks for CustomDeriveCallback { - fn add_derives(&self, _info: &bindgen::callbacks::DeriveInfo<'_>) -> Vec { - vec!["Serialize".into(), "AnyBitPattern".into(), "Default".into()] - } -} - -fn main() { - // Tell cargo to look for shared libraries in the specified directory - println!("cargo:rustc-link-search=../../fbw-a32nx/src/wasm/fbw_a320/src/model"); - - // The bindgen::Builder is the main entry point - // to bindgen, and lets you build up options for - // the resulting bindings. - let bindings = bindgen::Builder::default() - // The input header we would like to generate - // bindings for. - .header("wrapper.hpp") - .clang_arg("-std=c++20") - // Tell cargo to invalidate the built crate whenever any of the - // included header files changed. - .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) - .parse_callbacks(Box::new(CustomDeriveCallback::new())) - // Finish the builder and generate the bindings. - .generate() - // Unwrap the Result and panic on failure. - .expect("Unable to generate bindings"); - - // Write the bindings to the $OUT_DIR/bindings.rs file. - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - bindings - .write_to_file(out_path.join("bindings.rs")) - .expect("Couldn't write bindings!"); -} diff --git a/tools/fdr2csv/a32nx/src/main.rs b/tools/fdr2csv/a32nx/src/main.rs deleted file mode 100644 index 6ec10e058fa..00000000000 --- a/tools/fdr2csv/a32nx/src/main.rs +++ /dev/null @@ -1,216 +0,0 @@ -use bytemuck::AnyBitPattern; -use clap::Parser; -use csv::WriterBuilder; -use fdr2csv_common::csv_header_serializer; -use flate2::bufread::GzDecoder; -use headers::{ - ap_raw_output, ap_sm_output, athr_out, base_elac_analog_outputs, base_elac_discrete_outputs, - base_elac_out_bus, base_fac_analog_outputs, base_fac_bus, base_fac_discrete_outputs, - base_sec_analog_outputs, base_sec_discrete_outputs, base_sec_out_bus, AircraftSpecificData, - BaseData, -}; -use serde::Serialize; -use std::{ - fs::{File, OpenOptions}, - io::{prelude::*, BufReader, BufWriter, Error, ErrorKind}, - mem, -}; - -mod headers; - -#[derive(Parser, Debug)] -#[command(version, about, long_about = None)] -struct Args { - /// Input file - #[arg(short, long)] - input: String, - /// Output file - #[arg(short, long)] - output: String, - /// Delimiter - #[arg(short, long, default_value = ",")] - delimiter: char, - /// Input file is not compressed - #[arg(short, long, default_value_t = false)] - no_compression: bool, - /// Print struct size - #[arg(short, long, default_value_t = false)] - print_struct_size: bool, - /// Print interface version of input file - #[arg(short, long, default_value_t = false)] - get_input_file_version: bool, -} - -const INTERFACE_VERSION: u64 = 3200001; - -// Read number of bytes specified by the size of T from the binary file -fn read_bytes(reader: &mut impl Read) -> Result { - let size = mem::size_of::(); - - // allocate the buffer that will hold the value read from the binary - let mut buf = vec![0u8; size]; - - // now read from the reader into the buffer - reader.read_exact(&mut buf)?; - - // If the read was successful, reinterpret the bytes as the struct, and return - let res = bytemuck::from_bytes::(buf.as_slice()); - - Ok(*res) -} - -// A single FDR record -#[derive(Serialize, Default)] -struct FdrData { - base: BaseData, - specific: AircraftSpecificData, - elac_1: ElacData, - elac_2: ElacData, - sec_1: SecData, - sec_2: SecData, - sec_3: SecData, - fac_1: FacData, - fac_2: FacData, - ap_sm: ap_sm_output, - ap_law: ap_raw_output, - athr: athr_out, -} - -#[derive(Serialize, Default)] -struct ElacData { - bus_outputs: base_elac_out_bus, - discrete_outputs: base_elac_discrete_outputs, - analog_outputs: base_elac_analog_outputs, -} - -#[derive(Serialize, Default)] -struct SecData { - bus_outputs: base_sec_out_bus, - discrete_outputs: base_sec_discrete_outputs, - analog_outputs: base_sec_analog_outputs, -} - -#[derive(Serialize, Default)] -struct FacData { - bus_outputs: base_fac_bus, - discrete_outputs: base_fac_discrete_outputs, - analog_outputs: base_fac_analog_outputs, -} - -// These are helper functions to read in a whole FDR record. -fn read_record(reader: &mut impl Read) -> Result { - Ok(FdrData { - base: read_bytes::(reader)?, - specific: read_bytes::(reader)?, - elac_1: read_elac(reader)?, - elac_2: read_elac(reader)?, - sec_1: read_sec(reader)?, - sec_2: read_sec(reader)?, - sec_3: read_sec(reader)?, - fac_1: read_fac(reader)?, - fac_2: read_fac(reader)?, - ap_sm: read_bytes::(reader)?, - ap_law: read_bytes::(reader)?, - athr: read_bytes::(reader)?, - }) -} - -fn read_elac(reader: &mut impl Read) -> Result { - Ok(ElacData { - bus_outputs: read_bytes::(reader)?, - discrete_outputs: read_bytes::(reader)?, - analog_outputs: read_bytes::(reader)?, - }) -} - -fn read_sec(reader: &mut impl Read) -> Result { - Ok(SecData { - bus_outputs: read_bytes::(reader)?, - discrete_outputs: read_bytes::(reader)?, - analog_outputs: read_bytes::(reader)?, - }) -} - -fn read_fac(reader: &mut impl Read) -> Result { - Ok(FacData { - bus_outputs: read_bytes::(reader)?, - discrete_outputs: read_bytes::(reader)?, - analog_outputs: read_bytes::(reader)?, - }) -} - -fn main() -> Result<(), std::io::Error> { - // Parse CLI arguments - let args = Args::parse(); - - // Open the input file - let in_file = File::open(args.input.trim()) - .map_err(|e| std::io::Error::new(e.kind(), "Failed to open input file!"))?; - - // Create Gzip Reader - let mut reader: Box = if args.no_compression { - Box::new(BufReader::new(in_file)) - } else { - Box::new(GzDecoder::new(BufReader::new(in_file))) - }; - - // Read file version - let file_format_version = read_bytes::(&mut reader)?; - - // Print or check file version - if args.get_input_file_version { - println!("Interface version is {}", file_format_version); - return Ok(()); - } else if INTERFACE_VERSION != file_format_version { - return Err(std::io::Error::new( - ErrorKind::InvalidInput, - format!( - "Mismatch between converter and file version (expected {INTERFACE_VERSION}, got {file_format_version})", - ), - )); - } - - // Print info on conversion start - println!( - "Converting from '{}' to '{}' with interface version '{}' and delimiter '{}'", - args.input, args.output, file_format_version, args.delimiter - ); - - // Open or create output file in truncate mode - let out_file = OpenOptions::new() - .write(true) - .truncate(true) - .create(true) - .open(args.output.trim()) - .map_err(|e| std::io::Error::new(e.kind(), "Failed to open output file!"))?; - - let mut buf_writer = BufWriter::new(out_file); - - let mut counter = 0; - - // Generate and write the header - let header = csv_header_serializer::to_string(&FdrData::default(), args.delimiter) - .map_err(|_| std::io::Error::new(ErrorKind::Other, "Failed to generate header."))?; - buf_writer.write(header.as_bytes())?; - - // Create the CSV writer, and serialize the file. - let mut writer = WriterBuilder::new() - .delimiter(args.delimiter as u8) - .has_headers(false) - .from_writer(buf_writer); - - while let Ok(fdr_data) = read_record(&mut reader) { - writer.serialize(&fdr_data)?; - - counter += 1; - - if counter % 1000 == 0 { - print!("Processed {counter} entries...\r"); - std::io::stdout().flush()?; - } - } - - println!("Processed {counter} entries..."); - - Result::Ok(()) -} diff --git a/tools/fdr2csv/a32nx/wrapper.hpp b/tools/fdr2csv/a32nx/wrapper.hpp deleted file mode 100644 index da3a8f3d0ea..00000000000 --- a/tools/fdr2csv/a32nx/wrapper.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "../../../fbw-a32nx/src/wasm/fbw_a320/src/model/AutopilotLaws_types.h" -#include "../../../fbw-a32nx/src/wasm/fbw_a320/src/model/AutopilotStateMachine_types.h" -#include "../../../fbw-a32nx/src/wasm/fbw_a320/src/model/Autothrust_types.h" -#include "../../../fbw-a32nx/src/wasm/fbw_a320/src/model/ElacComputer_types.h" -#include "../../../fbw-a32nx/src/wasm/fbw_a320/src/model/FacComputer_types.h" -#include "../../../fbw-a32nx/src/wasm/fbw_a320/src/model/SecComputer_types.h" -#include "../../../fbw-a32nx/src/wasm/fbw_a320/src/recording/RecordingDataTypes.h" diff --git a/tools/fdr2csv/a380_wrapper.hpp b/tools/fdr2csv/a380_wrapper.hpp new file mode 100644 index 00000000000..c9711a22274 --- /dev/null +++ b/tools/fdr2csv/a380_wrapper.hpp @@ -0,0 +1,8 @@ +#include "../../fbw-a380x/src/wasm/fbw_a380/src/interface/FuelSystemData.h" +#include "../../fbw-a380x/src/wasm/fbw_a380/src/model/A380PrimComputer_types.h" +#include "../../fbw-a380x/src/wasm/fbw_a380/src/model/A380SecComputer_types.h" +#include "../../fbw-a380x/src/wasm/fbw_a380/src/model/AutopilotLaws_types.h" +#include "../../fbw-a380x/src/wasm/fbw_a380/src/model/AutopilotStateMachine_types.h" +#include "../../fbw-a380x/src/wasm/fbw_a380/src/model/Autothrust_types.h" +#include "../../fbw-a380x/src/wasm/fbw_a380/src/model/FacComputer_types.h" +#include "../../fbw-a380x/src/wasm/fbw_a380/src/recording/RecordingDataTypes.h" \ No newline at end of file diff --git a/tools/fdr2csv/a380x/Cargo.lock b/tools/fdr2csv/a380x/Cargo.lock deleted file mode 100644 index d470243e894..00000000000 --- a/tools/fdr2csv/a380x/Cargo.lock +++ /dev/null @@ -1,610 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "anstream" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" - -[[package]] -name = "anstyle-parse" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" -dependencies = [ - "anstyle", - "windows-sys", -] - -[[package]] -name = "bindgen" -version = "0.69.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "itertools", - "lazy_static", - "lazycell", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn", - "which", -] - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "bytemuck" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "clap" -version = "4.5.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" - -[[package]] -name = "colorchoice" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" - -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "csv" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" -dependencies = [ - "csv-core", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" -dependencies = [ - "memchr", -] - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "fdr2csv-a380x" -version = "0.1.0" -dependencies = [ - "bindgen", - "bytemuck", - "clap", - "csv", - "fdr2csv_common", - "flate2", - "serde", -] - -[[package]] -name = "fdr2csv_common" -version = "0.1.0" -dependencies = [ - "bindgen", - "bytemuck", - "clap", - "csv", - "flate2", - "serde", -] - -[[package]] -name = "flate2" -version = "1.0.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.155" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" - -[[package]] -name = "libloading" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" -dependencies = [ - "cfg-if", - "windows-targets", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "prettyplease" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" -dependencies = [ - "proc-macro2", - "syn", -] - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "regex" -version = "1.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "serde" -version = "1.0.213" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.213" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "syn" -version = "2.0.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/tools/fdr2csv/a380x/Cargo.toml b/tools/fdr2csv/a380x/Cargo.toml deleted file mode 100644 index 4c9d0fedc89..00000000000 --- a/tools/fdr2csv/a380x/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "fdr2csv-a380x" -version = "0.1.0" -authors = ["FlyByWire Simulations"] -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[build-dependencies] -bindgen = "0.69.5" - -[dependencies] -fdr2csv_common = { path = "../common" } - -clap = { version = "4.5.20", features = ["derive"] } -serde = { version = "1.0.213", features = ["derive"] } -bytemuck = { version = "1.19.0", features = ["derive"] } - -csv = "1.3.0" -flate2 = "1.0.30" - -[workspace] diff --git a/tools/fdr2csv/a380x/src/main.rs b/tools/fdr2csv/a380x/src/main.rs deleted file mode 100644 index b7df7b67fe7..00000000000 --- a/tools/fdr2csv/a380x/src/main.rs +++ /dev/null @@ -1,220 +0,0 @@ -use bytemuck::AnyBitPattern; -use clap::Parser; -use csv::WriterBuilder; -use fdr2csv_common::csv_header_serializer; -use flate2::bufread::GzDecoder; -use headers::{ - ap_raw_output, ap_sm_output, athr_out, base_fac_analog_outputs, base_fac_bus, - base_fac_discrete_outputs, base_prim_analog_outputs, base_prim_discrete_outputs, - base_prim_out_bus, base_sec_analog_outputs, base_sec_discrete_outputs, base_sec_out_bus, - AircraftSpecificData, BaseData, FuelSystemData, -}; -use serde::Serialize; -use std::{ - fs::{File, OpenOptions}, - io::{prelude::*, BufReader, BufWriter, Error, ErrorKind}, - mem, -}; - -mod headers; - -#[derive(Parser, Debug)] -#[command(version, about, long_about = None)] -struct Args { - /// Input file - #[arg(short, long)] - input: String, - /// Output file - #[arg(short, long)] - output: String, - /// Delimiter - #[arg(short, long, default_value = ",")] - delimiter: char, - /// Input file is not compressed - #[arg(short, long, default_value_t = false)] - no_compression: bool, - /// Print struct size - #[arg(short, long, default_value_t = false)] - print_struct_size: bool, - /// Print interface version of input file - #[arg(short, long, default_value_t = false)] - get_input_file_version: bool, -} - -const INTERFACE_VERSION: u64 = 3800001; - -// Read number of bytes specified by the size of T from the binary file -fn read_bytes(reader: &mut impl Read) -> Result { - let size = mem::size_of::(); - - // allocate the buffer that will hold the value read from the binary - let mut buf = vec![0u8; size]; - - // now read from the reader into the buffer - reader.read_exact(&mut buf)?; - - // If the read was successful, reinterpret the bytes as the struct, and return - let res = bytemuck::from_bytes::(buf.as_slice()); - - Ok(*res) -} - -// A single FDR record -#[derive(Serialize, Default)] -struct FdrData { - base: BaseData, - specific: AircraftSpecificData, - prim_1: PrimData, - prim_2: PrimData, - prim_3: PrimData, - sec_1: SecData, - sec_2: SecData, - sec_3: SecData, - fac_1: FacData, - fac_2: FacData, - ap_sm: ap_sm_output, - ap_law: ap_raw_output, - athr: athr_out, - fuel: FuelSystemData, -} - -#[derive(Serialize, Default)] -struct PrimData { - bus_outputs: base_prim_out_bus, - discrete_outputs: base_prim_discrete_outputs, - analog_outputs: base_prim_analog_outputs, -} - -#[derive(Serialize, Default)] -struct SecData { - bus_outputs: base_sec_out_bus, - discrete_outputs: base_sec_discrete_outputs, - analog_outputs: base_sec_analog_outputs, -} - -#[derive(Serialize, Default)] -struct FacData { - bus_outputs: base_fac_bus, - discrete_outputs: base_fac_discrete_outputs, - analog_outputs: base_fac_analog_outputs, -} - -// These are helper functions to read in a whole FDR record. -fn read_record(reader: &mut impl Read) -> Result { - Ok(FdrData { - base: read_bytes::(reader)?, - specific: read_bytes::(reader)?, - prim_1: read_prim(reader)?, - prim_2: read_prim(reader)?, - prim_3: read_prim(reader)?, - sec_1: read_sec(reader)?, - sec_2: read_sec(reader)?, - sec_3: read_sec(reader)?, - fac_1: read_fac(reader)?, - fac_2: read_fac(reader)?, - ap_sm: read_bytes::(reader)?, - ap_law: read_bytes::(reader)?, - athr: read_bytes::(reader)?, - fuel: read_bytes::(reader)?, - }) -} - -fn read_prim(reader: &mut impl Read) -> Result { - Ok(PrimData { - bus_outputs: read_bytes::(reader)?, - discrete_outputs: read_bytes::(reader)?, - analog_outputs: read_bytes::(reader)?, - }) -} - -fn read_sec(reader: &mut impl Read) -> Result { - Ok(SecData { - bus_outputs: read_bytes::(reader)?, - discrete_outputs: read_bytes::(reader)?, - analog_outputs: read_bytes::(reader)?, - }) -} - -fn read_fac(reader: &mut impl Read) -> Result { - Ok(FacData { - bus_outputs: read_bytes::(reader)?, - discrete_outputs: read_bytes::(reader)?, - analog_outputs: read_bytes::(reader)?, - }) -} - -fn main() -> Result<(), std::io::Error> { - // Parse CLI arguments - let args = Args::parse(); - - // Open the input file - let in_file = File::open(args.input.trim()) - .map_err(|e| std::io::Error::new(e.kind(), "Failed to open input file!"))?; - - // Create Gzip Reader - let mut reader: Box = if args.no_compression { - Box::new(BufReader::new(in_file)) - } else { - Box::new(GzDecoder::new(BufReader::new(in_file))) - }; - - // Read file version - let file_format_version = read_bytes::(&mut reader)?; - - // Print or check file version - if args.get_input_file_version { - println!("Interface version is {}", file_format_version); - return Ok(()); - } else if INTERFACE_VERSION != file_format_version { - return Err(std::io::Error::new( - ErrorKind::InvalidInput, - format!( - "Mismatch between converter and file version (expected {INTERFACE_VERSION}, got {file_format_version})", - ), - )); - } - - // Print info on conversion start - println!( - "Converting from '{}' to '{}' with interface version '{}' and delimiter '{}'", - args.input, args.output, file_format_version, args.delimiter - ); - - // Open or create output file in truncate mode - let out_file = OpenOptions::new() - .write(true) - .truncate(true) - .create(true) - .open(args.output.trim()) - .map_err(|e| std::io::Error::new(e.kind(), "Failed to open output file!"))?; - - let mut buf_writer = BufWriter::new(out_file); - - let mut counter = 0; - - // Generate and write the header - let header = csv_header_serializer::to_string(&FdrData::default(), args.delimiter) - .map_err(|_| std::io::Error::new(ErrorKind::Other, "Failed to generate header."))?; - buf_writer.write(header.as_bytes())?; - - // Create the CSV writer, and serialize the file. - let mut writer = WriterBuilder::new() - .delimiter(args.delimiter as u8) - .has_headers(false) - .from_writer(buf_writer); - - while let Ok(fdr_data) = read_record(&mut reader) { - writer.serialize(&fdr_data)?; - - counter += 1; - - if counter % 1000 == 0 { - print!("Processed {counter} entries...\r"); - std::io::stdout().flush()?; - } - } - - println!("Processed {counter} entries..."); - - Result::Ok(()) -} diff --git a/tools/fdr2csv/a380x/wrapper.hpp b/tools/fdr2csv/a380x/wrapper.hpp deleted file mode 100644 index 7d0889a4d2c..00000000000 --- a/tools/fdr2csv/a380x/wrapper.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "../../../fbw-a380x/src/wasm/fbw_a380/src/interface/FuelSystemData.h" -#include "../../../fbw-a380x/src/wasm/fbw_a380/src/model/A380PrimComputer_types.h" -#include "../../../fbw-a380x/src/wasm/fbw_a380/src/model/A380SecComputer_types.h" -#include "../../../fbw-a380x/src/wasm/fbw_a380/src/model/AutopilotLaws_types.h" -#include "../../../fbw-a380x/src/wasm/fbw_a380/src/model/AutopilotStateMachine_types.h" -#include "../../../fbw-a380x/src/wasm/fbw_a380/src/model/Autothrust_types.h" -#include "../../../fbw-a380x/src/wasm/fbw_a380/src/model/FacComputer_types.h" -#include "../../../fbw-a380x/src/wasm/fbw_a380/src/recording/RecordingDataTypes.h" diff --git a/tools/fdr2csv/a380x/build.rs b/tools/fdr2csv/build.rs similarity index 61% rename from tools/fdr2csv/a380x/build.rs rename to tools/fdr2csv/build.rs index f92c176c95d..4c1fd3932b2 100644 --- a/tools/fdr2csv/a380x/build.rs +++ b/tools/fdr2csv/build.rs @@ -23,10 +23,24 @@ fn main() { // The bindgen::Builder is the main entry point // to bindgen, and lets you build up options for // the resulting bindings. - let bindings = bindgen::Builder::default() + let bindings_320 = bindgen::Builder::default() // The input header we would like to generate // bindings for. - .header("wrapper.hpp") + .header("a320_wrapper.hpp") + .clang_arg("-std=c++20") + // Tell cargo to invalidate the built crate whenever any of the + // included header files changed. + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .parse_callbacks(Box::new(CustomDeriveCallback::new())) + // Finish the builder and generate the bindings. + .generate() + // Unwrap the Result and panic on failure. + .expect("Unable to generate bindings"); + + let bindings_380 = bindgen::Builder::default() + // The input header we would like to generate + // bindings for. + .header("a380_wrapper.hpp") .clang_arg("-std=c++20") // Tell cargo to invalidate the built crate whenever any of the // included header files changed. @@ -39,7 +53,11 @@ fn main() { // Write the bindings to the $OUT_DIR/bindings.rs file. let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - bindings - .write_to_file(out_path.join("bindings.rs")) + bindings_320 + .write_to_file(out_path.join("bindings_320.rs")) + .expect("Couldn't write bindings!"); + + bindings_380 + .write_to_file(out_path.join("bindings_380.rs")) .expect("Couldn't write bindings!"); } diff --git a/tools/fdr2csv/common/src/lib.rs b/tools/fdr2csv/common/src/lib.rs deleted file mode 100644 index 1a7058da99b..00000000000 --- a/tools/fdr2csv/common/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod csv_header_serializer; -pub mod error; diff --git a/tools/fdr2csv/src/a320.rs b/tools/fdr2csv/src/a320.rs new file mode 100644 index 00000000000..2357cbf1e56 --- /dev/null +++ b/tools/fdr2csv/src/a320.rs @@ -0,0 +1,93 @@ +use crate::{ + a320_headers::{ + ap_laws_output, ap_sm_output, athr_out, base_elac_analog_outputs, + base_elac_discrete_outputs, base_elac_out_bus, base_fac_analog_outputs, base_fac_bus, + base_fac_discrete_outputs, base_sec_analog_outputs, base_sec_discrete_outputs, + base_sec_out_bus, AircraftSpecificData, BaseData, + }, + read_bytes, +}; +use serde::Serialize; +use std::io::{prelude::*, Error}; + +pub const INTERFACE_VERSION: u64 = 3200001; + +// A single FDR record +#[derive(Serialize, Default)] +pub struct FdrData { + base: BaseData, + specific: AircraftSpecificData, + elac_1: ElacData, + elac_2: ElacData, + sec_1: SecData, + sec_2: SecData, + sec_3: SecData, + fac_1: FacData, + fac_2: FacData, + ap_sm: ap_sm_output, + ap_law: ap_laws_output, + athr: athr_out, +} + +#[derive(Serialize, Default)] +struct ElacData { + bus_outputs: base_elac_out_bus, + discrete_outputs: base_elac_discrete_outputs, + analog_outputs: base_elac_analog_outputs, +} + +#[derive(Serialize, Default)] +struct SecData { + bus_outputs: base_sec_out_bus, + discrete_outputs: base_sec_discrete_outputs, + analog_outputs: base_sec_analog_outputs, +} + +#[derive(Serialize, Default)] +struct FacData { + bus_outputs: base_fac_bus, + discrete_outputs: base_fac_discrete_outputs, + analog_outputs: base_fac_analog_outputs, +} + +// These are helper functions to read in a whole FDR record. +pub fn read_record(reader: &mut impl Read) -> Result { + Ok(FdrData { + base: read_bytes::(reader)?, + specific: read_bytes::(reader)?, + elac_1: read_elac(reader)?, + elac_2: read_elac(reader)?, + sec_1: read_sec(reader)?, + sec_2: read_sec(reader)?, + sec_3: read_sec(reader)?, + fac_1: read_fac(reader)?, + fac_2: read_fac(reader)?, + ap_sm: read_bytes::(reader)?, + ap_law: read_bytes::(reader)?, + athr: read_bytes::(reader)?, + }) +} + +fn read_elac(reader: &mut impl Read) -> Result { + Ok(ElacData { + bus_outputs: read_bytes::(reader)?, + discrete_outputs: read_bytes::(reader)?, + analog_outputs: read_bytes::(reader)?, + }) +} + +fn read_sec(reader: &mut impl Read) -> Result { + Ok(SecData { + bus_outputs: read_bytes::(reader)?, + discrete_outputs: read_bytes::(reader)?, + analog_outputs: read_bytes::(reader)?, + }) +} + +fn read_fac(reader: &mut impl Read) -> Result { + Ok(FacData { + bus_outputs: read_bytes::(reader)?, + discrete_outputs: read_bytes::(reader)?, + analog_outputs: read_bytes::(reader)?, + }) +} diff --git a/tools/fdr2csv/a380x/src/headers.rs b/tools/fdr2csv/src/a320_headers.rs similarity index 74% rename from tools/fdr2csv/a380x/src/headers.rs rename to tools/fdr2csv/src/a320_headers.rs index 44988be32a6..a709a48f03b 100644 --- a/tools/fdr2csv/a380x/src/headers.rs +++ b/tools/fdr2csv/src/a320_headers.rs @@ -7,4 +7,4 @@ use serde::Serialize; use bytemuck::AnyBitPattern; -include!(concat!(env!("OUT_DIR"), "/bindings.rs")); +include!(concat!(env!("OUT_DIR"), "/bindings_320.rs")); diff --git a/tools/fdr2csv/src/a380.rs b/tools/fdr2csv/src/a380.rs new file mode 100644 index 00000000000..3420e449254 --- /dev/null +++ b/tools/fdr2csv/src/a380.rs @@ -0,0 +1,98 @@ +use crate::{ + a380_headers::{ + ap_laws_output, ap_sm_output, athr_out, base_fac_analog_outputs, base_fac_bus, + base_fac_discrete_outputs, base_prim_analog_outputs, base_prim_discrete_outputs, + base_prim_out_bus, base_sec_analog_outputs, base_sec_discrete_outputs, base_sec_out_bus, + AircraftSpecificData, BaseData, FuelSystemData, + }, + read_bytes, +}; +use serde::Serialize; +use std::io::{prelude::*, Error}; + +pub const INTERFACE_VERSION: u64 = 3800001; +pub const INTERFACE_MIN_VERSION: u64 = 3800000; + +// A single FDR record +#[derive(Serialize, Default)] +pub struct FdrData { + base: BaseData, + specific: AircraftSpecificData, + prim_1: PrimData, + prim_2: PrimData, + prim_3: PrimData, + sec_1: SecData, + sec_2: SecData, + sec_3: SecData, + fac_1: FacData, + fac_2: FacData, + ap_sm: ap_sm_output, + ap_law: ap_laws_output, + athr: athr_out, + fuel: FuelSystemData, +} + +#[derive(Serialize, Default)] +struct PrimData { + bus_outputs: base_prim_out_bus, + discrete_outputs: base_prim_discrete_outputs, + analog_outputs: base_prim_analog_outputs, +} + +#[derive(Serialize, Default)] +struct SecData { + bus_outputs: base_sec_out_bus, + discrete_outputs: base_sec_discrete_outputs, + analog_outputs: base_sec_analog_outputs, +} + +#[derive(Serialize, Default)] +struct FacData { + bus_outputs: base_fac_bus, + discrete_outputs: base_fac_discrete_outputs, + analog_outputs: base_fac_analog_outputs, +} + +// These are helper functions to read in a whole FDR record. +pub fn read_record(reader: &mut impl Read) -> Result { + Ok(FdrData { + base: read_bytes::(reader)?, + specific: read_bytes::(reader)?, + prim_1: read_prim(reader)?, + prim_2: read_prim(reader)?, + prim_3: read_prim(reader)?, + sec_1: read_sec(reader)?, + sec_2: read_sec(reader)?, + sec_3: read_sec(reader)?, + fac_1: read_fac(reader)?, + fac_2: read_fac(reader)?, + ap_sm: read_bytes::(reader)?, + ap_law: read_bytes::(reader)?, + athr: read_bytes::(reader)?, + fuel: read_bytes::(reader)?, + }) +} + +fn read_prim(reader: &mut impl Read) -> Result { + Ok(PrimData { + bus_outputs: read_bytes::(reader)?, + discrete_outputs: read_bytes::(reader)?, + analog_outputs: read_bytes::(reader)?, + }) +} + +fn read_sec(reader: &mut impl Read) -> Result { + Ok(SecData { + bus_outputs: read_bytes::(reader)?, + discrete_outputs: read_bytes::(reader)?, + analog_outputs: read_bytes::(reader)?, + }) +} + +fn read_fac(reader: &mut impl Read) -> Result { + Ok(FacData { + bus_outputs: read_bytes::(reader)?, + discrete_outputs: read_bytes::(reader)?, + analog_outputs: read_bytes::(reader)?, + }) +} diff --git a/tools/fdr2csv/a32nx/src/headers.rs b/tools/fdr2csv/src/a380_headers.rs similarity index 74% rename from tools/fdr2csv/a32nx/src/headers.rs rename to tools/fdr2csv/src/a380_headers.rs index 44988be32a6..979950ebaf6 100644 --- a/tools/fdr2csv/a32nx/src/headers.rs +++ b/tools/fdr2csv/src/a380_headers.rs @@ -7,4 +7,4 @@ use serde::Serialize; use bytemuck::AnyBitPattern; -include!(concat!(env!("OUT_DIR"), "/bindings.rs")); +include!(concat!(env!("OUT_DIR"), "/bindings_380.rs")); diff --git a/tools/fdr2csv/common/src/csv_header_serializer.rs b/tools/fdr2csv/src/csv_header_serializer.rs similarity index 100% rename from tools/fdr2csv/common/src/csv_header_serializer.rs rename to tools/fdr2csv/src/csv_header_serializer.rs diff --git a/tools/fdr2csv/common/src/error.rs b/tools/fdr2csv/src/error.rs similarity index 100% rename from tools/fdr2csv/common/src/error.rs rename to tools/fdr2csv/src/error.rs diff --git a/tools/fdr2csv/src/main.rs b/tools/fdr2csv/src/main.rs new file mode 100644 index 00000000000..768953aea86 --- /dev/null +++ b/tools/fdr2csv/src/main.rs @@ -0,0 +1,180 @@ +use bytemuck::AnyBitPattern; +use clap::Parser; +use csv::WriterBuilder; +use flate2::bufread::GzDecoder; +use std::{ + fs::{File, OpenOptions}, + io::{prelude::*, BufReader, BufWriter, Error, ErrorKind}, + mem, +}; + +mod a320; +mod a320_headers; +mod a380; +mod a380_headers; +mod csv_header_serializer; +mod error; + +#[derive(Debug)] +enum AircraftType { + A320, + A380, +} + +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +struct Args { + /// Input file + #[arg(short, long)] + input: String, + /// Output file + #[arg(short, long, required_unless_present_any(["get_input_file_version", "get_raw_input_file_version"]))] + output: Option, + /// Delimiter + #[arg(short, long, default_value = ",")] + delimiter: char, + /// Input file is not compressed + #[arg(short, long, default_value_t = false)] + no_compression: bool, + /// Print struct size + #[arg(short, long, default_value_t = false)] + print_struct_size: bool, + /// Print interface version and aircraft type of input file + #[arg(short, long, default_value_t = false)] + get_input_file_version: bool, + /// Print raw interface version of input file + #[arg(short = 'r', long, default_value_t = false)] + get_raw_input_file_version: bool, +} + +// Read number of bytes specified by the size of T from the binary file +pub fn read_bytes(reader: &mut impl Read) -> Result { + let size = mem::size_of::(); + + // allocate the buffer that will hold the value read from the binary + let mut buf = vec![0u8; size]; + + // now read from the reader into the buffer + reader.read_exact(&mut buf)?; + + // If the read was successful, reinterpret the bytes as the struct, and return + let res = bytemuck::from_bytes::(buf.as_slice()); + + Ok(*res) +} + +fn main() -> Result<(), std::io::Error> { + // Parse CLI arguments + let args = Args::parse(); + + // Open the input file + let in_file = File::open(args.input.trim()) + .map_err(|e| std::io::Error::new(e.kind(), "Failed to open input file!"))?; + + // Create Gzip Reader + let mut reader: Box = if args.no_compression { + Box::new(BufReader::new(in_file)) + } else { + Box::new(GzDecoder::new(BufReader::new(in_file))) + }; + + // Read file version + let file_format_version = read_bytes::(&mut reader)?; + let aircraft_type = if file_format_version > a380::INTERFACE_MIN_VERSION { + AircraftType::A380 + } else { + AircraftType::A320 + }; + + let aircraft_interface_version = match aircraft_type { + AircraftType::A320 => a320::INTERFACE_VERSION, + AircraftType::A380 => a380::INTERFACE_VERSION, + }; + + // Print or check file version + if args.get_input_file_version { + println!( + "Aircraft Type is {:?}, Interface version is {}", + aircraft_type, file_format_version + ); + return Ok(()); + } else if args.get_raw_input_file_version { + println!("{}", file_format_version); + return Ok(()); + } else if aircraft_interface_version != file_format_version { + return Err(std::io::Error::new( + ErrorKind::InvalidInput, + format!( + "Mismatch between converter and file version (expected {aircraft_interface_version}, got {file_format_version})", + ), + )); + } + + // Print info on conversion start + println!( + "Converting from '{}' to '{}' for aircraft type '{:?}' with interface version '{}' and delimiter '{}'", + args.input, args.output.clone().unwrap(), aircraft_type, file_format_version, args.delimiter + ); + + // Open or create output file in truncate mode + let out_file = OpenOptions::new() + .write(true) + .truncate(true) + .create(true) + .open(args.output.clone().unwrap().trim()) + .map_err(|e| std::io::Error::new(e.kind(), "Failed to open output file!"))?; + + let mut buf_writer = BufWriter::new(out_file); + + let mut counter = 0; + + // Generate and write the header + let header = match aircraft_type { + AircraftType::A320 => { + csv_header_serializer::to_string(&a320::FdrData::default(), args.delimiter) + } + AircraftType::A380 => { + csv_header_serializer::to_string(&a380::FdrData::default(), args.delimiter) + } + } + .map_err(|_| std::io::Error::new(ErrorKind::Other, "Failed to generate header."))?; + + buf_writer.write(header.as_bytes())?; + + // Create the CSV writer, and serialize the file. + let mut writer = WriterBuilder::new() + .delimiter(args.delimiter as u8) + .has_headers(false) + .from_writer(buf_writer); + + match aircraft_type { + AircraftType::A320 => { + while let Ok(fdr_data) = a320::read_record(&mut reader) { + writer.serialize(&fdr_data)?; + + counter += 1; + + if counter % 1000 == 0 { + print!("Processed {counter} entries...\r"); + std::io::stdout().flush()?; + } + } + } + AircraftType::A380 => { + while let Ok(fdr_data) = a380::read_record(&mut reader) { + writer.serialize(&fdr_data)?; + + counter += 1; + + if counter % 1000 == 0 { + print!("Processed {counter} entries...\r"); + std::io::stdout().flush()?; + } + } + } + } + + println!("Processed {counter} entries..."); + + Result::Ok(()) +}