Archived
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7d004b299 |
No files matched your search
@@ -2,7 +2,7 @@ name: ci
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
check:
|
||||
build:
|
||||
name: Check build
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- run: cargo check --release
|
||||
- run: cargo build
|
||||
|
||||
test:
|
||||
name: Run Tests
|
||||
@@ -29,8 +29,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@1.85
|
||||
- run: cargo check --release
|
||||
- uses: dtolnay/rust-toolchain@1.83
|
||||
- run: cargo check
|
||||
|
||||
cross-check:
|
||||
name: Check Cross-Compilation
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: "armv7-unknown-linux-gnueabihf, thumbv7em-none-eabihf, thumbv6m-none-eabi"
|
||||
- run: cargo check --release --target=${{matrix.target}} --no-default-features
|
||||
- run: cargo check --target=${{matrix.target}} --no-default-features
|
||||
|
||||
fmt:
|
||||
name: Check formatting
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Rust
|
||||
/target
|
||||
/Cargo.lock
|
||||
|
||||
# CLion
|
||||
/.idea/*
|
||||
|
||||
+2
-14
@@ -8,15 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
# [unreleased]
|
||||
|
||||
## Fixed
|
||||
|
||||
- Fixed an off-by-one error in the CUC counter rollover modulus which caused the counter to skip
|
||||
0 when wrapping around.
|
||||
|
||||
# [v0.18.0] 2026-07-14
|
||||
|
||||
- Bumped Rust version to 2024
|
||||
- Bumped MSRV to 1.85
|
||||
# [v0.18.0] ?
|
||||
|
||||
## Changed
|
||||
|
||||
@@ -25,7 +17,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
`CcsdsPacketCreatorWithReservedData::packet_data`, including mutable variants as well.
|
||||
- `SequenceCounter::MAX_BIT_WIDTH` is now a regular trait method `SequenceCounter::max_bit_width`
|
||||
to allow dyn compatibility and easier usage in trait objects.
|
||||
- Improved type level support in USLP module by using VC ID type `u6` and MAP ID type `u4`.
|
||||
|
||||
## Added
|
||||
|
||||
@@ -33,8 +24,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Added `SequenceCounterOnFile` which persists the sequence counter by writing it to a file.
|
||||
- Added `SequenceCounter::set` method which allows manually setting an initial value.
|
||||
- Added `CcsdsPacketReader::raw_data` full data getter.
|
||||
- `UslpFrameCreator` constructor
|
||||
- Additional reader methods on `UslpFrameReader`
|
||||
|
||||
## Removed
|
||||
|
||||
@@ -710,8 +699,7 @@ The timestamp of `PusTm` is now optional. See Added and Changed section for deta
|
||||
Initial release with CCSDS Space Packet Primary Header implementation and basic PUS TC and TM
|
||||
implementations.
|
||||
|
||||
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/spacepackets/compare/v0.18.0...HEAD
|
||||
[v0.18.0]: https://egit.irs.uni-stuttgart.de/rust/spacepackets/compare/v0.17.0...v0.18.0
|
||||
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/spacepackets/compare/v0.17.0...HEAD
|
||||
[v0.17.0]: https://egit.irs.uni-stuttgart.de/rust/spacepackets/compare/v0.16.1...v0.17.0
|
||||
[v0.16.1]: https://egit.irs.uni-stuttgart.de/rust/spacepackets/compare/v0.16.0...v0.16.1
|
||||
[v0.16.0]: https://egit.irs.uni-stuttgart.de/rust/spacepackets/compare/v0.15.0...v0.16.0
|
||||
|
||||
Generated
-763
@@ -1,763 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[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 = "arbitrary-int"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "993a810118f8f37e9c4411c86f1c4c940a09a7ab34b7bf2d88d06f50c553fab7"
|
||||
dependencies = [
|
||||
"defmt",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic-polyfill"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
||||
|
||||
[[package]]
|
||||
name = "bitbybit"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d2a3353d70ac1091a33cbf31fc7e77b19091538a7e306e3740712af19807ca"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e17dd265a7d0f31ef544e1b20e03add05d3b45b491b633b10d67145d2acc1a38"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
|
||||
dependencies = [
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cobs"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "crc"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d"
|
||||
dependencies = [
|
||||
"crc-catalog",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc-catalog"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853"
|
||||
|
||||
[[package]]
|
||||
name = "critical-section"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
|
||||
|
||||
[[package]]
|
||||
name = "defmt"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"defmt-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt-macros"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8"
|
||||
dependencies = [
|
||||
"defmt-parser",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt-parser"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "delegate"
|
||||
version = "0.13.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "780eb241654bf097afb00fc5f054a09b687dad862e485fdcf8399bb056565370"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
|
||||
|
||||
[[package]]
|
||||
name = "embedded-io"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
|
||||
|
||||
[[package]]
|
||||
name = "embedded-io"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"pin-project-lite",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hash32"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heapless"
|
||||
version = "0.7.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
|
||||
dependencies = [
|
||||
"atomic-polyfill",
|
||||
"hash32",
|
||||
"rustc_version",
|
||||
"serde",
|
||||
"spin",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"log",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"futures-util",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.186"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26"
|
||||
dependencies = [
|
||||
"num_enum_derive",
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
||||
|
||||
[[package]]
|
||||
name = "postcard"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
|
||||
dependencies = [
|
||||
"cobs",
|
||||
"embedded-io 0.4.0",
|
||||
"embedded-io 0.6.1",
|
||||
"heapless",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
|
||||
dependencies = [
|
||||
"bitflags 2.13.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
|
||||
|
||||
[[package]]
|
||||
name = "spacepackets"
|
||||
version = "0.18.0"
|
||||
dependencies = [
|
||||
"arbitrary-int",
|
||||
"bitbybit",
|
||||
"chrono",
|
||||
"crc",
|
||||
"defmt",
|
||||
"delegate",
|
||||
"num-traits",
|
||||
"num_enum",
|
||||
"paste",
|
||||
"portable-atomic",
|
||||
"postcard",
|
||||
"serde",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"time",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.118"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"num-conv",
|
||||
"powerfmt",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"rustversion",
|
||||
"wasm-bindgen-macro",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.62.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.59.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7cbbc0a705a0fd05cc3676525980d2bf5a9bc4adac6d6475209a7887cf59d19"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
[package]
|
||||
name = "spacepackets"
|
||||
version = "0.18.0"
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
version = "0.17.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.83"
|
||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||
description = "Generic implementations for various CCSDS and ECSS packet standards"
|
||||
homepage = "https://egit.irs.uni-stuttgart.de/rust/spacepackets"
|
||||
@@ -23,7 +23,7 @@ num-traits = { version = "0.2", default-features = false }
|
||||
serde = { version = "1", optional = true, default-features = false, features = ["derive"] }
|
||||
arbitrary-int = { version = "2" }
|
||||
portable-atomic = { version = "1", optional = true }
|
||||
bitbybit = "2"
|
||||
bitbybit = "1.4"
|
||||
|
||||
time = { version = "0.3", default-features = false, optional = true }
|
||||
chrono = { version = "0.4", default-features = false, optional = true }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
all: check build clippy embedded test check-fmt docs coverage
|
||||
all: check build embedded test clippy check-fmt docs coverage
|
||||
|
||||
clippy:
|
||||
cargo clippy -- -D warnings
|
||||
|
||||
+8
-6
@@ -1,12 +1,12 @@
|
||||
//! # Acknowledgement (ACK) PDU packet implementation.
|
||||
use crate::{
|
||||
ByteConversionError,
|
||||
cfdp::{ConditionCode, CrcFlag, Direction, TransactionStatus},
|
||||
ByteConversionError,
|
||||
};
|
||||
|
||||
use super::{
|
||||
CfdpPdu, FileDirectiveType, PduError, PduHeader, WritablePduPacket, add_pdu_crc,
|
||||
generic_length_checks_pdu_deserialization,
|
||||
add_pdu_crc, generic_length_checks_pdu_deserialization, CfdpPdu, FileDirectiveType, PduError,
|
||||
PduHeader, WritablePduPacket,
|
||||
};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -63,13 +63,14 @@ impl AckPdu {
|
||||
condition_code: ConditionCode,
|
||||
transaction_status: TransactionStatus,
|
||||
) -> Self {
|
||||
// Unwrap okay here, [new] can only fail on invalid directive codes.
|
||||
Self::new(
|
||||
pdu_header,
|
||||
FileDirectiveType::Eof,
|
||||
condition_code,
|
||||
transaction_status,
|
||||
)
|
||||
.expect("only fails when directive codes are invalid")
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Constructor for an ACK PDU acknowledging a Finished PDU.
|
||||
@@ -80,13 +81,14 @@ impl AckPdu {
|
||||
condition_code: ConditionCode,
|
||||
transaction_status: TransactionStatus,
|
||||
) -> Self {
|
||||
// Unwrap okay here, [new] can only fail on invalid directive codes.
|
||||
Self::new(
|
||||
pdu_header,
|
||||
FileDirectiveType::Finished,
|
||||
condition_code,
|
||||
transaction_status,
|
||||
)
|
||||
.expect("only fails when directive codes are invalid")
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// PDU header.
|
||||
@@ -228,8 +230,8 @@ impl WritablePduPacket for AckPdu {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::cfdp::{
|
||||
pdu::tests::{common_pdu_conf, verify_raw_header, TEST_DEST_ID, TEST_SEQ_NUM, TEST_SRC_ID},
|
||||
LargeFileFlag, PduType, TransmissionMode,
|
||||
pdu::tests::{TEST_DEST_ID, TEST_SEQ_NUM, TEST_SRC_ID, common_pdu_conf, verify_raw_header},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
+4
-4
@@ -1,11 +1,11 @@
|
||||
//! # End-of-File (EOF) PDU packet implementation.
|
||||
use crate::ByteConversionError;
|
||||
use crate::cfdp::pdu::{
|
||||
FileDirectiveType, PduError, PduHeader, add_pdu_crc, generic_length_checks_pdu_deserialization,
|
||||
read_fss_field, write_fss_field,
|
||||
add_pdu_crc, generic_length_checks_pdu_deserialization, read_fss_field, write_fss_field,
|
||||
FileDirectiveType, PduError, PduHeader,
|
||||
};
|
||||
use crate::cfdp::tlv::{EntityIdTlv, WritableTlv};
|
||||
use crate::cfdp::{ConditionCode, CrcFlag, Direction, LargeFileFlag};
|
||||
use crate::ByteConversionError;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -205,7 +205,7 @@ impl WritablePduPacket for EofPdu {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::cfdp::pdu::tests::{
|
||||
TEST_DEST_ID, TEST_SEQ_NUM, TEST_SRC_ID, common_pdu_conf, verify_raw_header,
|
||||
common_pdu_conf, verify_raw_header, TEST_DEST_ID, TEST_SEQ_NUM, TEST_SRC_ID,
|
||||
};
|
||||
use crate::cfdp::pdu::{FileDirectiveType, PduHeader};
|
||||
use crate::cfdp::{ConditionCode, CrcFlag, LargeFileFlag, PduType, TransmissionMode};
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
//! # File Data PDU packet implementation
|
||||
use crate::ByteConversionError;
|
||||
use crate::cfdp::pdu::{
|
||||
PduError, PduHeader, add_pdu_crc, generic_length_checks_pdu_deserialization, read_fss_field,
|
||||
write_fss_field,
|
||||
add_pdu_crc, generic_length_checks_pdu_deserialization, read_fss_field, write_fss_field,
|
||||
PduError, PduHeader,
|
||||
};
|
||||
use crate::cfdp::{CrcFlag, LargeFileFlag, PduType, SegmentMetadataFlag};
|
||||
use crate::ByteConversionError;
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -135,8 +135,8 @@ impl FdPduBase<'_> {
|
||||
if self.pdu_header.pdu_conf.file_flag == LargeFileFlag::Large {
|
||||
len += 4;
|
||||
}
|
||||
if let Some(segment_metadata) = self.segment_metadata {
|
||||
len += segment_metadata.len_written()
|
||||
if self.segment_metadata.is_some() {
|
||||
len += self.segment_metadata.as_ref().unwrap().len_written()
|
||||
}
|
||||
len += file_data_len as usize;
|
||||
if self.crc_flag() == CrcFlag::WithCrc {
|
||||
@@ -147,8 +147,12 @@ impl FdPduBase<'_> {
|
||||
|
||||
fn write_common_fields_to_bytes(&self, buf: &mut [u8]) -> Result<usize, PduError> {
|
||||
let mut current_idx = self.pdu_header.write_to_bytes(buf)?;
|
||||
if let Some(segment_metadata) = self.segment_metadata {
|
||||
current_idx += segment_metadata.write_to_bytes(&mut buf[current_idx..])?;
|
||||
if self.segment_metadata.is_some() {
|
||||
current_idx += self
|
||||
.segment_metadata
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.write_to_bytes(&mut buf[current_idx..])?;
|
||||
}
|
||||
current_idx += write_fss_field(
|
||||
self.pdu_header.common_pdu_conf().file_flag,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
//! # Finished PDU packet implementation.
|
||||
use crate::ByteConversionError;
|
||||
use crate::cfdp::pdu::{
|
||||
FileDirectiveType, PduError, PduHeader, add_pdu_crc, generic_length_checks_pdu_deserialization,
|
||||
add_pdu_crc, generic_length_checks_pdu_deserialization, FileDirectiveType, PduError, PduHeader,
|
||||
};
|
||||
use crate::cfdp::tlv::{
|
||||
EntityIdTlv, FilestoreResponseTlv, GenericTlv, Tlv, TlvType, TlvTypeField, WritableTlv,
|
||||
};
|
||||
use crate::cfdp::{ConditionCode, CrcFlag, Direction, PduType};
|
||||
use crate::ByteConversionError;
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -453,7 +453,7 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::cfdp::lv::Lv;
|
||||
use crate::cfdp::pdu::tests::{
|
||||
TEST_DEST_ID, TEST_SEQ_NUM, TEST_SRC_ID, common_pdu_conf, verify_raw_header,
|
||||
common_pdu_conf, verify_raw_header, TEST_DEST_ID, TEST_SEQ_NUM, TEST_SRC_ID,
|
||||
};
|
||||
use crate::cfdp::pdu::{FileDirectiveType, PduHeader};
|
||||
use crate::cfdp::tlv::FilestoreResponseTlv;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
//! # Metadata PDU packet implementation.
|
||||
#[cfg(feature = "alloc")]
|
||||
use super::tlv::TlvOwned;
|
||||
use crate::ByteConversionError;
|
||||
use crate::cfdp::lv::Lv;
|
||||
use crate::cfdp::pdu::{
|
||||
FileDirectiveType, PduError, PduHeader, add_pdu_crc, generic_length_checks_pdu_deserialization,
|
||||
read_fss_field, write_fss_field,
|
||||
add_pdu_crc, generic_length_checks_pdu_deserialization, read_fss_field, write_fss_field,
|
||||
FileDirectiveType, PduError, PduHeader,
|
||||
};
|
||||
use crate::cfdp::tlv::{Tlv, WritableTlv};
|
||||
use crate::cfdp::{ChecksumType, CrcFlag, Direction, LargeFileFlag, PduType};
|
||||
use crate::ByteConversionError;
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::vec::Vec;
|
||||
#[cfg(feature = "serde")]
|
||||
@@ -418,11 +418,11 @@ mod tests {
|
||||
|
||||
use crate::cfdp::lv::Lv;
|
||||
use crate::cfdp::pdu::metadata::{
|
||||
MetadataGenericParams, MetadataPduCreator, MetadataPduReader,
|
||||
build_metadata_opts_from_slice, build_metadata_opts_from_vec,
|
||||
build_metadata_opts_from_slice, build_metadata_opts_from_vec, MetadataGenericParams,
|
||||
MetadataPduCreator, MetadataPduReader,
|
||||
};
|
||||
use crate::cfdp::pdu::tests::{
|
||||
TEST_DEST_ID, TEST_SEQ_NUM, TEST_SRC_ID, common_pdu_conf, verify_raw_header,
|
||||
common_pdu_conf, verify_raw_header, TEST_DEST_ID, TEST_SEQ_NUM, TEST_SRC_ID,
|
||||
};
|
||||
use crate::cfdp::pdu::{CfdpPdu, PduError, WritablePduPacket};
|
||||
use crate::cfdp::pdu::{FileDirectiveType, PduHeader};
|
||||
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
//! CFDP Packet Data Unit (PDU) support.
|
||||
use crate::ByteConversionError;
|
||||
use crate::cfdp::pdu::ack::InvalidAckedDirectiveCodeError;
|
||||
use crate::cfdp::pdu::nak::InvalidStartOrEndOfScopeError;
|
||||
use crate::cfdp::*;
|
||||
use crate::crc::CRC_CCITT_FALSE;
|
||||
use crate::util::{UnsignedByteField, UnsignedByteFieldU8, UnsignedEnum};
|
||||
use crate::ByteConversionError;
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::vec::Vec;
|
||||
|
||||
@@ -725,15 +725,15 @@ pub(crate) fn add_pdu_crc(buf: &mut [u8], mut current_idx: usize) -> usize {
|
||||
mod tests {
|
||||
use alloc::string::ToString;
|
||||
|
||||
use crate::ByteConversionError;
|
||||
use crate::cfdp::pdu::{CommonPduConfig, FIXED_HEADER_LEN, PduError, PduHeader};
|
||||
use crate::cfdp::pdu::{CommonPduConfig, PduError, PduHeader, FIXED_HEADER_LEN};
|
||||
use crate::cfdp::{
|
||||
CFDP_VERSION_2, CrcFlag, Direction, LargeFileFlag, PduType, SegmentMetadataFlag,
|
||||
SegmentationControl, TransmissionMode,
|
||||
CrcFlag, Direction, LargeFileFlag, PduType, SegmentMetadataFlag, SegmentationControl,
|
||||
TransmissionMode, CFDP_VERSION_2,
|
||||
};
|
||||
use crate::util::{
|
||||
UbfU8, UbfU16, UnsignedByteField, UnsignedByteFieldU8, UnsignedByteFieldU16, UnsignedEnum,
|
||||
UbfU16, UbfU8, UnsignedByteField, UnsignedByteFieldU16, UnsignedByteFieldU8, UnsignedEnum,
|
||||
};
|
||||
use crate::ByteConversionError;
|
||||
use std::format;
|
||||
|
||||
pub(crate) const TEST_SRC_ID: UbfU8 = UbfU8::new(5);
|
||||
|
||||
+4
-4
@@ -1,12 +1,12 @@
|
||||
//! # NAK PDU packet implementation.
|
||||
use crate::{
|
||||
ByteConversionError,
|
||||
cfdp::{CrcFlag, Direction, LargeFileFlag},
|
||||
ByteConversionError,
|
||||
};
|
||||
|
||||
use super::{
|
||||
CfdpPdu, FileDirectiveType, PduError, PduHeader, WritablePduPacket, add_pdu_crc,
|
||||
generic_length_checks_pdu_deserialization,
|
||||
add_pdu_crc, generic_length_checks_pdu_deserialization, CfdpPdu, FileDirectiveType, PduError,
|
||||
PduHeader, WritablePduPacket,
|
||||
};
|
||||
|
||||
/// Invalid start or end of scope value.
|
||||
@@ -761,8 +761,8 @@ mod tests {
|
||||
use alloc::string::ToString;
|
||||
|
||||
use crate::cfdp::{
|
||||
pdu::tests::{common_pdu_conf, verify_raw_header, TEST_DEST_ID, TEST_SEQ_NUM, TEST_SRC_ID},
|
||||
PduType, TransmissionMode,
|
||||
pdu::tests::{TEST_DEST_ID, TEST_SEQ_NUM, TEST_SRC_ID, common_pdu_conf, verify_raw_header},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
+5
-5
@@ -1,10 +1,10 @@
|
||||
//! Generic CFDP type-length-value (TLV) abstraction as specified in CFDP 5.1.9.
|
||||
use crate::ByteConversionError;
|
||||
use crate::cfdp::TlvLvError;
|
||||
use crate::cfdp::lv::{
|
||||
Lv, MIN_LV_LEN, generic_len_check_data_serialization, generic_len_check_deserialization,
|
||||
generic_len_check_data_serialization, generic_len_check_deserialization, Lv, MIN_LV_LEN,
|
||||
};
|
||||
use crate::cfdp::TlvLvError;
|
||||
use crate::util::{UnsignedByteField, UnsignedByteFieldError, UnsignedEnum};
|
||||
use crate::ByteConversionError;
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::vec;
|
||||
#[cfg(feature = "alloc")]
|
||||
@@ -1015,10 +1015,10 @@ pub(crate) fn verify_tlv_type(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::cfdp::TlvLvError;
|
||||
use crate::cfdp::lv::Lv;
|
||||
use crate::cfdp::tlv::{FilestoreActionCode, FilestoreRequestTlv, Tlv, TlvType, TlvTypeField};
|
||||
use crate::util::{UbfU8, UbfU16, UnsignedEnum};
|
||||
use crate::cfdp::TlvLvError;
|
||||
use crate::util::{UbfU16, UbfU8, UnsignedEnum};
|
||||
use alloc::string::ToString;
|
||||
|
||||
const TLV_TEST_STR_0: &str = "hello.txt";
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
use super::TlvOwned;
|
||||
use super::{GenericTlv, ReadableTlv, Tlv, TlvLvError, TlvType, TlvTypeField, WritableTlv};
|
||||
use crate::{
|
||||
ByteConversionError,
|
||||
cfdp::{InvalidTlvTypeFieldError, TlvLvDataTooLargeError},
|
||||
ByteConversionError,
|
||||
};
|
||||
use delegate::delegate;
|
||||
|
||||
|
||||
+4
-5
@@ -4,8 +4,8 @@
|
||||
//! You can find the PUS telecommand types in the [tc] module and the the PUS telemetry
|
||||
//! types inside the [tm] module.
|
||||
use crate::{
|
||||
ByteConversionError, CcsdsPacket,
|
||||
crc::{CRC_CCITT_FALSE, CRC_CCITT_FALSE_NO_TABLE},
|
||||
ByteConversionError, CcsdsPacket,
|
||||
};
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::vec::Vec;
|
||||
@@ -197,9 +197,8 @@ pub enum PusError {
|
||||
#[error("checksum verification for crc16 {0:#06x} failed")]
|
||||
ChecksumFailure(u16),
|
||||
/// CRC16 needs to be calculated first
|
||||
#[error("crc16 was not calculated")]
|
||||
CrcCalculationMissing,
|
||||
/// Raised when converting to and from raw byte slices
|
||||
//#[error("crc16 was not calculated")]
|
||||
//CrcCalculationMissing,
|
||||
#[error("pus error: {0}")]
|
||||
ByteConversion(#[from] ByteConversionError),
|
||||
}
|
||||
@@ -529,8 +528,8 @@ impl Default for CreatorConfig {
|
||||
mod tests {
|
||||
use alloc::string::ToString;
|
||||
|
||||
use crate::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU8, UnsignedEnum};
|
||||
use crate::ByteConversionError;
|
||||
use crate::ecss::{EcssEnumU8, EcssEnumU16, EcssEnumU32, UnsignedEnum};
|
||||
|
||||
use super::*;
|
||||
#[cfg(feature = "serde")]
|
||||
|
||||
+29
-28
@@ -42,20 +42,25 @@
|
||||
//! assert_eq!(pus_tc_by_builder, pus_tc);
|
||||
//! ```
|
||||
use crate::crc::{CRC_CCITT_FALSE, CRC_CCITT_FALSE_NO_TABLE};
|
||||
pub use crate::ecss::{CreatorConfig, MessageTypeId};
|
||||
use crate::ecss::{
|
||||
PusError, PusPacket, PusVersion, WritablePusPacket, crc_from_raw_data, sp_header_impls,
|
||||
user_data_from_raw, verify_crc16_ccitt_false_from_raw_to_pus_error,
|
||||
crc_from_raw_data, sp_header_impls, user_data_from_raw,
|
||||
verify_crc16_ccitt_false_from_raw_to_pus_error, PusError, PusPacket, PusVersion,
|
||||
WritablePusPacket,
|
||||
};
|
||||
use crate::{ByteConversionError, CCSDS_HEADER_LEN, CcsdsPacket, PacketType, SequenceFlags};
|
||||
pub use crate::ecss::{CreatorConfig, MessageTypeId};
|
||||
use crate::{ByteConversionError, CcsdsPacket, PacketType, SequenceFlags, CCSDS_HEADER_LEN};
|
||||
use crate::{PacketId, PacketSequenceControl, SpHeader};
|
||||
use arbitrary_int::{u3, u4, u11, u14};
|
||||
use arbitrary_int::{u11, u14, u3, u4};
|
||||
use core::mem::size_of;
|
||||
use delegate::delegate;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zerocopy::{FromBytes, IntoBytes};
|
||||
|
||||
// Is necessary for some reason, possibly bug.
|
||||
#[cfg(feature = "defmt")]
|
||||
use arbitrary_int::traits::Integer;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::vec::Vec;
|
||||
|
||||
@@ -132,7 +137,7 @@ pub mod zc {
|
||||
use crate::ecss::{MessageTypeId, PusError, PusVersion};
|
||||
use arbitrary_int::traits::Integer;
|
||||
use arbitrary_int::u4;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, NetworkEndian, U16, Unaligned};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, NetworkEndian, Unaligned, U16};
|
||||
|
||||
/// PUS TC secondary header.
|
||||
#[derive(FromBytes, IntoBytes, Immutable, Unaligned)]
|
||||
@@ -147,7 +152,7 @@ pub mod zc {
|
||||
impl TryFrom<crate::ecss::tc::PusTcSecondaryHeader> for PusTcSecondaryHeader {
|
||||
type Error = PusError;
|
||||
fn try_from(value: crate::ecss::tc::PusTcSecondaryHeader) -> Result<Self, Self::Error> {
|
||||
if !matches!(value.version, PusVersion::PusC) {
|
||||
if value.version != PusVersion::PusC {
|
||||
return Err(PusError::VersionNotSupported(value.version.raw_value()));
|
||||
}
|
||||
Ok(PusTcSecondaryHeader {
|
||||
@@ -417,8 +422,7 @@ impl<'app_data> PusTcCreator<'app_data> {
|
||||
let mut digest = CRC_CCITT_FALSE.digest();
|
||||
let sph_zc = crate::zc::SpHeader::from(self.sp_header);
|
||||
digest.update(sph_zc.as_bytes());
|
||||
let pus_tc_header = zc::PusTcSecondaryHeader::try_from(self.sec_header)
|
||||
.expect("the PUS version is hardcoded to PUS C");
|
||||
let pus_tc_header = zc::PusTcSecondaryHeader::try_from(self.sec_header).unwrap();
|
||||
digest.update(pus_tc_header.as_bytes());
|
||||
digest.update(self.app_data);
|
||||
digest.finalize()
|
||||
@@ -429,8 +433,7 @@ impl<'app_data> PusTcCreator<'app_data> {
|
||||
let mut digest = CRC_CCITT_FALSE_NO_TABLE.digest();
|
||||
let sph_zc = crate::zc::SpHeader::from(self.sp_header);
|
||||
digest.update(sph_zc.as_bytes());
|
||||
let pus_tc_header = zc::PusTcSecondaryHeader::try_from(self.sec_header)
|
||||
.expect("the PUS version is hardcoded to PUS C");
|
||||
let pus_tc_header = zc::PusTcSecondaryHeader::try_from(self.sec_header).unwrap();
|
||||
digest.update(pus_tc_header.as_bytes());
|
||||
digest.update(self.app_data);
|
||||
digest.finalize()
|
||||
@@ -451,8 +454,7 @@ impl<'app_data> PusTcCreator<'app_data> {
|
||||
let start_idx = vec.len();
|
||||
vec.extend_from_slice(sph_zc.as_bytes());
|
||||
// The PUS version is hardcoded to PUS C
|
||||
let pus_tc_header = zc::PusTcSecondaryHeader::try_from(self.sec_header)
|
||||
.expect("the PUS version is hardcoded to PUS C");
|
||||
let pus_tc_header = zc::PusTcSecondaryHeader::try_from(self.sec_header).unwrap();
|
||||
vec.extend_from_slice(pus_tc_header.as_bytes());
|
||||
vec.extend_from_slice(self.app_data);
|
||||
if self.has_checksum() {
|
||||
@@ -666,11 +668,11 @@ impl<'buf> PusTcCreatorWithReservedAppData<'buf> {
|
||||
sp_header.write_to_be_bytes(&mut buf[0..CCSDS_HEADER_LEN])?;
|
||||
curr_idx += CCSDS_HEADER_LEN;
|
||||
let sec_header_len = size_of::<zc::PusTcSecondaryHeader>();
|
||||
let sec_header_zc = zc::PusTcSecondaryHeader::try_from(sec_header)
|
||||
.expect("the PUS version is hardcoded to PUS C");
|
||||
let sec_header_zc = zc::PusTcSecondaryHeader::try_from(sec_header).unwrap();
|
||||
// Unwrap okay, this can not fail.
|
||||
sec_header_zc
|
||||
.write_to(&mut buf[curr_idx..curr_idx + sec_header_len])
|
||||
.expect("buffer is large enough for secondary header");
|
||||
.unwrap();
|
||||
curr_idx += sec_header_len;
|
||||
let app_data_offset = curr_idx;
|
||||
curr_idx += app_data_len;
|
||||
@@ -918,10 +920,8 @@ impl<'raw_data> PusTcReader<'raw_data> {
|
||||
/// a CRC-16-CCITT checksum which is also verified.
|
||||
pub fn new(slice: &'raw_data [u8]) -> Result<Self, PusError> {
|
||||
let pus_tc = Self::new_no_checksum_verification(slice, true)?;
|
||||
verify_crc16_ccitt_false_from_raw_to_pus_error(
|
||||
pus_tc.raw_data(),
|
||||
pus_tc.crc16().ok_or(PusError::CrcCalculationMissing)?,
|
||||
)?;
|
||||
// Unwrap for CRC16 okay, should always have some value.
|
||||
verify_crc16_ccitt_false_from_raw_to_pus_error(pus_tc.raw_data(), pus_tc.crc16().unwrap())?;
|
||||
Ok(pus_tc)
|
||||
}
|
||||
|
||||
@@ -929,9 +929,10 @@ impl<'raw_data> PusTcReader<'raw_data> {
|
||||
/// binary size and memory usage.
|
||||
pub fn new_checksum_no_table(slice: &'raw_data [u8]) -> Result<Self, PusError> {
|
||||
let pus_tc = Self::new_no_checksum_verification(slice, true)?;
|
||||
// Unwrap for CRC16 okay, should always have some value.
|
||||
verify_crc16_ccitt_false_from_raw_to_pus_error_no_table(
|
||||
pus_tc.raw_data(),
|
||||
pus_tc.crc16().ok_or(PusError::CrcCalculationMissing)?,
|
||||
pus_tc.crc16().unwrap(),
|
||||
)?;
|
||||
Ok(pus_tc)
|
||||
}
|
||||
@@ -979,10 +980,10 @@ impl<'raw_data> PusTcReader<'raw_data> {
|
||||
.unwrap();
|
||||
current_idx += PUC_TC_SECONDARY_HEADER_LEN;
|
||||
let raw_data = &slice[0..total_len];
|
||||
let crc16 = match has_checksum {
|
||||
true => Some(crc_from_raw_data(&slice[total_len - 2..total_len])?),
|
||||
false => None,
|
||||
};
|
||||
let mut crc16 = None;
|
||||
if has_checksum {
|
||||
crc16 = Some(crc_from_raw_data(&slice[total_len - 2..total_len])?);
|
||||
}
|
||||
Ok(Self {
|
||||
sp_header,
|
||||
sec_header: PusTcSecondaryHeader::try_from(sec_header).unwrap(),
|
||||
@@ -994,13 +995,13 @@ impl<'raw_data> PusTcReader<'raw_data> {
|
||||
|
||||
/// Application data slice.
|
||||
#[inline]
|
||||
pub fn app_data(&self) -> &'raw_data [u8] {
|
||||
self.app_data
|
||||
pub fn app_data(&self) -> &[u8] {
|
||||
self.user_data()
|
||||
}
|
||||
|
||||
/// Full raw data slice.
|
||||
#[inline]
|
||||
pub fn raw_data(&self) -> &'raw_data [u8] {
|
||||
pub fn raw_data(&self) -> &[u8] {
|
||||
self.raw_data
|
||||
}
|
||||
|
||||
|
||||
+11
-10
@@ -33,16 +33,17 @@
|
||||
//! assert_eq!(pus_tc.message_subtype_id(), 1);
|
||||
//! assert_eq!(pus_tc.apid().value(), 0x02);
|
||||
//! ```
|
||||
use crate::SpHeader;
|
||||
use crate::crc::{CRC_CCITT_FALSE, CRC_CCITT_FALSE_NO_TABLE};
|
||||
use crate::ecss::tc::{ACK_ALL, AckFlags};
|
||||
use crate::ecss::tc::{AckFlags, ACK_ALL};
|
||||
use crate::ecss::{
|
||||
MessageTypeId, PusError, PusPacket, PusVersion, WritablePusPacket, crc_from_raw_data,
|
||||
sp_header_impls, user_data_from_raw, verify_crc16_ccitt_false_from_raw_to_pus_error,
|
||||
crc_from_raw_data, sp_header_impls, user_data_from_raw,
|
||||
verify_crc16_ccitt_false_from_raw_to_pus_error, MessageTypeId, PusError, PusPacket, PusVersion,
|
||||
WritablePusPacket,
|
||||
};
|
||||
use crate::util::{UnsignedByteField, UnsignedEnum};
|
||||
use crate::{ByteConversionError, CCSDS_HEADER_LEN, CcsdsPacket, PacketType, SequenceFlags};
|
||||
use arbitrary_int::{u3, u4, u11, u14};
|
||||
use crate::SpHeader;
|
||||
use crate::{ByteConversionError, CcsdsPacket, PacketType, SequenceFlags, CCSDS_HEADER_LEN};
|
||||
use arbitrary_int::{u11, u14, u3, u4};
|
||||
use core::mem::size_of;
|
||||
use delegate::delegate;
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
@@ -791,13 +792,13 @@ impl<'raw_data> PusTcReader<'raw_data> {
|
||||
|
||||
/// Application data slice.
|
||||
#[inline]
|
||||
pub fn app_data(&self) -> &'raw_data [u8] {
|
||||
self.app_data
|
||||
pub fn app_data(&self) -> &[u8] {
|
||||
self.user_data()
|
||||
}
|
||||
|
||||
/// Full raw data slice.
|
||||
#[inline]
|
||||
pub fn raw_data(&self) -> &'raw_data [u8] {
|
||||
pub fn raw_data(&self) -> &[u8] {
|
||||
self.raw_data
|
||||
}
|
||||
|
||||
@@ -921,7 +922,7 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
use crate::ecss::{PusError, PusPacket, WritablePusPacket};
|
||||
use crate::util::{UnsignedByteFieldU8, UnsignedByteFieldU16};
|
||||
use crate::util::{UnsignedByteFieldU16, UnsignedByteFieldU8};
|
||||
use crate::{ByteConversionError, SpHeader};
|
||||
use crate::{CcsdsPacket, SequenceFlags};
|
||||
use alloc::string::ToString;
|
||||
|
||||
+16
-15
@@ -51,17 +51,18 @@
|
||||
//! assert_eq!(pus_tm_by_builder, ping_tm);
|
||||
//! ```
|
||||
use crate::crc::{CRC_CCITT_FALSE, CRC_CCITT_FALSE_NO_TABLE};
|
||||
pub use crate::ecss::{CreatorConfig, MessageTypeId};
|
||||
use crate::ecss::{
|
||||
PusError, PusPacket, PusVersion, WritablePusPacket, calc_pus_crc16, crc_from_raw_data,
|
||||
sp_header_impls, user_data_from_raw, verify_crc16_ccitt_false_from_raw_to_pus_error,
|
||||
calc_pus_crc16, crc_from_raw_data, sp_header_impls, user_data_from_raw,
|
||||
verify_crc16_ccitt_false_from_raw_to_pus_error, PusError, PusPacket, PusVersion,
|
||||
WritablePusPacket,
|
||||
};
|
||||
pub use crate::ecss::{CreatorConfig, MessageTypeId};
|
||||
use crate::{
|
||||
ByteConversionError, CCSDS_HEADER_LEN, CcsdsPacket, MAX_APID, PacketId, PacketSequenceControl,
|
||||
PacketType, SequenceFlags, SpHeader,
|
||||
ByteConversionError, CcsdsPacket, PacketId, PacketSequenceControl, PacketType, SequenceFlags,
|
||||
SpHeader, CCSDS_HEADER_LEN, MAX_APID,
|
||||
};
|
||||
use arbitrary_int::traits::Integer;
|
||||
use arbitrary_int::{u3, u4, u11, u14};
|
||||
use arbitrary_int::{u11, u14, u3, u4};
|
||||
use core::mem::size_of;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -117,7 +118,7 @@ pub mod zc {
|
||||
use super::GenericPusTmSecondaryHeader;
|
||||
use crate::ecss::{MessageTypeId, PusError, PusVersion};
|
||||
use arbitrary_int::{traits::Integer as _, u4};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, NetworkEndian, U16, Unaligned};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, NetworkEndian, Unaligned, U16};
|
||||
|
||||
/// PUS TM secondary header without a timestamp.
|
||||
#[derive(FromBytes, IntoBytes, Immutable, Unaligned)]
|
||||
@@ -1107,7 +1108,7 @@ impl<'raw_data> PusTmReader<'raw_data> {
|
||||
}
|
||||
Ok(Self {
|
||||
sp_header,
|
||||
sec_header: PusTmSecondaryHeader::try_from(zc_sec_header_wrapper)?,
|
||||
sec_header: PusTmSecondaryHeader::try_from(zc_sec_header_wrapper).unwrap(),
|
||||
raw_data,
|
||||
source_data: user_data_from_raw(
|
||||
current_idx,
|
||||
@@ -1127,8 +1128,8 @@ impl<'raw_data> PusTmReader<'raw_data> {
|
||||
|
||||
/// Source data slice.
|
||||
#[inline]
|
||||
pub fn source_data(&self) -> &'raw_data [u8] {
|
||||
self.source_data
|
||||
pub fn source_data(&self) -> &[u8] {
|
||||
self.user_data()
|
||||
}
|
||||
|
||||
/// Service type ID.
|
||||
@@ -1157,7 +1158,7 @@ impl<'raw_data> PusTmReader<'raw_data> {
|
||||
|
||||
/// Raw timestamp slice.
|
||||
#[inline]
|
||||
pub fn timestamp(&self) -> &'raw_data [u8] {
|
||||
pub fn timestamp(&self) -> &[u8] {
|
||||
self.sec_header.timestamp
|
||||
}
|
||||
|
||||
@@ -1169,7 +1170,7 @@ impl<'raw_data> PusTmReader<'raw_data> {
|
||||
|
||||
/// This function will return the slice [Self] was constructed from.
|
||||
#[inline]
|
||||
pub fn raw_data(&self) -> &'raw_data [u8] {
|
||||
pub fn raw_data(&self) -> &[u8] {
|
||||
self.raw_data
|
||||
}
|
||||
}
|
||||
@@ -1489,11 +1490,11 @@ impl GenericPusTmSecondaryHeader for PusTmZeroCopyWriter<'_> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::SpHeader;
|
||||
use crate::time::cds::CdsTime;
|
||||
#[cfg(feature = "serde")]
|
||||
use crate::time::CcsdsTimeProvider;
|
||||
use crate::time::cds::CdsTime;
|
||||
use crate::{MAX_SEQ_COUNT, ecss::PusVersion::PusC};
|
||||
use crate::SpHeader;
|
||||
use crate::{ecss::PusVersion::PusC, MAX_SEQ_COUNT};
|
||||
use alloc::string::ToString;
|
||||
#[cfg(feature = "serde")]
|
||||
use postcard::{from_bytes, to_allocvec};
|
||||
|
||||
+19
-16
@@ -50,17 +50,17 @@
|
||||
use crate::crc::{CRC_CCITT_FALSE, CRC_CCITT_FALSE_NO_TABLE};
|
||||
use crate::ecss::tm::IsPusTelemetry;
|
||||
use crate::ecss::{
|
||||
CrcType, MessageTypeId, PusError, PusPacket, PusVersion, WritablePusPacket, calc_pus_crc16,
|
||||
crc_from_raw_data, sp_header_impls, user_data_from_raw,
|
||||
verify_crc16_ccitt_false_from_raw_to_pus_error,
|
||||
calc_pus_crc16, crc_from_raw_data, sp_header_impls, user_data_from_raw,
|
||||
verify_crc16_ccitt_false_from_raw_to_pus_error, CrcType, MessageTypeId, PusError, PusPacket,
|
||||
PusVersion, WritablePusPacket,
|
||||
};
|
||||
use crate::util::{UnsignedByteField, UnsignedEnum};
|
||||
use crate::{
|
||||
ByteConversionError, CCSDS_HEADER_LEN, CcsdsPacket, MAX_APID, PacketType, SequenceFlags,
|
||||
SpHeader,
|
||||
ByteConversionError, CcsdsPacket, PacketType, SequenceFlags, SpHeader, CCSDS_HEADER_LEN,
|
||||
MAX_APID,
|
||||
};
|
||||
use arbitrary_int::traits::Integer;
|
||||
use arbitrary_int::{u3, u4, u11, u14};
|
||||
use arbitrary_int::{u11, u14, u3, u4};
|
||||
use core::mem::size_of;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -192,8 +192,11 @@ impl<'stamp> PusTmSecondaryHeader<'stamp> {
|
||||
.into());
|
||||
}
|
||||
let pus_version = PusVersion::try_from(u4::new((buf[0] >> 4) & 0x0F));
|
||||
let pus_version = pus_version.map_err(PusError::VersionNotSupported)?;
|
||||
if !matches!(pus_version, PusVersion::PusA) {
|
||||
if let Err(version_raw) = pus_version {
|
||||
return Err(PusError::VersionNotSupported(version_raw));
|
||||
}
|
||||
let pus_version = pus_version.unwrap();
|
||||
if pus_version != PusVersion::PusA {
|
||||
return Err(PusError::VersionNotSupported(pus_version.raw_value()));
|
||||
}
|
||||
let mut msg_counter = None;
|
||||
@@ -463,9 +466,9 @@ impl<'time, 'src_data> PusTmCreator<'time, 'src_data> {
|
||||
if let Some(dest_id) = self.sec_header.dest_id {
|
||||
let mut dest_id_buf: [u8; core::mem::size_of::<u64>()] =
|
||||
[0; core::mem::size_of::<u64>()];
|
||||
let len = dest_id
|
||||
.write_to_be_bytes(&mut dest_id_buf)
|
||||
.expect("buffer is maximum possible size; this operation cannot fail");
|
||||
// Unwrap okay, this can never fail because we created a buffer with the largest
|
||||
// possible size.
|
||||
let len = dest_id.write_to_be_bytes(&mut dest_id_buf).unwrap();
|
||||
digest.update(&dest_id_buf[0..len]);
|
||||
}
|
||||
digest.update(self.sec_header.timestamp);
|
||||
@@ -871,13 +874,13 @@ impl<'raw_data> PusTmReader<'raw_data> {
|
||||
|
||||
/// Raw source data slice.
|
||||
#[inline]
|
||||
pub fn source_data(&self) -> &'raw_data [u8] {
|
||||
self.source_data
|
||||
pub fn source_data(&self) -> &[u8] {
|
||||
self.user_data()
|
||||
}
|
||||
|
||||
/// Raw timestamp slice.
|
||||
#[inline]
|
||||
pub fn timestamp(&self) -> &'raw_data [u8] {
|
||||
pub fn timestamp(&self) -> &[u8] {
|
||||
self.sec_header.timestamp
|
||||
}
|
||||
|
||||
@@ -889,7 +892,7 @@ impl<'raw_data> PusTmReader<'raw_data> {
|
||||
|
||||
/// This function will return the slice [Self] was constructed from.
|
||||
#[inline]
|
||||
pub fn raw_data(&self) -> &'raw_data [u8] {
|
||||
pub fn raw_data(&self) -> &[u8] {
|
||||
self.raw_data
|
||||
}
|
||||
}
|
||||
@@ -1232,8 +1235,8 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
use crate::time::cds::CdsTime;
|
||||
use crate::{MAX_SEQ_COUNT, SpHeader};
|
||||
use crate::{ecss::PusVersion::PusA, util::UnsignedByteFieldU16};
|
||||
use crate::{SpHeader, MAX_SEQ_COUNT};
|
||||
#[cfg(feature = "serde")]
|
||||
use postcard::{from_bytes, to_allocvec};
|
||||
|
||||
|
||||
+46
-254
@@ -60,7 +60,6 @@
|
||||
//! println!("{:x?}", &ccsds_buf[0..6]);
|
||||
//! ```
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![warn(missing_docs)]
|
||||
#[cfg(feature = "alloc")]
|
||||
@@ -691,8 +690,8 @@ impl SpacePacketHeader {
|
||||
expected: CCSDS_HEADER_LEN,
|
||||
});
|
||||
}
|
||||
let zc_header = zc::SpHeader::read_from_bytes(&buf[0..Self::LENGTH])
|
||||
.expect("zerocopy read failed unexpectedly");
|
||||
// Unwrap okay, this can not fail.
|
||||
let zc_header = zc::SpHeader::read_from_bytes(&buf[0..Self::LENGTH]).unwrap();
|
||||
Ok((Self::from(zc_header), &buf[Self::LENGTH..]))
|
||||
}
|
||||
|
||||
@@ -785,7 +784,7 @@ pub mod zc {
|
||||
use arbitrary_int::traits::Integer;
|
||||
use arbitrary_int::u3;
|
||||
use zerocopy::byteorder::NetworkEndian;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, U16, Unaligned};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, Unaligned, U16};
|
||||
|
||||
/// [zerocopy] space packet header.
|
||||
#[derive(FromBytes, IntoBytes, Immutable, Unaligned, Debug)]
|
||||
@@ -1251,8 +1250,9 @@ impl CcsdsPacketCreatorCommon {
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn to_vec(&self, len_written: usize, packet_data: &[u8]) -> alloc::vec::Vec<u8> {
|
||||
let mut vec = alloc::vec![0u8; len_written];
|
||||
// Can not fail, unless we messed up the len_written method..
|
||||
self.write_to_bytes(&mut vec, len_written, packet_data)
|
||||
.expect("buffer size shall match the len_written");
|
||||
.unwrap();
|
||||
vec
|
||||
}
|
||||
}
|
||||
@@ -1571,16 +1571,7 @@ impl<'buf> CcsdsPacketReader<'buf> {
|
||||
buf: &'buf [u8],
|
||||
checksum_type: Option<ChecksumType>,
|
||||
) -> Result<Self, CcsdsPacketReadError> {
|
||||
if buf.len() < CCSDS_HEADER_LEN {
|
||||
return Err(ByteConversionError::FromSliceTooSmall {
|
||||
found: buf.len(),
|
||||
expected: CCSDS_HEADER_LEN,
|
||||
}
|
||||
.into());
|
||||
}
|
||||
let sp_header = SpHeader::from_be_bytes(&buf[0..CCSDS_HEADER_LEN])
|
||||
.expect("SP header creation failed unexpectedly")
|
||||
.0;
|
||||
let sp_header = SpHeader::from_be_bytes(&buf[0..CCSDS_HEADER_LEN])?.0;
|
||||
if sp_header.packet_len() > buf.len() {
|
||||
return Err(ByteConversionError::FromSliceTooSmall {
|
||||
found: buf.len(),
|
||||
@@ -1631,6 +1622,34 @@ impl CcsdsPacketReader<'_> {
|
||||
self.sp_header.packet_id.packet_type
|
||||
}
|
||||
|
||||
/// Full raw data.
|
||||
#[inline]
|
||||
pub fn raw_data(&self) -> &[u8] {
|
||||
self.raw_data
|
||||
}
|
||||
|
||||
/// Read-only access to the full packet data field.
|
||||
///
|
||||
/// This might also include the checksum but does not include the raw [SpacePacketHeader].
|
||||
/// [Self::user_data] can be used to only retrieve the user data slice without the checksum
|
||||
/// part.
|
||||
#[inline]
|
||||
pub fn packet_data(&self) -> &[u8] {
|
||||
self.raw_data[CCSDS_HEADER_LEN..self.raw_data.len()].as_ref()
|
||||
}
|
||||
|
||||
/// Read-only access to the user data field.
|
||||
///
|
||||
/// This is the [Self::packet_data] without the checksum, if the packet has one.
|
||||
#[inline]
|
||||
pub fn user_data(&self) -> &[u8] {
|
||||
if self.checksum.is_some() {
|
||||
self.packet_data()[0..self.packet_data().len() - 2].as_ref()
|
||||
} else {
|
||||
self.packet_data()
|
||||
}
|
||||
}
|
||||
|
||||
/// 11-bit Application Process ID field.
|
||||
#[inline]
|
||||
pub fn apid(&self) -> u11 {
|
||||
@@ -1668,36 +1687,6 @@ impl CcsdsPacketReader<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'buf> CcsdsPacketReader<'buf> {
|
||||
/// Full raw data.
|
||||
#[inline]
|
||||
pub fn raw_data(&self) -> &'buf [u8] {
|
||||
self.raw_data
|
||||
}
|
||||
|
||||
/// Read-only access to the full packet data field.
|
||||
///
|
||||
/// This might also include the checksum but does not include the raw [SpacePacketHeader].
|
||||
/// [Self::user_data] can be used to only retrieve the user data slice without the checksum
|
||||
/// part.
|
||||
#[inline]
|
||||
pub fn packet_data(&self) -> &'buf [u8] {
|
||||
self.raw_data[CCSDS_HEADER_LEN..self.raw_data.len()].as_ref()
|
||||
}
|
||||
|
||||
/// Read-only access to the user data field.
|
||||
///
|
||||
/// This is the [Self::packet_data] without the checksum, if the packet has one.
|
||||
#[inline]
|
||||
pub fn user_data(&self) -> &'buf [u8] {
|
||||
if self.checksum.is_some() {
|
||||
self.packet_data()[0..self.packet_data().len() - 2].as_ref()
|
||||
} else {
|
||||
self.packet_data()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CcsdsPacket for CcsdsPacketReader<'_> {
|
||||
/// CCSDS version field.
|
||||
#[inline]
|
||||
@@ -1724,142 +1713,16 @@ impl CcsdsPacket for CcsdsPacketReader<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// This is a helper structure to update certain fields in a raw CCSDS packet directly in place.
|
||||
/// This can be more efficient than creating a full [CcsdsPacketReader], modifying the fields and
|
||||
/// then writing it back to another buffer using a [CcsdsPacketCreator].
|
||||
///
|
||||
/// Please note that the [Self::finish] method has to be called for the CRC16 to be valid
|
||||
/// after changing fields of the packet if the CCSDS packet has a checksum. Furthermore, the
|
||||
/// constructor of this class will not do any checks except basic length checks to ensure that all
|
||||
/// relevant fields can be updated and all methods can be called without a panic. If a full
|
||||
/// validity check of the PUS TM packet is required, it is recommended to construct a full
|
||||
/// [CcsdsPacketReader] object from the raw bytestream first.
|
||||
pub struct CcsdsZeroCopyWriter<'buf> {
|
||||
buf: &'buf mut [u8],
|
||||
packet_len: usize,
|
||||
checksum: Option<ChecksumType>,
|
||||
}
|
||||
|
||||
impl<'buf> CcsdsZeroCopyWriter<'buf> {
|
||||
/// Constructor which expects the raw buffer containing the CCSDS packet and a checksum.
|
||||
pub fn new(
|
||||
buf: &'buf mut [u8],
|
||||
checksum: Option<ChecksumType>,
|
||||
) -> Result<CcsdsZeroCopyWriter<'buf>, ByteConversionError> {
|
||||
let raw_len = buf.len();
|
||||
if raw_len < CCSDS_HEADER_LEN {
|
||||
return Err(ByteConversionError::FromSliceTooSmall {
|
||||
found: raw_len,
|
||||
expected: CCSDS_HEADER_LEN,
|
||||
});
|
||||
}
|
||||
let sp_header = crate::zc::SpHeader::read_from_bytes(&buf[0..CCSDS_HEADER_LEN]).unwrap();
|
||||
if raw_len < sp_header.packet_len() {
|
||||
return Err(ByteConversionError::FromSliceTooSmall {
|
||||
found: raw_len,
|
||||
expected: sp_header.packet_len(),
|
||||
});
|
||||
}
|
||||
Ok(Self {
|
||||
buf,
|
||||
packet_len: sp_header.packet_len(),
|
||||
checksum,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl CcsdsZeroCopyWriter<'_> {
|
||||
/// Read-only access to the raw buffer.
|
||||
pub fn raw_buffer(&self) -> &[u8] {
|
||||
&self.buf[0..self.packet_len]
|
||||
}
|
||||
|
||||
/// Mutable access to the raw buffer.
|
||||
pub fn raw_buffer_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.buf[0..self.packet_len]
|
||||
}
|
||||
|
||||
/// Read-only access to the full packet data field.
|
||||
///
|
||||
/// This might also include the checksum but does not include the raw [SpacePacketHeader].
|
||||
/// [Self::user_data] can be used to only retrieve the user data slice without the checksum
|
||||
/// part.
|
||||
pub fn packet_data(&self) -> &[u8] {
|
||||
&self.buf[CCSDS_HEADER_LEN..self.packet_len]
|
||||
}
|
||||
|
||||
/// Mutable access to the full packet data field.
|
||||
///
|
||||
/// This might also include the checksum but does not include the raw [SpacePacketHeader].
|
||||
/// [Self::user_data_mut] can be used to only retrieve the user data slice without the checksum
|
||||
/// part.
|
||||
pub fn packet_data_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.buf[CCSDS_HEADER_LEN..self.packet_len]
|
||||
}
|
||||
|
||||
/// Read-only access to the user data field which excludes the optional CRC16.
|
||||
pub fn user_data(&self) -> &[u8] {
|
||||
match self.checksum {
|
||||
Some(_checksum) => &self.buf[CCSDS_HEADER_LEN..self.packet_len - 2],
|
||||
None => &self.buf[CCSDS_HEADER_LEN..],
|
||||
}
|
||||
}
|
||||
|
||||
/// Mutable access to the user data field which excludes the optional CRC16.
|
||||
pub fn user_data_mut(&mut self) -> &mut [u8] {
|
||||
match self.checksum {
|
||||
Some(_checksum) => &mut self.buf[CCSDS_HEADER_LEN..self.packet_len - 2],
|
||||
None => &mut self.buf[CCSDS_HEADER_LEN..],
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the application process identifier (APID).
|
||||
#[inline]
|
||||
pub fn set_apid(&mut self, apid: u11) {
|
||||
// Clear APID part of the raw packet ID
|
||||
let updated_apid = ((((self.buf[0] as u16) << 8) | self.buf[1] as u16)
|
||||
& !MAX_APID.as_u16())
|
||||
| apid.as_u16();
|
||||
self.buf[0..2].copy_from_slice(&updated_apid.to_be_bytes());
|
||||
}
|
||||
|
||||
/// Current application process identifier (APID).
|
||||
pub fn apid(&self) -> u11 {
|
||||
u11::new((((self.buf[0] as u16) << 8) | self.buf[1] as u16) & MAX_APID.as_u16())
|
||||
}
|
||||
|
||||
/// Set the sequence count in the CCSDS packet header.
|
||||
#[inline]
|
||||
pub fn set_seq_count(&mut self, seq_count: u14) {
|
||||
let new_psc =
|
||||
(u16::from_be_bytes(self.buf[2..4].try_into().unwrap()) & 0xC000) | seq_count.as_u16();
|
||||
self.buf[2..4].copy_from_slice(&new_psc.to_be_bytes());
|
||||
}
|
||||
|
||||
/// This method has to be called after modifying fields to ensure the CRC16 of the
|
||||
/// packet remains valid.
|
||||
pub fn finish(&mut self) {
|
||||
match self.checksum {
|
||||
Some(ChecksumType::WithCrc16) => {
|
||||
let crc16 = CRC_CCITT_FALSE.checksum(&self.buf[0..self.packet_len - 2]);
|
||||
self.buf[self.packet_len - 2..self.packet_len]
|
||||
.copy_from_slice(&crc16.to_be_bytes());
|
||||
}
|
||||
None | Some(ChecksumType::WithCrc16ButIgnored) => (),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, feature = "std"))]
|
||||
pub(crate) mod tests {
|
||||
use std::collections::HashSet;
|
||||
|
||||
use super::*;
|
||||
use crate::crc::CRC_CCITT_FALSE;
|
||||
#[allow(unused_imports)]
|
||||
use crate::ByteConversionError;
|
||||
#[cfg(feature = "serde")]
|
||||
use crate::CcsdsPrimaryHeader;
|
||||
use crate::crc::CRC_CCITT_FALSE;
|
||||
use crate::{SequenceFlags, SpHeader};
|
||||
use alloc::vec;
|
||||
use arbitrary_int::{u11, u14};
|
||||
@@ -1868,7 +1731,7 @@ pub(crate) mod tests {
|
||||
#[cfg(feature = "serde")]
|
||||
use postcard::{from_bytes, to_allocvec};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Serialize, de::DeserializeOwned};
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
use zerocopy::FromBytes;
|
||||
|
||||
const CONST_SP: SpHeader = SpHeader::new(
|
||||
@@ -2226,18 +2089,17 @@ pub(crate) mod tests {
|
||||
#[test]
|
||||
fn test_ccsds_size_function_invalid_size_with_checksum() {
|
||||
// 2 less bytes available because of the checksum.
|
||||
assert!(
|
||||
ccsds_packet_len_for_user_data_len(
|
||||
u16::MAX as usize - 1,
|
||||
Some(ChecksumType::WithCrc16)
|
||||
)
|
||||
.is_some()
|
||||
);
|
||||
assert!(ccsds_packet_len_for_user_data_len(
|
||||
u16::MAX as usize - 1,
|
||||
Some(ChecksumType::WithCrc16)
|
||||
)
|
||||
.is_some());
|
||||
// This is too much.
|
||||
assert!(
|
||||
ccsds_packet_len_for_user_data_len(u16::MAX as usize, Some(ChecksumType::WithCrc16))
|
||||
.is_none()
|
||||
);
|
||||
assert!(ccsds_packet_len_for_user_data_len(
|
||||
u16::MAX as usize,
|
||||
Some(ChecksumType::WithCrc16)
|
||||
)
|
||||
.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2366,15 +2228,6 @@ pub(crate) mod tests {
|
||||
assert_eq!(buf[12], 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ccsds_reader_fails_on_small_buf() {
|
||||
let buf: [u8; 5] = [0; 5];
|
||||
for size in 0..5 {
|
||||
let reader = CcsdsPacketReader::new(&buf[0..size], None);
|
||||
assert!(reader.is_err());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ccsds_creator_creation_empty_user_data_no_checksum() {
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
@@ -2979,65 +2832,4 @@ pub(crate) mod tests {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
id.hash(&mut hasher);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ccsds_zero_copy_writer() {
|
||||
let data = [1, 2, 3, 4];
|
||||
let packet_creator = CcsdsPacketCreatorOwned::new_tm_with_checksum(
|
||||
SpacePacketHeader::new_from_apid(u11::new(0x1)),
|
||||
&data,
|
||||
)
|
||||
.unwrap();
|
||||
let mut packet_raw = packet_creator.to_vec();
|
||||
let packet_copy = packet_raw.clone();
|
||||
|
||||
let mut ccsds_zero_copy_writer =
|
||||
CcsdsZeroCopyWriter::new(&mut packet_raw, Some(ChecksumType::WithCrc16)).unwrap();
|
||||
assert_eq!(ccsds_zero_copy_writer.user_data(), &[1, 2, 3, 4]);
|
||||
assert_eq!(ccsds_zero_copy_writer.user_data_mut(), &mut [1, 2, 3, 4]);
|
||||
assert_eq!(&ccsds_zero_copy_writer.packet_data()[0..4], &[1, 2, 3, 4]);
|
||||
assert_eq!(
|
||||
&mut ccsds_zero_copy_writer.packet_data_mut()[0..4],
|
||||
&mut [1, 2, 3, 4]
|
||||
);
|
||||
assert_eq!(ccsds_zero_copy_writer.buf, &packet_copy);
|
||||
assert_eq!(ccsds_zero_copy_writer.raw_buffer(), &packet_copy);
|
||||
assert_eq!(ccsds_zero_copy_writer.raw_buffer_mut(), &packet_copy);
|
||||
assert_eq!(ccsds_zero_copy_writer.apid(), packet_creator.apid());
|
||||
ccsds_zero_copy_writer.set_apid(MAX_APID);
|
||||
assert_eq!(ccsds_zero_copy_writer.apid(), MAX_APID);
|
||||
ccsds_zero_copy_writer.set_seq_count(u14::new(0x42));
|
||||
ccsds_zero_copy_writer.finish();
|
||||
|
||||
let reader = CcsdsPacketReader::new(&packet_raw, Some(ChecksumType::WithCrc16)).unwrap();
|
||||
assert_eq!(reader.apid(), MAX_APID);
|
||||
assert_eq!(reader.seq_count(), u14::new(0x42));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reader_data_outlives_reader() {
|
||||
fn slices_from_local_reader(buf: &[u8]) -> (&[u8], &[u8], &[u8]) {
|
||||
let reader = CcsdsPacketReader::new(buf, Some(ChecksumType::WithCrc16)).unwrap();
|
||||
(reader.raw_data(), reader.packet_data(), reader.user_data())
|
||||
}
|
||||
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
let data = [1, 2, 3, 4, 5];
|
||||
let mut packet_creator = CcsdsPacketCreatorWithReservedData::new(
|
||||
SpacePacketHeader::new_from_apid(u11::new(0x1)),
|
||||
PacketType::Tc,
|
||||
data.len(),
|
||||
&mut buf,
|
||||
Some(ChecksumType::WithCrc16),
|
||||
)
|
||||
.unwrap();
|
||||
packet_creator.user_data_mut().copy_from_slice(&data);
|
||||
let packet_len = packet_creator.packet_len();
|
||||
packet_creator.finish();
|
||||
|
||||
let (raw_data, packet_data, user_data) = slices_from_local_reader(&buf[0..packet_len]);
|
||||
assert_eq!(raw_data, &buf[0..packet_len]);
|
||||
assert_eq!(packet_data.len(), data.len() + 2);
|
||||
assert_eq!(user_data, &data);
|
||||
}
|
||||
}
|
||||
+35
-35
@@ -492,17 +492,17 @@ pub mod std_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
Inner: SequenceCounter<Raw = RawTy>,
|
||||
RawTy: core::fmt::Debug
|
||||
+ Copy
|
||||
+ Clone
|
||||
+ Into<u64>
|
||||
+ TryFrom<u64>
|
||||
+ FromStr
|
||||
+ Default
|
||||
+ PartialEq
|
||||
+ Eq,
|
||||
> SequenceCounterOnFile<Inner, RawTy>
|
||||
Inner: SequenceCounter<Raw = RawTy>,
|
||||
RawTy: core::fmt::Debug
|
||||
+ Copy
|
||||
+ Clone
|
||||
+ Into<u64>
|
||||
+ TryFrom<u64>
|
||||
+ FromStr
|
||||
+ Default
|
||||
+ PartialEq
|
||||
+ Eq,
|
||||
> SequenceCounterOnFile<Inner, RawTy>
|
||||
{
|
||||
/// Initialize a new persistent sequence counter using a file at the given path and
|
||||
/// any non persistent inner [SequenceCounter] implementation.
|
||||
@@ -549,17 +549,17 @@ pub mod std_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
Inner: SequenceCounter<Raw = RawTy>,
|
||||
RawTy: core::fmt::Debug
|
||||
+ Copy
|
||||
+ Clone
|
||||
+ Into<u64>
|
||||
+ TryFrom<u64, Error: core::fmt::Debug>
|
||||
+ FromStr
|
||||
+ Default
|
||||
+ PartialEq
|
||||
+ Eq,
|
||||
> SequenceCounter for SequenceCounterOnFile<Inner, RawTy>
|
||||
Inner: SequenceCounter<Raw = RawTy>,
|
||||
RawTy: core::fmt::Debug
|
||||
+ Copy
|
||||
+ Clone
|
||||
+ Into<u64>
|
||||
+ TryFrom<u64, Error: core::fmt::Debug>
|
||||
+ FromStr
|
||||
+ Default
|
||||
+ PartialEq
|
||||
+ Eq,
|
||||
> SequenceCounter for SequenceCounterOnFile<Inner, RawTy>
|
||||
{
|
||||
type Raw = RawTy;
|
||||
|
||||
@@ -590,17 +590,17 @@ pub mod std_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
Inner: SequenceCounter<Raw = RawTy>,
|
||||
RawTy: core::fmt::Debug
|
||||
+ Copy
|
||||
+ Clone
|
||||
+ Into<u64>
|
||||
+ TryFrom<u64>
|
||||
+ FromStr
|
||||
+ Default
|
||||
+ PartialEq
|
||||
+ Eq,
|
||||
> Drop for SequenceCounterOnFile<Inner, RawTy>
|
||||
Inner: SequenceCounter<Raw = RawTy>,
|
||||
RawTy: core::fmt::Debug
|
||||
+ Copy
|
||||
+ Clone
|
||||
+ Into<u64>
|
||||
+ TryFrom<u64>
|
||||
+ FromStr
|
||||
+ Default
|
||||
+ PartialEq
|
||||
+ Eq,
|
||||
> Drop for SequenceCounterOnFile<Inner, RawTy>
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
if self.save_on_drop {
|
||||
@@ -632,14 +632,14 @@ pub mod std_mod {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::sync::atomic::{AtomicU8, AtomicU16, AtomicU32, AtomicU64};
|
||||
use core::sync::atomic::{AtomicU16, AtomicU32, AtomicU64, AtomicU8};
|
||||
use std::boxed::Box;
|
||||
|
||||
use crate::MAX_SEQ_COUNT;
|
||||
use crate::seq_count::{
|
||||
SequenceCounter, SequenceCounterCcsdsSimple, SequenceCounterSimple,
|
||||
SequenceCounterSyncCustomWrapU8,
|
||||
};
|
||||
use crate::MAX_SEQ_COUNT;
|
||||
|
||||
#[test]
|
||||
fn test_u8_counter() {
|
||||
|
||||
+1
-1
@@ -36,8 +36,8 @@ pub const FMT_STR_CODE_B_TERMINATED_WITH_SIZE: (&str, usize) = ("%Y-%jT%T%.3fZ",
|
||||
pub mod alloc_mod_chrono {
|
||||
use super::*;
|
||||
use chrono::{
|
||||
DateTime, Utc,
|
||||
format::{DelayedFormat, StrftimeItems},
|
||||
DateTime, Utc,
|
||||
};
|
||||
|
||||
/// Generates a time code formatter using the [FMT_STR_CODE_A_WITH_SIZE] format.
|
||||
|
||||
+98
-77
@@ -4,8 +4,8 @@
|
||||
//! The core data structure to do this is the [CdsTime] struct and the
|
||||
//! [get_dyn_time_provider_from_bytes] function to retrieve correct instances of the
|
||||
//! struct from a bytestream.
|
||||
use crate::ByteConversionError;
|
||||
use crate::private::Sealed;
|
||||
use crate::ByteConversionError;
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt::Debug;
|
||||
use core::ops::{Add, AddAssign};
|
||||
@@ -30,8 +30,9 @@ use core::any::Any;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{
|
||||
CcsdsTimeCode, CcsdsTimeProvider, DateBeforeCcsdsEpochError, MS_PER_DAY, SECONDS_PER_DAY,
|
||||
TimeReader, TimeWriter, TimestampError, UnixTime, ccsds_to_unix_days, unix_to_ccsds_days,
|
||||
ccsds_to_unix_days, unix_to_ccsds_days, CcsdsTimeCode, CcsdsTimeProvider,
|
||||
DateBeforeCcsdsEpochError, TimeReader, TimeWriter, TimestampError, UnixTime, MS_PER_DAY,
|
||||
SECONDS_PER_DAY,
|
||||
};
|
||||
|
||||
/// Base value for the preamble field for a time field parser to determine the time field type.
|
||||
@@ -293,8 +294,13 @@ impl<ProvidesDaysLen: ProvidesDaysLength> CdsBase for CdsTime<ProvidesDaysLen> {
|
||||
|
||||
impl<ProvidesDaysLen: ProvidesDaysLength> CdsTime<ProvidesDaysLen> {
|
||||
/// Please note that a precision value of 0 will be converted to [None] (no precision).
|
||||
pub const fn set_submillis(&mut self, prec: SubmillisPrecision, value: u32) -> bool {
|
||||
pub fn set_submillis(&mut self, prec: SubmillisPrecision, value: u32) -> bool {
|
||||
self.pfield &= !(0b11);
|
||||
if let SubmillisPrecision::Absent = prec {
|
||||
// self.submillis_precision = prec;
|
||||
self.submillis = 0;
|
||||
return true;
|
||||
}
|
||||
// self.submillis_precision = prec;
|
||||
match prec {
|
||||
SubmillisPrecision::Microseconds => {
|
||||
@@ -308,10 +314,7 @@ impl<ProvidesDaysLen: ProvidesDaysLength> CdsTime<ProvidesDaysLen> {
|
||||
self.pfield |= SubmillisPrecision::Picoseconds as u8;
|
||||
self.submillis = value;
|
||||
}
|
||||
SubmillisPrecision::Absent => {
|
||||
self.submillis = 0;
|
||||
}
|
||||
SubmillisPrecision::Reserved => (),
|
||||
_ => (),
|
||||
}
|
||||
true
|
||||
}
|
||||
@@ -350,18 +353,23 @@ impl<ProvidesDaysLen: ProvidesDaysLength> CdsTime<ProvidesDaysLen> {
|
||||
));
|
||||
}
|
||||
let pfield = buf[0];
|
||||
let cds_type = CcsdsTimeCode::try_from((pfield >> 4) & 0b111).map_err(|_| {
|
||||
TimestampError::InvalidTimeCode {
|
||||
expected: CcsdsTimeCode::Cds,
|
||||
found: (pfield >> 4) & 0b111,
|
||||
match CcsdsTimeCode::try_from((pfield >> 4) & 0b111) {
|
||||
Ok(cds_type) => match cds_type {
|
||||
CcsdsTimeCode::Cds => (),
|
||||
_ => {
|
||||
return Err(TimestampError::InvalidTimeCode {
|
||||
expected: CcsdsTimeCode::Cds,
|
||||
found: cds_type as u8,
|
||||
})
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(TimestampError::InvalidTimeCode {
|
||||
expected: CcsdsTimeCode::Cds,
|
||||
found: (pfield >> 4) & 0b111,
|
||||
});
|
||||
}
|
||||
})?;
|
||||
if !matches!(cds_type, CcsdsTimeCode::Cds) {
|
||||
return Err(TimestampError::InvalidTimeCode {
|
||||
expected: CcsdsTimeCode::Cds,
|
||||
found: cds_type as u8,
|
||||
});
|
||||
}
|
||||
};
|
||||
if ((pfield >> 3) & 0b1) == 1 {
|
||||
return Err(TimestampError::CustomEpochNotSupported);
|
||||
}
|
||||
@@ -386,10 +394,14 @@ impl<ProvidesDaysLen: ProvidesDaysLength> CdsTime<ProvidesDaysLen> {
|
||||
if length_of_day_segment_from_pfield(pfield) == LengthOfDaySegment::Long24Bits {
|
||||
init_len += 1
|
||||
}
|
||||
match precision_from_pfield(pfield) {
|
||||
SubmillisPrecision::Microseconds => init_len += 2,
|
||||
SubmillisPrecision::Picoseconds => init_len += 4,
|
||||
SubmillisPrecision::Absent | SubmillisPrecision::Reserved => (),
|
||||
match pfield & 0b11 {
|
||||
0b01 => {
|
||||
init_len += 2;
|
||||
}
|
||||
0b10 => {
|
||||
init_len += 4;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
init_len
|
||||
}
|
||||
@@ -425,17 +437,21 @@ impl<ProvidesDaysLen: ProvidesDaysLength> CdsTime<ProvidesDaysLen> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
const fn generic_new(
|
||||
fn generic_new(
|
||||
days_len: LengthOfDaySegment,
|
||||
ccsds_days: ProvidesDaysLen::FieldType,
|
||||
ms_of_day: u32,
|
||||
) -> Self {
|
||||
Self {
|
||||
) -> Result<Self, CdsError>
|
||||
where
|
||||
i64: From<ProvidesDaysLen::FieldType>,
|
||||
{
|
||||
let provider = Self {
|
||||
pfield: Self::generate_p_field(days_len, SubmillisPrecision::Absent),
|
||||
ccsds_days,
|
||||
ms_of_day,
|
||||
submillis: 0,
|
||||
}
|
||||
};
|
||||
Ok(provider)
|
||||
}
|
||||
|
||||
#[cfg(feature = "chrono")]
|
||||
@@ -518,22 +534,17 @@ impl<ProvidesDaysLen: ProvidesDaysLength> CdsTime<ProvidesDaysLen> {
|
||||
Ok(match self.submillis_precision() {
|
||||
SubmillisPrecision::Microseconds => ConversionFromNow::new_with_submillis_us_prec()?,
|
||||
SubmillisPrecision::Picoseconds => ConversionFromNow::new_with_submillis_ps_prec()?,
|
||||
SubmillisPrecision::Absent | SubmillisPrecision::Reserved => ConversionFromNow::new()?,
|
||||
_ => ConversionFromNow::new()?,
|
||||
})
|
||||
}
|
||||
|
||||
const fn generate_p_field(
|
||||
day_seg_len: LengthOfDaySegment,
|
||||
submillis_prec: SubmillisPrecision,
|
||||
) -> u8 {
|
||||
fn generate_p_field(day_seg_len: LengthOfDaySegment, submillis_prec: SubmillisPrecision) -> u8 {
|
||||
let mut pfield = P_FIELD_BASE | ((day_seg_len as u8) << 2);
|
||||
if matches!(
|
||||
submillis_prec,
|
||||
SubmillisPrecision::Microseconds
|
||||
| SubmillisPrecision::Picoseconds
|
||||
| SubmillisPrecision::Reserved
|
||||
) {
|
||||
pfield |= submillis_prec as u8
|
||||
match submillis_prec {
|
||||
SubmillisPrecision::Microseconds => pfield |= SubmillisPrecision::Microseconds as u8,
|
||||
SubmillisPrecision::Picoseconds => pfield |= SubmillisPrecision::Picoseconds as u8,
|
||||
SubmillisPrecision::Reserved => pfield |= SubmillisPrecision::Reserved as u8,
|
||||
_ => (),
|
||||
}
|
||||
pfield
|
||||
}
|
||||
@@ -566,11 +577,7 @@ impl CdsTime<DaysLen24Bits> {
|
||||
if ccsds_days > MAX_DAYS_24_BITS {
|
||||
return Err(CdsError::InvalidCcsdsDays(ccsds_days.into()));
|
||||
}
|
||||
Ok(Self::generic_new(
|
||||
LengthOfDaySegment::Long24Bits,
|
||||
ccsds_days,
|
||||
ms_of_day,
|
||||
))
|
||||
Self::generic_new(LengthOfDaySegment::Long24Bits, ccsds_days, ms_of_day)
|
||||
}
|
||||
|
||||
/// Generate a time stamp from the current time using the system clock.
|
||||
@@ -645,17 +652,17 @@ impl CdsTime<DaysLen24Bits> {
|
||||
match submillis_precision {
|
||||
SubmillisPrecision::Microseconds => {
|
||||
provider.set_submillis(
|
||||
submillis_precision,
|
||||
SubmillisPrecision::Microseconds,
|
||||
u16::from_be_bytes(buf[8..10].try_into().unwrap()) as u32,
|
||||
);
|
||||
}
|
||||
SubmillisPrecision::Picoseconds => {
|
||||
provider.set_submillis(
|
||||
submillis_precision,
|
||||
SubmillisPrecision::Picoseconds,
|
||||
u32::from_be_bytes(buf[8..12].try_into().unwrap()),
|
||||
);
|
||||
}
|
||||
SubmillisPrecision::Absent | SubmillisPrecision::Reserved => (),
|
||||
_ => (),
|
||||
}
|
||||
Ok(provider)
|
||||
}
|
||||
@@ -663,8 +670,9 @@ impl CdsTime<DaysLen24Bits> {
|
||||
|
||||
impl CdsTime<DaysLen16Bits> {
|
||||
/// Generate a new timestamp provider with the days field width set to 16 bits
|
||||
pub const fn new_with_u16_days(ccsds_days: u16, ms_of_day: u32) -> Self {
|
||||
Self::generic_new(LengthOfDaySegment::Short16Bits, ccsds_days, ms_of_day)
|
||||
pub fn new_with_u16_days(ccsds_days: u16, ms_of_day: u32) -> Self {
|
||||
// This should never fail, type system ensures CCSDS can not be negative or too large
|
||||
Self::generic_new(LengthOfDaySegment::Short16Bits, ccsds_days, ms_of_day).unwrap()
|
||||
}
|
||||
|
||||
/// Create a provider from a [`chrono::DateTime<Utc>`] struct.
|
||||
@@ -755,17 +763,17 @@ impl CdsTime<DaysLen16Bits> {
|
||||
match submillis_precision {
|
||||
SubmillisPrecision::Microseconds => {
|
||||
provider.set_submillis(
|
||||
submillis_precision,
|
||||
SubmillisPrecision::Microseconds,
|
||||
u16::from_be_bytes(buf[7..9].try_into().unwrap()) as u32,
|
||||
);
|
||||
}
|
||||
SubmillisPrecision::Picoseconds => {
|
||||
provider.set_submillis(
|
||||
submillis_precision,
|
||||
SubmillisPrecision::Picoseconds,
|
||||
u32::from_be_bytes(buf[7..11].try_into().unwrap()),
|
||||
);
|
||||
}
|
||||
SubmillisPrecision::Absent | SubmillisPrecision::Reserved => (),
|
||||
_ => (),
|
||||
}
|
||||
Ok(provider)
|
||||
}
|
||||
@@ -929,7 +937,7 @@ impl CdsTime<DaysLen24Bits> {
|
||||
SubmillisPrecision::Picoseconds => {
|
||||
buf[8..12].copy_from_slice(self.submillis().to_be_bytes().as_slice());
|
||||
}
|
||||
SubmillisPrecision::Absent | SubmillisPrecision::Reserved => (),
|
||||
_ => (),
|
||||
}
|
||||
Ok(self.len_as_bytes())
|
||||
}
|
||||
@@ -962,20 +970,24 @@ impl<DaysLenProvider: ProvidesDaysLength> PartialOrd for CdsTime<DaysLenProvider
|
||||
if self == other {
|
||||
return Some(Ordering::Equal);
|
||||
}
|
||||
let ordering = self.ccsds_days_as_u32().cmp(&other.ccsds_days_as_u32());
|
||||
if ordering != Ordering::Equal {
|
||||
return Some(ordering);
|
||||
match self.ccsds_days_as_u32().cmp(&other.ccsds_days_as_u32()) {
|
||||
Ordering::Less => return Some(Ordering::Less),
|
||||
Ordering::Greater => return Some(Ordering::Greater),
|
||||
_ => (),
|
||||
}
|
||||
let ordering = self.ms_of_day().cmp(&other.ms_of_day());
|
||||
if ordering != Ordering::Equal {
|
||||
return Some(ordering);
|
||||
match self.ms_of_day().cmp(&other.ms_of_day()) {
|
||||
Ordering::Less => return Some(Ordering::Less),
|
||||
Ordering::Greater => return Some(Ordering::Greater),
|
||||
_ => (),
|
||||
}
|
||||
let ordering = self
|
||||
match self
|
||||
.precision_as_ns()
|
||||
.unwrap_or(0)
|
||||
.cmp(&other.precision_as_ns().unwrap_or(0));
|
||||
if ordering != Ordering::Equal {
|
||||
return Some(ordering);
|
||||
.cmp(&other.precision_as_ns().unwrap_or(0))
|
||||
{
|
||||
Ordering::Less => return Some(Ordering::Less),
|
||||
Ordering::Greater => return Some(Ordering::Greater),
|
||||
_ => (),
|
||||
}
|
||||
Some(Ordering::Equal)
|
||||
}
|
||||
@@ -1039,7 +1051,7 @@ impl ConversionFromUnix {
|
||||
let submillis = match precision {
|
||||
SubmillisPrecision::Microseconds => (subsec_nanos / 1_000) % 1000,
|
||||
SubmillisPrecision::Picoseconds => (subsec_nanos % 10_u32.pow(6)) * 1000,
|
||||
SubmillisPrecision::Absent | SubmillisPrecision::Reserved => 0,
|
||||
_ => 0,
|
||||
};
|
||||
Ok(Self {
|
||||
ccsds_days: unix_to_ccsds_days(unix_days) as u32,
|
||||
@@ -1149,12 +1161,16 @@ impl ConversionFromChronoDatetime {
|
||||
// The contained values in the conversion should be all positive now
|
||||
let unix_conversion =
|
||||
ConversionFromUnix::new(dt.timestamp(), dt.timestamp_subsec_nanos(), prec)?;
|
||||
|
||||
let submillis = match prec {
|
||||
SubmillisPrecision::Microseconds => dt.timestamp_subsec_micros() % 1000,
|
||||
SubmillisPrecision::Picoseconds => (dt.timestamp_subsec_nanos() % 10_u32.pow(6)) * 1000,
|
||||
SubmillisPrecision::Absent | SubmillisPrecision::Reserved => 0,
|
||||
};
|
||||
let mut submillis = 0;
|
||||
match prec {
|
||||
SubmillisPrecision::Microseconds => {
|
||||
submillis = dt.timestamp_subsec_micros() % 1000;
|
||||
}
|
||||
SubmillisPrecision::Picoseconds => {
|
||||
submillis = (dt.timestamp_subsec_nanos() % 10_u32.pow(6)) * 1000;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
Ok(Self {
|
||||
unix_conversion,
|
||||
submillis_prec: prec,
|
||||
@@ -1191,12 +1207,17 @@ impl ConversionFromNow {
|
||||
// so it is okay to unwrap
|
||||
let unix_conversion =
|
||||
ConversionFromUnix::new(epoch as i64, now.subsec_nanos(), prec).unwrap();
|
||||
let mut submillis = 0;
|
||||
|
||||
let submillis = match prec {
|
||||
SubmillisPrecision::Microseconds => now.subsec_micros() % 1000,
|
||||
SubmillisPrecision::Picoseconds => (now.subsec_nanos() % 10_u32.pow(6)) * 1000,
|
||||
SubmillisPrecision::Absent | SubmillisPrecision::Reserved => 0,
|
||||
};
|
||||
match prec {
|
||||
SubmillisPrecision::Microseconds => {
|
||||
submillis = now.subsec_micros() % 1000;
|
||||
}
|
||||
SubmillisPrecision::Picoseconds => {
|
||||
submillis = (now.subsec_nanos() % 10_u32.pow(6)) * 1000;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
Ok(Self {
|
||||
unix_conversion,
|
||||
submillis_prec: prec,
|
||||
@@ -1315,9 +1336,9 @@ impl CdsTimestamp for CdsTime<DaysLen24Bits> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::ByteConversionError::FromSliceTooSmall;
|
||||
use crate::time::TimestampError::{ByteConversion, InvalidTimeCode};
|
||||
use crate::time::{DAYS_CCSDS_TO_UNIX, MS_PER_DAY, UnixTime};
|
||||
use crate::time::{UnixTime, DAYS_CCSDS_TO_UNIX, MS_PER_DAY};
|
||||
use crate::ByteConversionError::FromSliceTooSmall;
|
||||
use alloc::string::ToString;
|
||||
use chrono::{Datelike, NaiveDate, Timelike};
|
||||
#[cfg(feature = "serde")]
|
||||
|
||||
+13
-33
@@ -15,9 +15,9 @@ use crate::ByteConversionError;
|
||||
#[cfg(feature = "std")]
|
||||
use super::StdTimestampError;
|
||||
use super::{
|
||||
ccsds_epoch_to_unix_epoch, ccsds_time_code_from_p_field, unix_epoch_to_ccsds_epoch,
|
||||
CcsdsTimeCode, CcsdsTimeProvider, DateBeforeCcsdsEpochError, TimeReader, TimeWriter,
|
||||
TimestampError, UnixTime, ccsds_epoch_to_unix_epoch, ccsds_time_code_from_p_field,
|
||||
unix_epoch_to_ccsds_epoch,
|
||||
TimestampError, UnixTime,
|
||||
};
|
||||
#[cfg(feature = "std")]
|
||||
use std::time::SystemTime;
|
||||
@@ -452,7 +452,7 @@ impl CucTime {
|
||||
.ok_or(CucError::LeapSecondCorrectionError)?;
|
||||
let fractions =
|
||||
fractional_part_from_subsec_ns(res, unix_time.subsec_millis() as u64 * 10_u64.pow(6));
|
||||
Self::new_generic(WidthCounterPair(4, counter), fractions)
|
||||
Self::new_generic(WidthCounterPair(4, counter as u32), fractions)
|
||||
}
|
||||
|
||||
/// Most generic constructor which allows full configurability for the counter and for the
|
||||
@@ -822,10 +822,10 @@ fn get_time_values_after_duration_addition(
|
||||
new_counter = sum as u32;
|
||||
};
|
||||
match time.counter.0 {
|
||||
1 => counter_inc_handler(1_u64 << 8),
|
||||
2 => counter_inc_handler(1_u64 << 16),
|
||||
3 => counter_inc_handler(1_u64 << 24),
|
||||
4 => counter_inc_handler(1_u64 << 32),
|
||||
1 => counter_inc_handler(u8::MAX as u64),
|
||||
2 => counter_inc_handler(u16::MAX as u64),
|
||||
3 => counter_inc_handler((2_u32.pow(24) - 1) as u64),
|
||||
4 => counter_inc_handler(u32::MAX as u64),
|
||||
_ => {
|
||||
// Should never happen
|
||||
panic!("invalid counter width")
|
||||
@@ -866,8 +866,8 @@ impl Add<Duration> for CucTime {
|
||||
fn add(self, duration: Duration) -> Self::Output {
|
||||
let (new_counter, new_fractional_part) =
|
||||
get_time_values_after_duration_addition(&self, duration);
|
||||
Self::new_with_fractions(new_counter, new_fractional_part)
|
||||
.expect("The generated fractional part should always be valid")
|
||||
// The generated fractional part should always be valid, so its okay to unwrap here.
|
||||
Self::new_with_fractions(new_counter, new_fractional_part).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -877,14 +877,14 @@ impl Add<Duration> for &CucTime {
|
||||
fn add(self, duration: Duration) -> Self::Output {
|
||||
let (new_counter, new_fractional_part) =
|
||||
get_time_values_after_duration_addition(self, duration);
|
||||
Self::Output::new_with_fractions(new_counter, new_fractional_part)
|
||||
.expect("The generated fractional part should always be valid")
|
||||
// The generated fractional part should always be valid, so its okay to unwrap here.
|
||||
Self::Output::new_with_fractions(new_counter, new_fractional_part).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::time::{DAYS_CCSDS_TO_UNIX, SECONDS_PER_DAY, UnixTime};
|
||||
use crate::time::{UnixTime, DAYS_CCSDS_TO_UNIX, SECONDS_PER_DAY};
|
||||
|
||||
use super::*;
|
||||
use alloc::string::ToString;
|
||||
@@ -1392,27 +1392,7 @@ mod tests {
|
||||
CucTime::new_generic(WidthCounterPair(1, 255), FractionalPart::new_empty()).unwrap();
|
||||
let duration = Duration::from_secs(10);
|
||||
cuc_stamp += duration;
|
||||
assert_eq!(cuc_stamp.counter.1, 9);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_duration_reaches_max_counter_value() {
|
||||
let mut cuc_stamp =
|
||||
CucTime::new_generic(WidthCounterPair(1, 254), FractionalPart::new_empty()).unwrap();
|
||||
|
||||
cuc_stamp += Duration::from_secs(1);
|
||||
|
||||
assert_eq!(cuc_stamp.counter(), 255);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_duration_wraps_after_max_counter_value() {
|
||||
let mut cuc_stamp =
|
||||
CucTime::new_generic(WidthCounterPair(1, 255), FractionalPart::new_empty()).unwrap();
|
||||
|
||||
cuc_stamp += Duration::from_secs(1);
|
||||
|
||||
assert_eq!(cuc_stamp.counter(), 0);
|
||||
assert_eq!(cuc_stamp.counter.1, 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
+2
-2
@@ -431,14 +431,14 @@ impl Ord for UnixTime {
|
||||
Ordering::Greater
|
||||
} else {
|
||||
Ordering::Less
|
||||
};
|
||||
}
|
||||
}
|
||||
Ordering::Greater => {
|
||||
return if self.secs < 0 {
|
||||
Ordering::Less
|
||||
} else {
|
||||
Ordering::Greater
|
||||
};
|
||||
}
|
||||
}
|
||||
Ordering::Equal => (),
|
||||
}
|
||||
|
||||
+150
-655
File diff suppressed because it is too large.
Load diff
+3
-3
@@ -384,11 +384,11 @@ impl TryFrom<UnsignedByteField> for UnsignedByteFieldU64 {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::ByteConversionError;
|
||||
use crate::util::{
|
||||
UnsignedByteField, UnsignedByteFieldError, UnsignedByteFieldU8, UnsignedByteFieldU16,
|
||||
UnsignedByteFieldU32, UnsignedByteFieldU64, UnsignedEnum,
|
||||
UnsignedByteField, UnsignedByteFieldError, UnsignedByteFieldU16, UnsignedByteFieldU32,
|
||||
UnsignedByteFieldU64, UnsignedByteFieldU8, UnsignedEnum,
|
||||
};
|
||||
use crate::ByteConversionError;
|
||||
use std::format;
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user