diff --git a/Cargo.lock b/Cargo.lock index 59453f5..559a793 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,6 +61,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "anyhow" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" + [[package]] name = "arrayvec" version = "0.7.6" @@ -131,9 +137,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "block-buffer" @@ -155,7 +161,7 @@ dependencies = [ [[package]] name = "bluestation-bs" -version = "0.3.4" +version = "0.4.0" dependencies = [ "clap", "ctrlc", @@ -194,9 +200,9 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" -version = "1.2.51" +version = "1.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" dependencies = [ "find-msvc-tools", "shlex", @@ -242,9 +248,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.54" +version = "4.5.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" +checksum = "c5caf74d17c3aec5495110c34cc3f78644bfa89af6c8993ed4de2790e49b6499" dependencies = [ "clap_builder", "clap_derive", @@ -252,9 +258,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.54" +version = "4.5.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" +checksum = "370daa45065b80218950227371916a1633217ae42b2715b2287b606dcd618e24" dependencies = [ "anstream", "anstyle", @@ -264,9 +270,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.5.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" dependencies = [ "heck", "proc-macro2", @@ -276,9 +282,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" [[package]] name = "colorchoice" @@ -296,6 +302,26 @@ dependencies = [ "memchr", ] +[[package]] +name = "const_format" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -375,9 +401,9 @@ checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" [[package]] name = "deranged" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4" dependencies = [ "powerfmt", ] @@ -424,9 +450,15 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "generic-array" @@ -466,10 +498,43 @@ dependencies = [ ] [[package]] -name = "glam" -version = "0.31.0" +name = "getrandom" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74a4d85559e2637d3d839438b5b3d75c31e655276f9544d72475c36b92fabbed" +checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", + "wasip3", +] + +[[package]] +name = "git-version" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19" +dependencies = [ + "git-version-macro", +] + +[[package]] +name = "git-version-macro" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glam" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34627c5158214743a374170fed714833fdf4e4b0cbcc1ea98417866a4c5d4441" [[package]] name = "glob" @@ -477,6 +542,15 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + [[package]] name = "hashbrown" version = "0.16.1" @@ -506,13 +580,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] -name = "indexmap" -version = "2.12.1" +name = "id-arena" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.1", + "serde", + "serde_core", ] [[package]] @@ -572,10 +654,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] -name = "libc" -version = "0.2.179" +name = "leb128fmt" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "libc" +version = "0.2.182" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" [[package]] name = "libloading" @@ -622,9 +710,9 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "minimal-lexical" @@ -645,7 +733,7 @@ dependencies = [ [[package]] name = "net-tnmm-test" -version = "0.3.4" +version = "0.4.0" dependencies = [ "clap", "tetra-config", @@ -660,7 +748,7 @@ dependencies = [ [[package]] name = "net-tnmm-test-quic" -version = "0.3.4" +version = "0.4.0" dependencies = [ "quinn", "rcgen", @@ -737,9 +825,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num-integer" @@ -822,7 +910,7 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "pdu-tool" -version = "0.3.4" +version = "0.4.0" dependencies = [ "clap", "tetra-config", @@ -877,6 +965,16 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "primal-check" version = "0.3.4" @@ -888,9 +986,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -909,7 +1007,7 @@ dependencies = [ "rustc-hash 2.1.1", "rustls", "socket2", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", "web-time", @@ -932,7 +1030,7 @@ dependencies = [ "rustls-pki-types", "rustls-platform-verifier", "slab", - "thiserror 2.0.17", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -954,9 +1052,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] @@ -985,7 +1083,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -1005,7 +1103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -1019,9 +1117,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ "getrandom 0.3.4", ] @@ -1041,9 +1139,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -1053,9 +1151,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -1064,9 +1162,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" [[package]] name = "ring" @@ -1144,7 +1242,7 @@ dependencies = [ "openssl-probe 0.2.1", "rustls-pki-types", "schannel", - "security-framework 3.5.1", + "security-framework 3.6.0", ] [[package]] @@ -1181,7 +1279,7 @@ dependencies = [ "rustls-native-certs 0.8.3", "rustls-platform-verifier-android", "rustls-webpki", - "security-framework 3.5.1", + "security-framework 3.6.0", "security-framework-sys", "webpki-root-certs", "windows-sys 0.61.2", @@ -1243,9 +1341,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.5.1" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +checksum = "d17b898a6d6948c3a8ee4372c17cb384f90d2e6e912ef00895b14fd7ab54ec38" dependencies = [ "bitflags", "core-foundation 0.10.1", @@ -1256,14 +1354,20 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.15.0" +version = "2.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +checksum = "321c8673b092a9a42605034a9879d73cb79101ed5fd117bc9a597b89b4e9e61a" dependencies = [ "core-foundation-sys", "libc", ] +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + [[package]] name = "serde" version = "1.0.228" @@ -1412,9 +1516,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.114" +version = "2.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "3df424c70518695237746f84cede799c9c58fcb37450d7b23716568cc8bc69cb" dependencies = [ "proc-macro2", "quote", @@ -1423,7 +1527,7 @@ dependencies = [ [[package]] name = "tetra-config" -version = "0.3.4" +version = "0.4.0" dependencies = [ "serde", "tetra-core", @@ -1432,8 +1536,10 @@ dependencies = [ [[package]] name = "tetra-core" -version = "0.3.4" +version = "0.4.0" dependencies = [ + "const_format", + "git-version", "serde", "tracing", "tracing-appender", @@ -1442,7 +1548,7 @@ dependencies = [ [[package]] name = "tetra-entities" -version = "0.3.4" +version = "0.4.0" dependencies = [ "as-any", "bitcode", @@ -1470,7 +1576,7 @@ dependencies = [ [[package]] name = "tetra-pdus" -version = "0.3.4" +version = "0.4.0" dependencies = [ "tetra-config", "tetra-core", @@ -1480,7 +1586,7 @@ dependencies = [ [[package]] name = "tetra-saps" -version = "0.3.4" +version = "0.4.0" dependencies = [ "tetra-core", "tracing", @@ -1498,11 +1604,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.18", ] [[package]] @@ -1518,9 +1624,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", @@ -1538,30 +1644,30 @@ dependencies = [ [[package]] name = "time" -version = "0.3.44" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", "num-conv", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.24" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -1667,7 +1773,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" dependencies = [ "crossbeam-channel", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", "tracing-subscriber", ] @@ -1762,9 +1868,15 @@ checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "untrusted" @@ -1786,11 +1898,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.20.0" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" +checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.1", "js-sys", "wasm-bindgen", ] @@ -1825,9 +1937,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.1+wasi-0.2.4" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ "wit-bindgen", ] @@ -1877,6 +1998,40 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + [[package]] name = "web-time" version = "1.1.0" @@ -2144,9 +2299,91 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] [[package]] name = "yasna" @@ -2159,18 +2396,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.32" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fabae64378cb18147bb18bca364e63bdbe72a0ffe4adf0addfec8aa166b2c56" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.32" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9c2d862265a8bb4471d87e033e730f536e2a285cc7cb05dbce09a2a97075f90" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" dependencies = [ "proc-macro2", "quote", @@ -2185,6 +2422,6 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zmij" -version = "1.0.19" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml index 84beb47..7bcd614 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ members = [ ] [workspace.package] -version = "0.3.4" +version = "0.4.0" edition = "2024" authors = ["Wouter Bokslag / Midnight Blue"] license = "MIT" diff --git a/bins/bluestation-bs/src/main.rs b/bins/bluestation-bs/src/main.rs index 8f9fd82..ea25f0b 100644 --- a/bins/bluestation-bs/src/main.rs +++ b/bins/bluestation-bs/src/main.rs @@ -64,13 +64,11 @@ fn build_bs_stack(cfg: &mut SharedConfig) -> MessageRouter { router.register_entity(Box::new(cmce)); // Register Brew entity if enabled - let brew_cfg = cfg.config().brew.clone(); - if brew_cfg.enabled { + if let Some(brew_cfg) = cfg.config().brew.clone() { let brew_config = BrewConfig { host: brew_cfg.host, port: brew_cfg.port, tls: brew_cfg.tls, - user_agent: brew_cfg.user_agent, username: brew_cfg.username, password: brew_cfg.password, issi: brew_cfg.issi, diff --git a/crates/tetra-config/src/lib.rs b/crates/tetra-config/src/lib.rs index f4a95e4..8812153 100644 --- a/crates/tetra-config/src/lib.rs +++ b/crates/tetra-config/src/lib.rs @@ -7,6 +7,8 @@ pub mod stack_config; pub mod stack_config_soapy; +pub mod stack_config_brew; + pub mod toml_config; pub use stack_config::*; diff --git a/crates/tetra-config/src/stack_config.rs b/crates/tetra-config/src/stack_config.rs index 28eea1d..6691d2a 100644 --- a/crates/tetra-config/src/stack_config.rs +++ b/crates/tetra-config/src/stack_config.rs @@ -3,6 +3,8 @@ use std::sync::{Arc, RwLock}; use tetra_core::TimeslotAllocator; use tetra_core::freqs::FreqInfo; +use crate::stack_config_brew::CfgBrew; + use super::stack_config_soapy::CfgSoapySdr; #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)] @@ -184,72 +186,6 @@ fn default_main_carrier() -> u16 { 1521 } -/// Brew protocol (TetraPack/BrandMeister) configuration -#[derive(Debug, Clone, Deserialize)] -pub struct CfgBrew { - /// Enable Brew integration - #[serde(default)] - pub enabled: bool, - /// TetraPack server hostname or IP - #[serde(default = "default_brew_host")] - pub host: String, - /// TetraPack server port - #[serde(default = "default_brew_port")] - pub port: u16, - /// Use TLS (wss:// / https://) - #[serde(default)] - pub tls: bool, - /// User-Agent string for authentication - #[serde(default = "default_brew_user_agent")] - pub user_agent: String, - /// Optional username for HTTP Digest auth - pub username: Option, - /// Optional password for HTTP Digest auth - pub password: Option, - /// ISSI to register with the TetraPack server - #[serde(default)] - pub issi: u32, - /// GSSIs (group IDs) to affiliate to - #[serde(default)] - pub groups: Vec, - /// Reconnection delay in seconds - #[serde(default = "default_brew_reconnect_delay")] - pub reconnect_delay_secs: u64, -} - -fn default_brew_host() -> String { - "127.0.0.1".to_string() -} - -fn default_brew_port() -> u16 { - 3000 -} - -fn default_brew_user_agent() -> String { - "TETRAHS/000001".to_string() -} - -fn default_brew_reconnect_delay() -> u64 { - 15 -} - -impl Default for CfgBrew { - fn default() -> Self { - Self { - enabled: false, - host: default_brew_host(), - port: default_brew_port(), - tls: false, - user_agent: default_brew_user_agent(), - username: None, - password: None, - issi: 0, - groups: Vec::new(), - reconnect_delay_secs: default_brew_reconnect_delay(), - } - } -} - #[derive(Debug, Clone, Deserialize)] pub struct StackConfig { #[serde(default = "default_stack_mode")] @@ -267,8 +203,7 @@ pub struct StackConfig { pub cell: CfgCellInfo, /// Brew protocol (TetraPack/BrandMeister) configuration - #[serde(default)] - pub brew: CfgBrew, + pub brew: Option, } fn default_stack_mode() -> StackMode { @@ -283,7 +218,8 @@ impl StackConfig { phy_io: CfgPhyIo::default(), net: CfgNetInfo { mcc, mnc }, cell: CfgCellInfo::default(), - brew: CfgBrew::default(), + + brew: None, } } diff --git a/crates/tetra-config/src/stack_config_brew.rs b/crates/tetra-config/src/stack_config_brew.rs new file mode 100644 index 0000000..940ed37 --- /dev/null +++ b/crates/tetra-config/src/stack_config_brew.rs @@ -0,0 +1,72 @@ +use std::collections::HashMap; + +use serde::Deserialize; +use toml::Value; + +/// Brew protocol (TetraPack/BrandMeister) configuration +#[derive(Debug, Clone, Deserialize)] +pub struct CfgBrew { + /// TetraPack server hostname or IP + pub host: String, + /// TetraPack server port + pub port: u16, + /// Use TLS (wss:// / https://) + pub tls: bool, + /// Optional username for HTTP Digest auth + pub username: Option, + /// Optional password for HTTP Digest auth + pub password: Option, + /// ISSI to register with the TetraPack server + pub issi: u32, + /// GSSIs (group IDs) to affiliate to + pub groups: Vec, + /// Reconnection delay in seconds + pub reconnect_delay_secs: u64, +} + +#[derive(Default, Deserialize)] +pub struct CfgBrewDto { + /// TetraPack server hostname or IP + pub host: String, + /// TetraPack server port + #[serde(default = "default_brew_port")] + pub port: u16, + /// Use TLS (wss:// / https://) + pub tls: bool, + /// Optional username for HTTP Digest auth + pub username: Option, + /// Optional password for HTTP Digest auth + pub password: Option, + /// ISSI to register with the TetraPack server + pub issi: u32, + /// GSSIs (group IDs) to affiliate to + pub groups: Vec, + /// Reconnection delay in seconds + #[serde(default = "default_brew_reconnect_delay")] + pub reconnect_delay_secs: u64, + + #[serde(flatten)] + pub extra: HashMap, +} + +fn default_brew_port() -> u16 { + 3000 +} + +fn default_brew_reconnect_delay() -> u64 { + 15 +} + +/// Convert a CfgBrewDto (from TOML) into a CfgBrew (used in the stack config) +pub fn apply_brew_patch(src: CfgBrewDto) -> CfgBrew { + CfgBrew { + host: src.host, + port: src.port, + tls: src.tls, + username: src.username, + password: src.password, + issi: src.issi, + groups: src.groups, + reconnect_delay_secs: src.reconnect_delay_secs, + } +} diff --git a/crates/tetra-config/src/stack_config_soapy.rs b/crates/tetra-config/src/stack_config_soapy.rs index 77b1800..86c35cf 100644 --- a/crates/tetra-config/src/stack_config_soapy.rs +++ b/crates/tetra-config/src/stack_config_soapy.rs @@ -84,7 +84,6 @@ pub struct CfgSoapySdr { /// PPM frequency error correction pub ppm_err: Option, /// Hardware-specific I/O configuration - #[serde(flatten)] pub io_cfg: SoapySdrIoCfg, } diff --git a/crates/tetra-config/src/toml_config.rs b/crates/tetra-config/src/toml_config.rs index b1a131f..cbc376c 100644 --- a/crates/tetra-config/src/toml_config.rs +++ b/crates/tetra-config/src/toml_config.rs @@ -6,8 +6,10 @@ use std::path::Path; use serde::Deserialize; use toml::Value; +use super::stack_config_brew::{CfgBrewDto, apply_brew_patch}; + use super::stack_config::{ - CfgBrew, CfgCellInfo, CfgNetInfo, CfgPhyIo, PhyBackend, SharedConfig, StackConfig, StackMode, + CfgCellInfo, CfgNetInfo, CfgPhyIo, PhyBackend, SharedConfig, StackConfig, StackMode, StackState, }; use super::stack_config_soapy::{CfgSoapySdr, LimeSdrCfg, SXceiverCfg, UsrpB2xxCfg}; @@ -48,6 +50,17 @@ pub fn from_toml_str(toml_str: &str) -> Result Result Result, #[serde(default)] - brew: Option, + brew: Option, #[serde(flatten)] extra: HashMap, diff --git a/crates/tetra-core/Cargo.toml b/crates/tetra-core/Cargo.toml index d7f03aa..9241d13 100644 --- a/crates/tetra-core/Cargo.toml +++ b/crates/tetra-core/Cargo.toml @@ -8,4 +8,6 @@ serde = { workspace = true } tracing = { workspace = true } tracing-subscriber = { workspace = true } tracing-appender = { workspace = true } +git-version = "0.3.9" +const_format = "0.2.35" # as-any = { workspace = true } diff --git a/crates/tetra-core/src/lib.rs b/crates/tetra-core/src/lib.rs index ea2ed8b..c31ce13 100644 --- a/crates/tetra-core/src/lib.rs +++ b/crates/tetra-core/src/lib.rs @@ -1,11 +1,11 @@ //! Core utilities for TETRA BlueStation //! -//! This crate provides fundamental types and utilities used across the TETRA stack: -//! - BitBuffer for bit-level PDU manipulation -//! - TdmaTime for TDMA frame timing -//! - Address types (ISSI, GSSI, etc.) -//! - PHY types (PhyBlockNum, BurstType, etc.) -//! - Common macros and debug utilities +//! This crate provides fundamental types and utilities used across the TETRA stack + +/// Git version string, set at compile time +pub const GIT_VERSION: &str = git_version::git_version!(); +/// Stack version followed by git version string, e.g., "0.1.0-aabbccdd" +pub const STACK_VERSION: &str = const_format::formatcp!("{}-{}", env!("CARGO_PKG_VERSION"), GIT_VERSION); pub mod address; pub mod bitbuffer; diff --git a/crates/tetra-entities/src/brew/entity.rs b/crates/tetra-entities/src/brew/entity.rs index b9fa9f6..0320510 100644 --- a/crates/tetra-entities/src/brew/entity.rs +++ b/crates/tetra-entities/src/brew/entity.rs @@ -79,6 +79,9 @@ struct UlForwardedCall { pub struct BrewEntity { config: SharedConfig, + + brew_config: BrewConfig, + dltime: TdmaTime, /// Receive events from the worker thread @@ -110,7 +113,7 @@ impl BrewEntity { let (command_sender, command_receiver) = unbounded::(); // Spawn worker thread - let worker_config = brew_config; + let worker_config = brew_config.clone(); let handle = thread::Builder::new() .name("brew-worker".to_string()) .spawn(move || { @@ -121,6 +124,7 @@ impl BrewEntity { Self { config, + brew_config, dltime: TdmaTime::default(), event_receiver, command_sender, @@ -554,7 +558,8 @@ impl BrewEntity { } // Check if this group is subscribed in Brew config - let groups = &self.config.config().brew.groups; + // let groups = &self.config.config().brew.groups; + let groups = &self.brew_config.groups; if !groups.contains(&dest_gssi) { tracing::debug!( "BrewEntity: local call on GSSI {} not subscribed (subscribed: {:?}), not forwarding", diff --git a/crates/tetra-entities/src/brew/worker.rs b/crates/tetra-entities/src/brew/worker.rs index c4b0b65..2d4ef79 100644 --- a/crates/tetra-entities/src/brew/worker.rs +++ b/crates/tetra-entities/src/brew/worker.rs @@ -94,8 +94,6 @@ pub struct BrewConfig { pub port: u16, /// Use TLS (wss:// / https://) pub tls: bool, - /// User-Agent string for authentication (e.g., "TETRAHS/012345") - pub user_agent: String, /// Optional username for HTTP Digest auth pub username: Option, /// Optional password for HTTP Digest auth @@ -313,12 +311,15 @@ impl BrewWorker { tracing::info!("BrewWorker stopped"); } + fn user_agent() -> String { + format!("BlueStation/{}", tetra_core::STACK_VERSION) + } + /// Perform HTTP GET /brew/ with optional Digest Auth to get the WebSocket endpoint fn authenticate(&self) -> Result { let host = &self.config.host; let port = self.config.port; - let ua = &self.config.user_agent; - + // ── First request (unauthenticated) ── let mut stream = connect_stream(host, port, self.config.tls)?; @@ -327,7 +328,7 @@ impl BrewWorker { Host: {}\r\n\ User-Agent: {}\r\n\ \r\n", - host, ua + host, Self::user_agent() ); stream .write_all(request.as_bytes()) @@ -409,7 +410,7 @@ impl BrewWorker { User-Agent: {}\r\n\ Authorization: {}\r\n\ \r\n", - host, ua, auth_header + host, Self::user_agent(), auth_header ); stream2 .write_all(auth_request.as_bytes()) @@ -472,7 +473,7 @@ impl BrewWorker { let request = tungstenite::http::Request::builder() .uri(&ws_url) .header("Host", format!("{}:{}", self.config.host, self.config.port)) - .header("User-Agent", &self.config.user_agent) + .header("User-Agent", Self::user_agent()) .header("Sec-WebSocket-Protocol", "brew") .header("Connection", "Upgrade") .header("Upgrade", "websocket") diff --git a/crates/tetra-entities/tests/common/component_test.rs b/crates/tetra-entities/tests/common/component_test.rs index e07e9c2..a067809 100644 --- a/crates/tetra-entities/tests/common/component_test.rs +++ b/crates/tetra-entities/tests/common/component_test.rs @@ -1,5 +1,5 @@ use tetra_config::{ - CfgBrew, CfgCellInfo, CfgNetInfo, CfgPhyIo, PhyBackend, SharedConfig, StackConfig, StackMode, + CfgCellInfo, CfgNetInfo, CfgPhyIo, PhyBackend, SharedConfig, StackConfig, StackMode, StackState, }; use tetra_core::TdmaTime; @@ -52,7 +52,7 @@ pub fn default_test_config(stack_mode: StackMode) -> StackConfig { phy_io, net: net_info, cell: cell_info, - brew: CfgBrew::default(), + brew: None, } }