commit 66459afcab4a8fc6ea8fa1166834fdb90be9443b Author: lkoester Date: Thu Dec 15 14:57:29 2022 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dd0bafb --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/target + +/.idea/* +!/.idea/runConfigurations + diff --git a/.idea/runConfigurations/Run.xml b/.idea/runConfigurations/Run.xml new file mode 100644 index 0000000..fb73350 --- /dev/null +++ b/.idea/runConfigurations/Run.xml @@ -0,0 +1,19 @@ + + + + \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..4d85a20 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,737 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf6ccdb167abbf410dcb915cabd428929d7f6a04980b54a11f26a39f1c7f7107" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "atomic-polyfill" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bumpalo" +version = "3.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" + +[[package]] +name = "bus" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80cb4625f5b60155ff1018c9d4ce2e38bf5ae3e5780dfab9fa68bb44a6b751e2" +dependencies = [ + "crossbeam-channel", + "num_cpus", + "parking_lot_core", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +dependencies = [ + "iana-time-zone", + "num-integer", + "num-traits", + "winapi", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "crc" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53757d12b596c16c78b83458d732a5d1a17ab3f53f2f7412f6fb57cc8a140ab3" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d0165d2900ae6778e36e80bbc4da3b5eefccee9ba939761f9c2882a5d9af3ff" + +[[package]] +name = "critical-section" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "cxx" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "delegate" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d70a2d4995466955a415223acf3c9c934b9ff2339631cdf4ffc893da4bacd717" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "delegate" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "082a24a9967533dc5d743c602157637116fc1b52806d694a5a45e6f32567fcdd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "dyn-clone" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" + +[[package]] +name = "embed-doc-image" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af36f591236d9d822425cb6896595658fa558fcebf5ee8accac1d4b92c47166e" +dependencies = [ + "base64", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "eurosim-obsw" +version = "0.1.0" +dependencies = [ + "satrs-core", + "spacepackets", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" +dependencies = [ + "ahash", +] + +[[package]] +name = "heapless" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" + +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "parking_lot_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "paste" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1c2c742266c2f1041c914ba65355a83ae8747b05f208319784083583494b4b" + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "satrs-core" +version = "0.1.0" +dependencies = [ + "bus", + "crossbeam-channel", + "delegate 0.8.0", + "downcast-rs", + "dyn-clone", + "embed-doc-image", + "hashbrown", + "heapless", + "num-traits", + "paste", + "spacepackets", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + +[[package]] +name = "semver" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" + +[[package]] +name = "serde" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "spacepackets" +version = "0.2.0" +dependencies = [ + "chrono", + "crc", + "delegate 0.7.0", + "num-traits", + "serde", + "zerocopy", +] + +[[package]] +name = "spin" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "syn" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + +[[package]] +name = "zerocopy" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332f188cc1bcf1fe1064b8c58d150f497e697f49774aa846f2dc949d9a25f236" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6505e6815af7de1746a08f69c69606bb45695a17149517680f3b2149713b19a3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..a92c68a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "eurosim-obsw" +version = "0.1.0" +edition = "2021" +authors = ["Linus Köster ", "Robin Müller "] +description = "EuroSim OBSW Implementation" +homepage = "https://egit.irs.uni-stuttgart.de/rust/eurosim-obsw" +repository = "https://egit.irs.uni-stuttgart.de/rust/eurosim-obsw" +# license = "Apache-2.0" +categories = ["aerospace", "hardware-support", "embedded"] +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +[dependencies.spacepackets] +path = "../satrs-launchpad/spacepackets" + +[dependencies.satrs-core] +path = "../satrs-launchpad/satrs-core" + +[features] diff --git a/src/ccsds.rs b/src/ccsds.rs new file mode 100644 index 0000000..cbaf5c7 --- /dev/null +++ b/src/ccsds.rs @@ -0,0 +1,37 @@ +use crate::tmtc::PUS_APID; +use satrs_core::tmtc::{CcsdsPacketHandler, PusDistributor, ReceivesCcsdsTc}; +use spacepackets::{CcsdsPacket, SpHeader}; + +pub struct CcsdsReceiver { + pub pus_handler: PusDistributor<()>, +} + +impl CcsdsPacketHandler for CcsdsReceiver { + type Error = (); + + fn valid_apids(&self) -> &'static [u16] { + &[PUS_APID] + } + + fn handle_known_apid( + &mut self, + sp_header: &SpHeader, + tc_raw: &[u8], + ) -> Result<(), Self::Error> { + if sp_header.apid() == PUS_APID { + self.pus_handler + .pass_ccsds(sp_header, tc_raw) + .expect("Handling PUS packet failed"); + } + Ok(()) + } + + fn handle_unknown_apid( + &mut self, + sp_header: &SpHeader, + _tc_raw: &[u8], + ) -> Result<(), Self::Error> { + println!("Unknown APID 0x{:x?} detected", sp_header.apid()); + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..b1bb894 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,4 @@ +use std::net::Ipv4Addr; + +pub const OBSW_SERVER_ADDR: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1); +pub const SERVER_PORT: u16 = 7301; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..db45376 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,183 @@ +mod ccsds; +mod pus; +mod tmtc; + +use crate::tmtc::{core_tmtc_task, CoreTmtcArgs, TmStore, PUS_APID}; +use satrs_core::event_man::{ + EventManagerWithMpscQueue, MpscEventReceiver, MpscEventU32SendProvider, SendEventProvider, +}; +use satrs_core::events::EventU32; +use satrs_core::hal::host::udp_server::UdpTcServer; +use satrs_core::pool::{LocalPool, PoolCfg, SharedPool, StoreAddr}; +use satrs_core::pus::event_man::{ + DefaultPusMgmtBackendProvider, EventReporter, EventRequest, EventRequestWithToken, + PusEventDispatcher, +}; +use satrs_core::pus::verification::{ + MpscVerifSender, VerificationReporterCfg, VerificationReporterWithSender, +}; +use satrs_core::pus::{EcssTmError, EcssTmSender}; +use satrs_core::seq_count::SimpleSeqCountProvider; +use satrs_core::tmtc::CcsdsError; +use eurosim_obsw::{OBSW_SERVER_ADDR, SERVER_PORT}; +use spacepackets::time::{CdsShortTimeProvider, TimeWriter}; +use spacepackets::tm::PusTm; +use std::net::{IpAddr, SocketAddr}; +use std::sync::mpsc::channel; +use std::sync::{mpsc, Arc, RwLock}; +use std::thread; + +struct TmFunnel { + tm_funnel_rx: mpsc::Receiver, + tm_server_tx: mpsc::Sender, +} + +struct UdpTmtcServer { + udp_tc_server: UdpTcServer>, + tm_rx: mpsc::Receiver, + tm_store: SharedPool, +} + +#[cfg(feature = "can")] + +unsafe impl Send for UdpTmtcServer {} + +#[derive(Clone)] +struct EventTmSender { + store_helper: TmStore, + sender: mpsc::Sender, +} + +impl EventTmSender { + fn new(store_helper: TmStore, sender: mpsc::Sender) -> Self { + Self { + store_helper, + sender, + } + } +} + +impl EcssTmSender for EventTmSender { + type Error = mpsc::SendError; + + fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError> { + let addr = self.store_helper.add_pus_tm(&tm); + self.sender.send(addr).map_err(EcssTmError::SendError) + } +} +fn main() { + println!("Running OBSW example"); + let pool_cfg = PoolCfg::new(vec![(8, 32), (4, 64), (2, 128)]); + let tm_pool = LocalPool::new(pool_cfg); + let tm_store: SharedPool = Arc::new(RwLock::new(Box::new(tm_pool))); + let tm_store_helper = TmStore { + pool: tm_store.clone(), + }; + let addr = SocketAddr::new(IpAddr::V4(OBSW_SERVER_ADDR), SERVER_PORT); + let (tm_funnel_tx, tm_funnel_rx) = channel(); + let (tm_server_tx, tm_server_rx) = channel(); + let sender = MpscVerifSender::new(tm_store.clone(), tm_funnel_tx.clone()); + let verif_cfg = VerificationReporterCfg::new( + PUS_APID, + Box::new(SimpleSeqCountProvider::default()), + 1, + 2, + 8, + ) + .unwrap(); + let reporter_with_sender_0 = VerificationReporterWithSender::new(&verif_cfg, Box::new(sender)); + + // Create event handling components + let (event_request_tx, event_request_rx) = channel::(); + let (event_sender, event_man_rx) = channel(); + let event_recv = MpscEventReceiver::::new(event_man_rx); + let mut event_man = EventManagerWithMpscQueue::new(Box::new(event_recv)); + let event_reporter = EventReporter::new(PUS_APID, 128).unwrap(); + let pus_tm_backend = DefaultPusMgmtBackendProvider::::default(); + let mut pus_event_dispatcher = + PusEventDispatcher::new(event_reporter, Box::new(pus_tm_backend)); + let (pus_event_man_tx, pus_event_man_rx) = channel(); + let pus_event_man_send_provider = MpscEventU32SendProvider::new(1, pus_event_man_tx); + let mut reporter1 = reporter_with_sender_0.clone(); + event_man.subscribe_all(pus_event_man_send_provider.id()); + + // Create clones here to allow move for thread 0 + let core_args = CoreTmtcArgs { + tm_store: tm_store_helper.clone(), + tm_sender: tm_funnel_tx.clone(), + event_sender, + event_request_tx, + }; + + println!("Starting TMTC task"); + let jh0 = thread::spawn(move || { + core_tmtc_task(core_args, tm_server_rx, addr, reporter_with_sender_0); + }); + + println!("Starting TM funnel task"); + let jh1 = thread::spawn(move || { + let tm_funnel = TmFunnel { + tm_server_tx, + tm_funnel_rx, + }; + loop { + if let Ok(addr) = tm_funnel.tm_funnel_rx.recv() { + tm_funnel + .tm_server_tx + .send(addr) + .expect("Sending TM to server failed"); + } + } + }); + + println!("Starting event handling task"); + let jh2 = thread::spawn(move || { + let mut timestamp: [u8; 7] = [0; 7]; + let mut sender = EventTmSender::new(tm_store_helper, tm_funnel_tx); + let mut time_provider = CdsShortTimeProvider::new(0, 0); + let mut report_completion = |event_req: EventRequestWithToken, timestamp: &[u8]| { + reporter1 + .completion_success(event_req.token, timestamp) + .expect("Sending completion success failed"); + }; + loop { + if let Ok(event_req) = event_request_rx.try_recv() { + match event_req.request { + EventRequest::Enable(event) => { + pus_event_dispatcher + .enable_tm_for_event(&event) + .expect("Enabling TM failed"); + update_time(&mut time_provider, &mut timestamp); + report_completion(event_req, ×tamp); + } + EventRequest::Disable(event) => { + pus_event_dispatcher + .disable_tm_for_event(&event) + .expect("Disabling TM failed"); + update_time(&mut time_provider, &mut timestamp); + report_completion(event_req, ×tamp); + } + } + } + if let Ok((event, _param)) = pus_event_man_rx.try_recv() { + update_time(&mut time_provider, &mut timestamp); + pus_event_dispatcher + .generate_pus_event_tm_generic(&mut sender, ×tamp, event, None) + .expect("Sending TM as event failed"); + } + } + }); + + jh0.join().expect("Joining UDP TMTC server thread failed"); + jh1.join().expect("Joining TM Funnel thread failed"); + jh2.join().expect("Joining Event Manager thread failed"); +} + +pub fn update_time(time_provider: &mut CdsShortTimeProvider, timestamp: &mut [u8]) { + time_provider + .update_from_now() + .expect("Could not get current time"); + time_provider + .write_to_bytes(timestamp) + .expect("Writing timestamp failed"); +} diff --git a/src/pus.rs b/src/pus.rs new file mode 100644 index 0000000..18a21b9 --- /dev/null +++ b/src/pus.rs @@ -0,0 +1,185 @@ +use crate::tmtc::TmStore; +use satrs_core::events::EventU32; +use satrs_core::pool::StoreAddr; +use satrs_core::pus::event::Subservices; +use satrs_core::pus::event_man::{EventRequest, EventRequestWithToken}; +use satrs_core::pus::verification::{ + FailParams, StdVerifReporterWithSender, TcStateAccepted, VerificationToken, +}; +use satrs_core::tmtc::tm_helper::PusTmWithCdsShortHelper; +use satrs_core::tmtc::PusServiceProvider; +use spacepackets::ecss::{EcssEnumU16, PusPacket}; +use spacepackets::tc::PusTc; +use spacepackets::time::{CdsShortTimeProvider, TimeWriter}; +use spacepackets::SpHeader; +use std::sync::mpsc; + +pub struct PusReceiver { + pub tm_helper: PusTmWithCdsShortHelper, + pub tm_tx: mpsc::Sender, + pub tm_store: TmStore, + pub verif_reporter: StdVerifReporterWithSender, + event_request_tx: mpsc::Sender, + stamper: CdsShortTimeProvider, + time_stamp: [u8; 7], +} + +impl PusReceiver { + pub fn new( + apid: u16, + tm_tx: mpsc::Sender, + tm_store: TmStore, + verif_reporter: StdVerifReporterWithSender, + event_request_tx: mpsc::Sender, + ) -> Self { + Self { + tm_helper: PusTmWithCdsShortHelper::new(apid), + tm_tx, + tm_store, + verif_reporter, + event_request_tx, + stamper: CdsShortTimeProvider::default(), + time_stamp: [0; 7], + } + } +} + +impl PusServiceProvider for PusReceiver { + type Error = (); + + fn handle_pus_tc_packet( + &mut self, + service: u8, + _header: &SpHeader, + pus_tc: &PusTc, + ) -> Result<(), Self::Error> { + let init_token = self.verif_reporter.add_tc(pus_tc); + self.update_time_stamp(); + let accepted_token = self + .verif_reporter + .acceptance_success(init_token, &self.time_stamp) + .expect("Acceptance success failure"); + if service == 17 { + self.handle_test_service(pus_tc, accepted_token); + } else if service == 5 { + self.handle_event_service(pus_tc, accepted_token); + } else { + // TODO: Unknown service verification failure + // TODO: Unknown service returncode + } + Ok(()) + } +} + +impl PusReceiver { + fn handle_test_service(&mut self, pus_tc: &PusTc, token: VerificationToken) { + if pus_tc.subservice() == 1 { + println!("Received PUS ping command TC[17,1]"); + println!("Sending ping reply PUS TM[17,2]"); + let ping_reply = self.tm_helper.create_pus_tm_timestamp_now(17, 2, None); + let addr = self.tm_store.add_pus_tm(&ping_reply); + let start_token = self + .verif_reporter + .start_success(token, &self.time_stamp) + .expect("Error sending start success"); + self.tm_tx + .send(addr) + .expect("Sending TM to TM funnel failed"); + self.verif_reporter + .completion_success(start_token, &self.time_stamp) + .expect("Error sending completion success"); + } else { + // TODO: Unknown Subservice returncode + self.update_time_stamp(); + self.verif_reporter + .start_failure( + token, + FailParams::new(&self.time_stamp, &EcssEnumU16::new(2), None), + ) + .expect("Sending start failure TM failed"); + } + } + + fn update_time_stamp(&mut self) { + self.stamper + .update_from_now() + .expect("Updating timestamp failed"); + self.stamper + .write_to_bytes(&mut self.time_stamp) + .expect("Writing timestamp failed"); + } + + fn handle_event_service(&mut self, pus_tc: &PusTc, token: VerificationToken) { + let send_start_failure = |verif_reporter: &mut StdVerifReporterWithSender, + timestamp: &[u8; 7], + failure_code: EcssEnumU16, + failure_data: Option<&[u8]>| { + verif_reporter + .start_failure( + token, + FailParams::new(timestamp, &failure_code, failure_data), + ) + .expect("Sending start failure TM failed"); + }; + let send_start_acceptance = |verif_reporter: &mut StdVerifReporterWithSender, + timestamp: &[u8; 7]| { + verif_reporter + .start_success(token, timestamp) + .expect("Sending start success TM failed") + }; + if pus_tc.user_data().is_none() { + self.update_time_stamp(); + send_start_failure( + &mut self.verif_reporter, + &self.time_stamp, + EcssEnumU16::new(1), + None, + ); + return; + } + let app_data = pus_tc.user_data().unwrap(); + if app_data.len() < 4 { + self.update_time_stamp(); + send_start_failure( + &mut self.verif_reporter, + &self.time_stamp, + EcssEnumU16::new(1), + None, + ); + return; + } + let event_id = EventU32::from(u32::from_be_bytes(app_data.try_into().unwrap())); + match PusPacket::subservice(pus_tc).try_into() { + Ok(Subservices::TcEnableEventGeneration) => { + self.update_time_stamp(); + let start_token = send_start_acceptance(&mut self.verif_reporter, &self.time_stamp); + self.event_request_tx + .send(EventRequestWithToken { + request: EventRequest::Enable(event_id), + token: start_token, + }) + .expect("Sending event request failed"); + } + Ok(Subservices::TcDisableEventGeneration) => { + self.update_time_stamp(); + let start_token = send_start_acceptance(&mut self.verif_reporter, &self.time_stamp); + self.event_request_tx + .send(EventRequestWithToken { + request: EventRequest::Disable(event_id), + token: start_token, + }) + .expect("Sending event request failed"); + } + _ => { + // TODO: Unknown Subservice returncode + self.update_time_stamp(); + send_start_failure( + &mut self.verif_reporter, + &self.time_stamp, + EcssEnumU16::new(2), + None, + ); + } + } + } +} diff --git a/src/tmtc.rs b/src/tmtc.rs new file mode 100644 index 0000000..03d0db0 --- /dev/null +++ b/src/tmtc.rs @@ -0,0 +1,127 @@ +use satrs_core::events::EventU32; +use satrs_core::hal::host::udp_server::{ReceiveResult, UdpTcServer}; +use satrs_core::params::Params; +use std::net::SocketAddr; +use std::sync::mpsc; +use std::sync::mpsc::Sender; +use std::thread; +use std::time::Duration; + +use crate::ccsds::CcsdsReceiver; +use crate::pus::PusReceiver; +use crate::UdpTmtcServer; +use satrs_core::pool::{SharedPool, StoreAddr}; +use satrs_core::pus::event_man::EventRequestWithToken; +use satrs_core::pus::verification::StdVerifReporterWithSender; +use satrs_core::tmtc::{CcsdsDistributor, CcsdsError, PusDistributor}; +use spacepackets::tm::PusTm; + +pub const PUS_APID: u16 = 0x02; + +pub struct CoreTmtcArgs { + pub tm_store: TmStore, + pub tm_sender: Sender, + pub event_sender: Sender<(EventU32, Option)>, + pub event_request_tx: Sender, +} + +#[derive(Clone)] +pub struct TmStore { + pub pool: SharedPool, +} + +impl TmStore { + pub fn add_pus_tm(&mut self, pus_tm: &PusTm) -> StoreAddr { + let mut pg = self.pool.write().expect("Error locking TM store"); + let (addr, buf) = pg.free_element(pus_tm.len_packed()).expect("Store error"); + pus_tm + .write_to_bytes(buf) + .expect("Writing PUS TM to store failed"); + addr + } +} + +pub fn core_tmtc_task( + args: CoreTmtcArgs, + tm_server_rx: mpsc::Receiver, + addr: SocketAddr, + verif_reporter: StdVerifReporterWithSender, +) { + let pus_receiver = PusReceiver::new( + PUS_APID, + args.tm_sender, + args.tm_store.clone(), + verif_reporter, + args.event_request_tx, + ); + let pus_distributor = PusDistributor::new(Box::new(pus_receiver)); + let ccsds_receiver = CcsdsReceiver { + pus_handler: pus_distributor, + }; + let ccsds_distributor = CcsdsDistributor::new(Box::new(ccsds_receiver)); + let udp_tc_server = UdpTcServer::new(addr, 2048, Box::new(ccsds_distributor)) + .expect("Creating UDP TMTC server failed"); + + let mut udp_tmtc_server = UdpTmtcServer { + udp_tc_server, + tm_rx: tm_server_rx, + tm_store: args.tm_store.pool.clone(), + }; + loop { + core_tmtc_loop(&mut udp_tmtc_server); + thread::sleep(Duration::from_millis(400)); + } +} + +fn core_tmtc_loop(udp_tmtc_server: &mut UdpTmtcServer) { + while core_tc_handling(udp_tmtc_server) {} + if let Some(recv_addr) = udp_tmtc_server.udp_tc_server.last_sender() { + core_tm_handling(udp_tmtc_server, &recv_addr); + } +} + +fn core_tc_handling(udp_tmtc_server: &mut UdpTmtcServer) -> bool { + match udp_tmtc_server.udp_tc_server.try_recv_tc() { + Ok(_) => true, + Err(e) => match e { + ReceiveResult::ReceiverError(e) => match e { + CcsdsError::PacketError(e) => { + println!("Got packet error: {e:?}"); + true + } + CcsdsError::CustomError(_) => { + println!("Unknown receiver error"); + true + } + }, + ReceiveResult::IoError(e) => { + println!("IO error {e}"); + false + } + ReceiveResult::NothingReceived => false, + }, + } +} + +fn core_tm_handling(udp_tmtc_server: &mut UdpTmtcServer, recv_addr: &SocketAddr) { + while let Ok(addr) = udp_tmtc_server.tm_rx.try_recv() { + let mut store_lock = udp_tmtc_server + .tm_store + .write() + .expect("Locking TM store failed"); + let pg = store_lock.read_with_guard(addr); + let buf = pg.read().expect("Error reading TM pool data"); + if buf.len() > 9 { + let service = buf[7]; + let subservice = buf[8]; + println!("Sending PUS TM[{},{}]", service, subservice) + } else { + println!("Sending PUS TM"); + } + udp_tmtc_server + .udp_tc_server + .socket + .send_to(buf, recv_addr) + .expect("Sending TM failed"); + } +}