diff --git a/.gitignore b/.gitignore index abcf1830..934859fb 100644 --- a/.gitignore +++ b/.gitignore @@ -20,8 +20,7 @@ logs/ # protobuf mod.rs -command_data.rs -serverdata.rs +/src/proto/*.rs -# private testing +# private testing /privatetest/ diff --git a/Cargo.lock b/Cargo.lock index 02905d12..3cffedab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "autocfg" @@ -75,9 +75,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.15.1" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b5ce75405893cd713f9ab8e297d8e438f624dde7d706108285f7e17a25a180f" +checksum = "94bffc006df10ac2a68c83692d734a465f8ee6c5b384d8545a636f81d858f4bf" dependencies = [ "aws-lc-sys", "zeroize", @@ -85,9 +85,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.34.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "179c3777a8b5e70e90ea426114ffc565b2c1a9f82f6c4a0c5a34aa6ef5e781b6" +checksum = "4321e568ed89bb5a7d291a7f37997c2c0df89809d7b6d12062c81ddb54aa782e" dependencies = [ "cc", "cmake", @@ -97,9 +97,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 = "bitstream-io" @@ -118,9 +118,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "calypso" @@ -174,9 +174,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.48" +version = "1.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c481bdbf0ed3b892f6f806287d72acd515b352a4ec27a208489b8c1bc839633a" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" dependencies = [ "find-msvc-tools", "jobserver", @@ -196,17 +196,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" -[[package]] -name = "chacha20" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" -dependencies = [ - "cfg-if", - "cpufeatures", - "rand_core", -] - [[package]] name = "clap" version = "4.5.60" @@ -238,7 +227,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -249,9 +238,9 @@ checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" [[package]] name = "cmake" -version = "0.1.54" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" dependencies = [ "cc", ] @@ -287,15 +276,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "cpufeatures" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" -dependencies = [ - "libc", -] - [[package]] name = "daedalus" version = "0.1.0" @@ -368,9 +348,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "find-msvc-tools" -version = "0.1.5" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fixedbitset" @@ -403,9 +383,9 @@ checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "futures" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -434,9 +414,9 @@ checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -457,7 +437,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -491,9 +471,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "libc", @@ -521,7 +501,6 @@ dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", - "rand_core", "wasip2", "wasip3", ] @@ -570,9 +549,9 @@ checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" [[package]] name = "indexmap" -version = "2.12.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -597,9 +576,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jobserver" @@ -625,9 +604,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.177" +version = "0.2.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "linux-raw-sys" @@ -637,9 +616,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "lock_api" @@ -652,9 +631,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "matchers" @@ -667,9 +646,9 @@ dependencies = [ [[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 = "memoffset" @@ -688,9 +667,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mio" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", "log", @@ -780,7 +759,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -797,9 +776,9 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "openssl-probe" -version = "0.1.6" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "parking_lot" @@ -855,7 +834,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -869,9 +848,18 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] [[package]] name = "prettyplease" @@ -880,14 +868,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] name = "proc-macro-crate" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ "toml_edit", ] @@ -975,20 +963,32 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.10.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "chacha20", - "getrandom 0.4.2", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" -version = "0.10.0" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] [[package]] name = "redox_syscall" @@ -1016,7 +1016,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -1033,9 +1033,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", @@ -1044,9 +1044,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "ring" @@ -1056,7 +1056,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.17", "libc", "untrusted", "windows-sys 0.52.0", @@ -1098,37 +1098,37 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ "bitflags", "errno", "libc", - "linux-raw-sys 0.11.0", + "linux-raw-sys 0.12.1", "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.35" +version = "0.23.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" dependencies = [ "aws-lc-rs", "log", "once_cell", "rustls-pki-types", - "rustls-webpki 0.103.8", + "rustls-webpki 0.103.9", "subtle", "zeroize", ] [[package]] name = "rustls-native-certs" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ "openssl-probe", "rustls-pki-types", @@ -1147,9 +1147,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "708c0f9d5f54ba0272468c1d306a52c495b31fa155e91bc25371e6df7996908c" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ "zeroize", ] @@ -1167,9 +1167,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.8" +version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ "aws-lc-rs", "ring", @@ -1185,9 +1185,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "schannel" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] @@ -1214,7 +1214,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -1225,9 +1225,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "3.5.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ "bitflags", "core-foundation", @@ -1238,9 +1238,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.15.0" +version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", @@ -1279,7 +1279,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -1290,7 +1290,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -1334,24 +1334,25 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.7" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] [[package]] name = "siphasher" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" @@ -1371,12 +1372,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1435,9 +1436,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.111" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -1446,14 +1447,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.23.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.2", "once_cell", - "rustix 1.1.2", + "rustix 1.1.4", "windows-sys 0.61.2", ] @@ -1483,7 +1484,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -1494,7 +1495,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -1518,20 +1519,20 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.1", + "socket2 0.6.3", "tokio-macros", "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -1546,9 +1547,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", "pin-project-lite", @@ -1574,18 +1575,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.3" +version = "1.0.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "32c2555c699578a4f59f0cc68e5116c8d7cabbd45e1409b989d4be085b53f13e" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.23.7" +version = "0.25.4+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" +checksum = "7193cbd0ce53dc966037f54351dbbcf0d5a642c7f0038c382ef9e677ce8c13f2" dependencies = [ "indexmap", "toml_datetime", @@ -1595,9 +1596,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.0.9+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" dependencies = [ "winnow", ] @@ -1621,7 +1622,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -1665,9 +1666,9 @@ dependencies = [ [[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" @@ -1701,11 +1702,11 @@ 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 0.46.0", + "wit-bindgen", ] [[package]] @@ -1714,7 +1715,7 @@ 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 0.51.0", + "wit-bindgen", ] [[package]] @@ -1775,7 +1776,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -1784,16 +1785,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", + "windows-targets", ] [[package]] @@ -1811,31 +1803,14 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -1844,111 +1819,57 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "winnow" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" dependencies = [ "memchr", ] -[[package]] -name = "wit-bindgen" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" - [[package]] name = "wit-bindgen" version = "0.51.0" @@ -1979,7 +1900,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn 2.0.111", + "syn 2.0.117", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -1995,7 +1916,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -2037,6 +1958,26 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "zerocopy" +version = "0.8.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "zeroize" version = "1.8.2" @@ -2045,6 +1986,6 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zmij" -version = "1.0.2" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4a4e8e9dc5c62d159f04fcdbe07f4c3fb710415aab4754bf11505501e3251d" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml index 598c732a..81591279 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "calypso" version = "0.1.0" edition = "2024" -#rust-version = "1.85" +rust-version = "1.88" default-run = "calypso" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -36,7 +36,7 @@ regex = { workspace = true } phf = { version = "0.13.1", features = ["macros"] } calypso-cangen = { path = "./libs/calypso-cangen" } daedalus = { path = "./libs/daedalus" } -tokio = { version = "1.47.1", features = ["full"] } +tokio = { version = "1.47.1", features = ["full", "net"] } futures-util = "0.3.31" tracing = "0.1.41" tracing-subscriber = { version = "0.3.19", features = ["ansi", "env-filter"] } diff --git a/build.rs b/build.rs index 578bd083..2c45c5fa 100644 --- a/build.rs +++ b/build.rs @@ -13,6 +13,7 @@ fn main() { // Inputs must reside in some of include paths. .input("src/proto/command_data.proto") .input("src/proto/serverdata.proto") + .input("src/proto/firmware_data.proto") // Specify output directory relative to Cargo output directory. .out_dir("src/proto") .run_from_script(); diff --git a/src/can.rs b/src/can.rs new file mode 100644 index 00000000..8aa4dfda --- /dev/null +++ b/src/can.rs @@ -0,0 +1,233 @@ +use crate::data::{DecodeData, EncodeData}; +use crate::decode_data::DECODE_FUNCTION_MAP; +use crate::proto::serverdata::ServerData; +use futures_util::StreamExt; +use socketcan::Id; +use socketcan::tokio::CanSocket; +use socketcan::{CanDataFrame, CanError, CanFrame, EmbeddedFrame, Frame, SocketOptions}; +use std::collections::HashMap; +use std::time::UNIX_EPOCH; +use tokio::sync::mpsc::{Receiver, Sender}; +use tokio::time::Duration; +use tokio_util::sync::CancellationToken; +use tracing::{debug, info, trace, warn}; +/** + * Helper function to create a `CanFrame` + * msg: (id, `EncodeData`), the message to send + * # Panics + * If an invaid ID is sent by the `EncodeData` + */ +#[must_use] +pub fn create_frame(msg: (&u32, &EncodeData)) -> Option { + let id: Id = if msg.1.is_ext { + socketcan::ExtendedId::new(msg.1.id) + .unwrap_or_else(|| panic!("Invalid extended ID: {}", msg.1.id)) + .into() + } else { + socketcan::StandardId::new( + msg.1 + .id + .try_into() + .unwrap_or_else(|_| panic!("Invalid standard ID: {}", msg.1.id)), + ) + .unwrap_or_else(|| panic!("Invalid standard ID: {}", msg.1.id)) + .into() + }; + + CanFrame::new(id, &msg.1.value) +} + +/** + * Helper function to dump the current bidir commands into CAN + * `send_map`: A map of CAN IDs and data to be sent to the car + * `can_push_send`: A channel to send CAN messages + */ +pub async fn release_commands( + send_map: &HashMap, + can_push_send: &Sender, +) { + for msg in send_map { + // let id = u32::from_str_radix((msg.1.1).trim_start_matches("0x"), 16).expect("Invalid CAN ID!"); + + match create_frame(msg) { + Some(packet) => match can_push_send.send(packet).await { + Ok(()) => (), + Err(err) => warn!("Error sending can command to can manager {}", err), + }, + None => { + warn!("Packet is too long: {}", msg.1); + } + } + } +} + +/** + * Reads the can socket and publishes the data to siren channel + * `can_interface`: the socketcan interface to bind to + * `send_to_siren`: the channel to send protobuf messages to + * `alt_send_to_siren`: the channel to send priority queue alt messages to + * `send_over_can`: can messages to be sent over CAN + * + * # Panics + * Panics if can socket could not be opened + */ +pub async fn can_manager( + token: CancellationToken, + can_interface: String, + main_send_to_siren: Sender<(String, ServerData)>, + alt_send_to_siren: Option>, + send_raw_can: Option>, + mut send_over_can: Receiver, +) { + let mut socket = CanSocket::open(&can_interface).expect("Failed to open CAN socket!"); + socket + .set_error_filter_accept_all() + .expect("Failed to set error mask on CAN socket!"); + socket + .set_recv_own_msgs(true) // important to get the bidir messages + .expect("Cant recv own messages"); + + // the rate variables, updated every 3 seconds to the user + let mut mqtt_cnt: u64 = 0u64; + let mut frame_cnt: u64 = 0u64; + let mut disp_interval = tokio::time::interval(Duration::from_secs(3)); + let mut time_interval = tokio::time::Instant::now(); + + loop { + tokio::select! { + () = token.cancelled() => { + debug!("Shutting down CAN reader!"); + break; + }, + Some(frame) = socket.next() => { + frame_cnt += 1; + pub_frame(frame, &main_send_to_siren, alt_send_to_siren.as_ref(), send_raw_can.as_ref(), &mut mqtt_cnt, ).await; + } + Some(frame) = send_over_can.recv() => { + match socket.write_frame(frame).await { + Ok(()) => (), + Err(r) => warn!("Could not send CAN frame: {}", r), + } + }, + _ = disp_interval.tick() => { + info!("{:.3} msgs/sec and {:.3} frames/sec", (mqtt_cnt as f64 + / (tokio::time::Instant::now() - time_interval).as_millis() as f64) * 1000f64, + (frame_cnt as f64 / (tokio::time::Instant::now() - time_interval).as_millis() as f64) * 1000f64); + time_interval = tokio::time::Instant::now(); + frame_cnt = 0; + mqtt_cnt = 0; + } + } + } +} + +/** + * Handles reception of a frame or error + * frame: the frame + * `main_send`: the siren receiver + * `alt_send`: the priority siren receiver + * cnt: a variable incremented per MQTT message sent over `main_send` + */ +async fn pub_frame( + frame: Result, + main_send: &Sender<(String, ServerData)>, + alt_send: Option<&Sender<(String, ServerData)>>, + raw_send: Option<&Sender>, + cnt: &mut u64, +) { + let decoded_data = match frame { + // CanDataFrame + Ok(CanFrame::Data(data_frame)) => { + let data = data_frame.data(); + let id: u32 = match data_frame.id() { + socketcan::Id::Standard(std) => std.as_raw().into(), + socketcan::Id::Extended(ext) => ext.as_raw(), + }; + if let Some(send) = raw_send { + // for now just hardcode IMD + if id == 0x23 + && let Err(err) = send.send(data_frame).await + { + warn!("Could not send IMD code the response! {}", err); + } + } + trace!("RECVED message with ID: {:#01x}", id); + match DECODE_FUNCTION_MAP.get(&id) { + Some(func) => func(data), + None => vec![DecodeData::new( + vec![id as f32], + "Calypso/Unknown", + "ID", + None, + )], + } + } + // CanRemoteFrame + Ok(CanFrame::Remote(remote_frame)) => { + // Send frame ID for Remote + vec![DecodeData::new( + vec![remote_frame.raw_id() as f32], + "Calypso/Events/RemoteFrame", + "id", + None, + )] + } + // CanErrorFrame + Ok(CanFrame::Error(error_frame)) => { + // Publish enum index of error onto CAN + // TODO: maybe look into better representation? + let error_index: f32 = match CanError::from(error_frame) { + CanError::TransmitTimeout => 0.0, + CanError::LostArbitration(_) => 1.0, + CanError::ControllerProblem(_) => 2.0, + CanError::ProtocolViolation { .. } => 3.0, + CanError::TransceiverError => 4.0, + CanError::NoAck => 5.0, + CanError::BusOff => 6.0, + CanError::BusError => 7.0, + CanError::Restarted => 8.0, + CanError::DecodingFailure(_) => 9.0, + CanError::Unknown(_) => 10.0, + }; + vec![DecodeData::new( + vec![error_index], + "Calypso/Events/ErrorFrame", + "CanError enum", + None, + )] + } + // Socket failure + Err(err) => { + warn!("CAN Socket failure: {}", err); + return; + } + }; + // TODO switch to hardware timestamps + let timestamp = UNIX_EPOCH.elapsed().unwrap().as_micros() as u64; + + // Convert decoded CAN to Protobuf and publish over MQTT + for data in &decoded_data { + *cnt += 1; + let mut payload = ServerData::new(); + payload.unit.clone_from(&data.unit); + payload.values.clone_from(&data.value); + payload.time_us = timestamp; + + if let Some(alt_send) = alt_send + && let Some(clients) = &data.clients + && clients.first().unwrap_or(&0) == &1882 + { + match alt_send.send((data.topic.clone(), payload.clone())).await { + Ok(()) => trace!("Sent a CAN message to SIREN manager alt"), + Err(err) => { + warn!("Could not send CAN message to SIREN manager alt: {}", err); + } + } + } + + match main_send.send((data.topic.clone(), payload)).await { + Ok(()) => trace!("Sent a CAN message to SIREN manager"), + Err(err) => warn!("Could not send CAN message to SIREN manager: {}", err), + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 0ba8db43..e49b63ce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,3 +7,6 @@ pub mod simulatable_message; pub mod simulate_data; pub mod imd_poll; + +pub mod can; +pub mod udp; diff --git a/src/main.rs b/src/main.rs index 5e887d72..a9eea946 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,29 +1,23 @@ use std::{ collections::HashMap, - time::{Duration, SystemTime, UNIX_EPOCH}, + time::{Duration, SystemTime}, }; use calypso::{ - data::{DecodeData, EncodeData}, - decode_data::DECODE_FUNCTION_MAP, + data::EncodeData, encode_data::{ENCODABLE_KEY_LIST, ENCODE_FUNCTION_MAP}, imd_poll::imd_poll_main, - proto::{ - command_data, - serverdata::{self, ServerData}, - }, + proto::{command_data, serverdata::ServerData}, + udp::eth_manager, }; use calypso_cangen::can_types::BidirMode; use clap::Parser; -use futures_util::StreamExt; use protobuf::Message; use rumqttc::v5::{ AsyncClient, Event, EventLoop, MqttOptions, mqttbytes::v5::{Packet, Publish}, }; -use socketcan::{ - CanDataFrame, CanError, CanFrame, EmbeddedFrame, Frame, Id, SocketOptions, tokio::CanSocket, -}; +use socketcan::{CanDataFrame, CanFrame}; use tokio::{ signal, sync::mpsc::{self, Receiver, Sender}, @@ -33,6 +27,8 @@ use tokio_util::task::TaskTracker; use tracing::{debug, info, level_filters::LevelFilter, trace, warn}; use tracing_subscriber::{EnvFilter, fmt::format::FmtSpan}; +use calypso::can::{can_manager, create_frame, release_commands}; + const ENCODER_MAP_SUB: &str = "Calypso/Bidir/Command/#"; /// Calypso command line arguments @@ -61,6 +57,10 @@ struct CalypsoArgs { )] socketcan_iface: String, + /// The `UDP` interface IP + #[arg(short = 'i', long, env = "CALYPSO_ETH_IP", default_value = "224.0.0.1")] + eth_ip: Option, + /// Whether to enable MQTT multi-client #[arg(short = 'm', long, env = "CALYPSO_MQTT_MULTICLIENT")] mqtt_multiclient: bool, @@ -70,174 +70,6 @@ struct CalypsoArgs { imd: bool, } -/** - * Reads the can socket and publishes the data to siren channel - * `can_interface`: the socketcan interface to bind to - * `send_to_siren`: the channel to send protobuf messages to - * `alt_send_to_siren`: the channel to send priority queue alt messages to - * `send_over_can`: can messages to be sent over CAN - */ -async fn can_manager( - token: CancellationToken, - can_interface: String, - main_send_to_siren: Sender<(String, ServerData)>, - alt_send_to_siren: Option>, - send_raw_can: Option>, - mut send_over_can: Receiver, -) { - let mut socket = CanSocket::open(&can_interface).expect("Failed to open CAN socket!"); - socket - .set_error_filter_accept_all() - .expect("Failed to set error mask on CAN socket!"); - socket - .set_recv_own_msgs(true) // important to get the bidir messages - .expect("Cant recv own messages"); - - // the rate variables, updated every 3 seconds to the user - let mut mqtt_cnt: u64 = 0u64; - let mut frame_cnt: u64 = 0u64; - let mut disp_interval = tokio::time::interval(Duration::from_secs(3)); - let mut time_interval = tokio::time::Instant::now(); - - loop { - tokio::select! { - () = token.cancelled() => { - debug!("Shutting down CAN reader!"); - break; - }, - Some(frame) = socket.next() => { - frame_cnt += 1; - pub_frame(frame, &main_send_to_siren, alt_send_to_siren.as_ref(), send_raw_can.as_ref(), &mut mqtt_cnt, ).await; - } - Some(frame) = send_over_can.recv() => { - match socket.write_frame(frame).await { - Ok(()) => (), - Err(r) => warn!("Could not send CAN frame: {}", r), - } - }, - _ = disp_interval.tick() => { - info!("{:.3} msgs/sec and {:.3} frames/sec", (mqtt_cnt as f64 - / (tokio::time::Instant::now() - time_interval).as_millis() as f64) * 1000f64, - (frame_cnt as f64 / (tokio::time::Instant::now() - time_interval).as_millis() as f64) * 1000f64); - time_interval = tokio::time::Instant::now(); - frame_cnt = 0; - mqtt_cnt = 0; - } - } - } -} - -/** - * Handles reception of a frame or error - * frame: the frame - * `main_send`: the siren receiver - * `alt_send`: the priority siren receiver - * cnt: a variable incremented per MQTT message sent over `main_send` - */ -async fn pub_frame( - frame: Result, - main_send: &Sender<(String, ServerData)>, - alt_send: Option<&Sender<(String, ServerData)>>, - raw_send: Option<&Sender>, - cnt: &mut u64, -) { - let decoded_data = match frame { - // CanDataFrame - Ok(CanFrame::Data(data_frame)) => { - let data = data_frame.data(); - let id: u32 = match data_frame.id() { - socketcan::Id::Standard(std) => std.as_raw().into(), - socketcan::Id::Extended(ext) => ext.as_raw(), - }; - if let Some(send) = raw_send { - // for now just hardcode IMD - if id == 0x23 - && let Err(err) = send.send(data_frame).await - { - warn!("Could not send IMD code the response! {}", err); - } - } - trace!("RECVED message with ID: {:#01x}", id); - match DECODE_FUNCTION_MAP.get(&id) { - Some(func) => func(data), - None => vec![DecodeData::new( - vec![id as f32], - "Calypso/Unknown", - "ID", - None, - )], - } - } - // CanRemoteFrame - Ok(CanFrame::Remote(remote_frame)) => { - // Send frame ID for Remote - vec![DecodeData::new( - vec![remote_frame.raw_id() as f32], - "Calypso/Events/RemoteFrame", - "id", - None, - )] - } - // CanErrorFrame - Ok(CanFrame::Error(error_frame)) => { - // Publish enum index of error onto CAN - // TODO: maybe look into better representation? - let error_index: f32 = match CanError::from(error_frame) { - CanError::TransmitTimeout => 0.0, - CanError::LostArbitration(_) => 1.0, - CanError::ControllerProblem(_) => 2.0, - CanError::ProtocolViolation { .. } => 3.0, - CanError::TransceiverError => 4.0, - CanError::NoAck => 5.0, - CanError::BusOff => 6.0, - CanError::BusError => 7.0, - CanError::Restarted => 8.0, - CanError::DecodingFailure(_) => 9.0, - CanError::Unknown(_) => 10.0, - }; - vec![DecodeData::new( - vec![error_index], - "Calypso/Events/ErrorFrame", - "CanError enum", - None, - )] - } - // Socket failure - Err(err) => { - warn!("CAN Socket failure: {}", err); - return; - } - }; - // TODO switch to hardware timestamps - let timestamp = UNIX_EPOCH.elapsed().unwrap().as_micros() as u64; - - // Convert decoded CAN to Protobuf and publish over MQTT - for data in &decoded_data { - *cnt += 1; - let mut payload = serverdata::ServerData::new(); - payload.unit.clone_from(&data.unit); - payload.values.clone_from(&data.value); - payload.time_us = timestamp; - - if let Some(alt_send) = alt_send - && let Some(clients) = &data.clients - && clients.first().unwrap_or(&0) == &1882 - { - match alt_send.send((data.topic.clone(), payload.clone())).await { - Ok(()) => trace!("Sent a CAN message to SIREN manager alt"), - Err(err) => { - warn!("Could not send CAN message to SIREN manager alt: {}", err); - } - } - } - - match main_send.send((data.topic.clone(), payload)).await { - Ok(()) => trace!("Sent a CAN message to SIREN manager"), - Err(err) => warn!("Could not send CAN message to SIREN manager: {}", err), - } - } -} - /** * Inits siren communication, returning the main (1st) and priority (2nd) structs * `pub_path`: The base URL (and port for main) @@ -439,50 +271,6 @@ async fn bidir_manager( } } -/** - * Helper function to create a `CanFrame` - * msg: (id, `EncodeData`), the message to send - */ -fn create_frame(msg: (&u32, &EncodeData)) -> Option { - let id: Id = if msg.1.is_ext { - socketcan::ExtendedId::new(msg.1.id) - .unwrap_or_else(|| panic!("Invalid extended ID: {}", msg.1.id)) - .into() - } else { - socketcan::StandardId::new( - msg.1 - .id - .try_into() - .unwrap_or_else(|_| panic!("Invalid standard ID: {}", msg.1.id)), - ) - .unwrap_or_else(|| panic!("Invalid standard ID: {}", msg.1.id)) - .into() - }; - - CanFrame::new(id, &msg.1.value) -} - -/** - * Helper function to dump the current bidir commands into CAN - * `send_map`: A map of CAN IDs and data to be sent to the car - * `can_push_send`: A channel to send CAN messages - */ -async fn release_commands(send_map: &HashMap, can_push_send: &Sender) { - for msg in send_map { - // let id = u32::from_str_radix((msg.1.1).trim_start_matches("0x"), 16).expect("Invalid CAN ID!"); - - match create_frame(msg) { - Some(packet) => match can_push_send.send(packet).await { - Ok(()) => (), - Err(err) => warn!("Error sending can command to can manager {}", err), - }, - None => { - warn!("Packet is too long: {}", msg.1); - } - } - } -} - /** * Helper function to parse a MQTT message to create the corresponding bidir update * msg: The raw MQTT message @@ -622,6 +410,10 @@ async fn main() { )); } + if let Some(eth_ip) = cli.eth_ip { + task_tracker.spawn(eth_manager(token.clone(), eth_ip, decoder_send.clone())); + } + task_tracker.spawn(bidir_manager( token.clone(), can_push_send.clone(), diff --git a/src/proto/firmware_data.proto b/src/proto/firmware_data.proto new file mode 100644 index 00000000..9d3647c7 --- /dev/null +++ b/src/proto/firmware_data.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package firmwaredata.v1; + +message FirmwareData { + string unit = 1; + // time since unix epoch in MICROSECONDS + uint64 time_us = 2; + repeated float values = 3; + string topic = 4; +} diff --git a/src/udp.rs b/src/udp.rs new file mode 100644 index 00000000..0499439c --- /dev/null +++ b/src/udp.rs @@ -0,0 +1,57 @@ +use crate::proto::firmware_data::FirmwareData; +use crate::proto::serverdata::ServerData; +use protobuf::Message; +use tokio::{net::UdpSocket, sync::mpsc::Sender}; +use tokio_util::sync::CancellationToken; +use tracing::{debug, warn}; + +/// the maximum UDP datagram size to read +const MAX_BUF_SIZE: usize = 1024; + +/** + * The ethernet manager to recieve ethernet packets and send them over MQTT (Input `FirmwareData`, output `ServerData`) + * + * # Errors + * Errors if the UDP socket incurs an underlying IO error + */ +pub async fn eth_manager( + token: CancellationToken, + eth_ip: String, + main_send_to_siren: Sender<(String, ServerData)>, +) -> Result<(), std::io::Error> { + let sock = UdpSocket::bind(eth_ip).await?; + let mut buf = [0; MAX_BUF_SIZE]; + loop { + tokio::select! { + () = token.cancelled() => { + debug!("Shutting down ETH reader!"); + break; + }, + Ok((len, _)) = sock.recv_from(&mut buf) => { + if len >= MAX_BUF_SIZE { + warn!("Exceeded maximum ethernet buffer size, please increase!"); + continue; + } + handle_eth_msg(&buf[0..len], &main_send_to_siren).await; + } + } + } + + Ok(()) +} + +async fn handle_eth_msg(data: &[u8], main_send_to_siren: &Sender<(String, ServerData)>) { + let Ok(data) = FirmwareData::parse_from_bytes(data) else { + warn!("Could not parse packet, not valid protobuf!"); + return; + }; + + let mut server_data = ServerData::new(); + server_data.time_us = data.time_us; + server_data.unit = data.unit; + server_data.values = data.values; + + if let Err(err) = main_send_to_siren.send((data.topic, server_data)).await { + warn!("Could not send ETH translated packet over channel: {}", err); + } +}