add beast, http-json, collectd-stats
This commit is contained in:
parent
1fb409758b
commit
afca212069
|
@ -2,6 +2,25 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adsb"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9245ecd631f63f1995269dc9f88fdda8fc8e9a308c4196315cfdedd1ccfccc07"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.4.0"
|
||||
|
@ -11,6 +30,12 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "as-slice"
|
||||
version = "0.1.5"
|
||||
|
@ -46,12 +71,33 @@ version = "0.13.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||
|
||||
[[package]]
|
||||
name = "beast"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"adsb",
|
||||
"futures",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "0.19.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium",
|
||||
"tap",
|
||||
"wyz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blake2"
|
||||
version = "0.9.2"
|
||||
|
@ -81,9 +127,9 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
|
|||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.17"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
|
||||
checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
|
@ -91,6 +137,16 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "buf_redux"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"safemem",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.8.0"
|
||||
|
@ -131,6 +187,15 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "collectd-stats"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"beast",
|
||||
"nav-types",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.2"
|
||||
|
@ -265,6 +330,12 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
|
||||
|
||||
[[package]]
|
||||
name = "futf"
|
||||
version = "0.1.4"
|
||||
|
@ -417,7 +488,7 @@ version = "0.7.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8bd2e95dd9f5c8ff74159ed9205ad7fd239a9569173a550863976421b45d2bb"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"approx 0.4.0",
|
||||
"num-traits",
|
||||
"rstar",
|
||||
]
|
||||
|
@ -487,6 +558,31 @@ version = "0.11.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||
|
||||
[[package]]
|
||||
name = "headers"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c4eb0471fcb85846d8b0690695ef354f9afb11cb03cac2e1d7c9253351afb0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bitflags",
|
||||
"bytes",
|
||||
"headers-core",
|
||||
"http",
|
||||
"httpdate",
|
||||
"mime",
|
||||
"sha-1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "headers-core"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
|
||||
dependencies = [
|
||||
"http",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heapless"
|
||||
version = "0.6.1"
|
||||
|
@ -575,6 +671,18 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-json"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"adsb",
|
||||
"beast",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"warp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.5.1"
|
||||
|
@ -645,6 +753,15 @@ dependencies = [
|
|||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "input_buffer"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f97967975f448f1a7ddb12b0bc41069d09ed6a1c161a92687e057325db35d413"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
|
@ -708,6 +825,19 @@ version = "1.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lexical-core"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"ryu",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.105"
|
||||
|
@ -780,10 +910,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.1"
|
||||
name = "matrixmultiply"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
checksum = "916806ba0031cd542105d916a97c8572e1fa6dd79c9c51e7eb43a09ec2dd84c1"
|
||||
dependencies = [
|
||||
"rawpointer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
|
@ -791,6 +930,16 @@ version = "0.3.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212"
|
||||
dependencies = [
|
||||
"mime",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minidom"
|
||||
version = "0.13.0"
|
||||
|
@ -822,6 +971,42 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multipart"
|
||||
version = "0.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d050aeedc89243f5347c3e237e3e13dc76fbe4ae3742a57b94dc14f69acf76d4"
|
||||
dependencies = [
|
||||
"buf_redux",
|
||||
"httparse",
|
||||
"log",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"quick-error",
|
||||
"rand 0.7.3",
|
||||
"safemem",
|
||||
"tempfile",
|
||||
"twoway",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nalgebra"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "500430fe18b836c0099c22e716139eae37210ecf8e1ae3931b73078e9a2de7a9"
|
||||
dependencies = [
|
||||
"approx 0.3.2",
|
||||
"generic-array 0.13.3",
|
||||
"matrixmultiply",
|
||||
"num-complex",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"rand 0.7.3",
|
||||
"rand_distr",
|
||||
"simba",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.8"
|
||||
|
@ -840,12 +1025,34 @@ dependencies = [
|
|||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nav-types"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a761b66b2e27aba4945f8e82ad20aef2dac0f47f9659ecbbdf54095c79828a37"
|
||||
dependencies = [
|
||||
"nalgebra",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "new_debug_unreachable"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "6.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c5c51b9083a3c620fa67a2a635d1ce7d95b897e957d6b28ff9a5da960a103a6"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"funty",
|
||||
"lexical-core",
|
||||
"memchr",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.3.6"
|
||||
|
@ -855,6 +1062,16 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
|
@ -865,6 +1082,17 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
|
@ -954,6 +1182,25 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
|
||||
dependencies = [
|
||||
"paste-impl",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste-impl"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pbkdf2"
|
||||
version = "0.6.0"
|
||||
|
@ -1022,6 +1269,26 @@ dependencies = [
|
|||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.7"
|
||||
|
@ -1097,6 +1364,12 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "radium"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
|
@ -1161,6 +1434,15 @@ dependencies = [
|
|||
"getrandom 0.2.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_distr"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
|
||||
dependencies = [
|
||||
"rand 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
|
@ -1188,6 +1470,12 @@ dependencies = [
|
|||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rawpointer"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.10"
|
||||
|
@ -1290,6 +1578,12 @@ version = "1.0.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "safemem"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
|
||||
|
||||
[[package]]
|
||||
name = "sasl"
|
||||
version = "0.5.0"
|
||||
|
@ -1314,6 +1608,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
|
@ -1451,6 +1751,18 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simba"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "051b345c9ec09734622cbb49e20dfcf72c9b55e473f0ca6a8025409e37c25fb8"
|
||||
dependencies = [
|
||||
"approx 0.3.2",
|
||||
"num-complex",
|
||||
"num-traits",
|
||||
"paste",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.7"
|
||||
|
@ -1496,6 +1808,12 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
version = "0.8.2"
|
||||
|
@ -1539,6 +1857,12 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.2.0"
|
||||
|
@ -1661,6 +1985,19 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-tungstenite"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1a5f475f1b9d077ea1017ecbc60890fda8e54942d680ca0b1d2b47cfa2d861b"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"pin-project",
|
||||
"tokio",
|
||||
"tungstenite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.6.8"
|
||||
|
@ -1711,6 +2048,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
|
@ -1775,6 +2113,34 @@ version = "0.2.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
||||
|
||||
[[package]]
|
||||
name = "tungstenite"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ada8297e8d70872fa9a551d93250a9f407beb9f37ef86494eb20012a2ff7c24"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"http",
|
||||
"httparse",
|
||||
"input_buffer",
|
||||
"log",
|
||||
"rand 0.8.4",
|
||||
"sha-1",
|
||||
"url",
|
||||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "twoway"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.14.0"
|
||||
|
@ -1787,6 +2153,15 @@ version = "0.1.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.7"
|
||||
|
@ -1854,6 +2229,35 @@ dependencies = [
|
|||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "warp"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "332d47745e9a0c38636dbd454729b147d16bd1ed08ae67b3ab281c4506771054"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures",
|
||||
"headers",
|
||||
"http",
|
||||
"hyper",
|
||||
"log",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"multipart",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"scoped-tls",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-tungstenite",
|
||||
"tokio-util",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
|
@ -1988,6 +2392,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
|
||||
|
||||
[[package]]
|
||||
name = "xml5ever"
|
||||
version = "0.16.2"
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"heliwatch",
|
||||
"beast",
|
||||
"http-json",
|
||||
"collectd-stats",
|
||||
]
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "beast"
|
||||
description = "Receive ADS-B data from readsb"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
adsb = "0.3"
|
|
@ -0,0 +1,153 @@
|
|||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::time::{Duration, Instant};
|
||||
use futures::stream::StreamExt;
|
||||
use tokio::sync::mpsc::channel;
|
||||
use adsb::ICAOAddress;
|
||||
use super::beast;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Entry {
|
||||
pub emitter_category: Option<u8>,
|
||||
pub callsign: Option<String>,
|
||||
pub altitude: Option<u16>,
|
||||
cpr1: Option<adsb::CPRFrame>,
|
||||
cpr2: Option<adsb::CPRFrame>,
|
||||
pub heading: Option<f64>,
|
||||
pub ground_speed: Option<f64>,
|
||||
pub vertical_rate: Option<i16>,
|
||||
pub vertical_rate_source: Option<adsb::VerticalRateSource>,
|
||||
last_update: Option<Instant>,
|
||||
}
|
||||
|
||||
impl Entry {
|
||||
const MAX_AGE: u64 = 300;
|
||||
|
||||
fn update(&mut self, kind: adsb::ADSBMessageKind) {
|
||||
match kind {
|
||||
adsb::ADSBMessageKind::AirbornePosition {
|
||||
altitude, cpr_frame
|
||||
} => {
|
||||
self.altitude = Some(altitude);
|
||||
if self.cpr2.as_ref().map(|cpr2| cpr2.parity != cpr_frame.parity).unwrap_or(false) {
|
||||
self.cpr1 = self.cpr2.take();
|
||||
}
|
||||
self.cpr2 = Some(cpr_frame);
|
||||
}
|
||||
adsb::ADSBMessageKind::AirborneVelocity {
|
||||
heading, ground_speed,
|
||||
vertical_rate, vertical_rate_source,
|
||||
} => {
|
||||
self.heading = Some(heading);
|
||||
self.ground_speed = Some(ground_speed);
|
||||
self.vertical_rate = Some(vertical_rate);
|
||||
self.vertical_rate_source = Some(vertical_rate_source);
|
||||
}
|
||||
adsb::ADSBMessageKind::AircraftIdentification {
|
||||
emitter_category, callsign
|
||||
} => {
|
||||
self.emitter_category = Some(emitter_category);
|
||||
self.callsign = Some(callsign);
|
||||
}
|
||||
}
|
||||
|
||||
self.last_update = Some(Instant::now());
|
||||
}
|
||||
|
||||
pub fn location(&self) -> Option<adsb::Position> {
|
||||
match (&self.cpr1, &self.cpr2) {
|
||||
(Some(cpr1), Some(cpr2)) => {
|
||||
let pos = adsb::cpr::get_position((cpr1, cpr2))?;
|
||||
if pos.latitude >= -90.0 && pos.latitude <= 90.0 &&
|
||||
pos.longitude >= -180.0 && pos.longitude <= 180.0
|
||||
{
|
||||
Some(pos)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ =>
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Aircrafts {
|
||||
state: Arc<RwLock<HashMap<ICAOAddress, RwLock<Entry>>>>,
|
||||
}
|
||||
|
||||
impl Aircrafts {
|
||||
pub fn new() -> Self {
|
||||
Aircrafts {
|
||||
state: Arc::new(RwLock::new(HashMap::new())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(&self) -> std::sync::RwLockReadGuard<HashMap<ICAOAddress, RwLock<Entry>>> {
|
||||
self.state.read().unwrap()
|
||||
}
|
||||
|
||||
pub fn connect(&self, host: &'static str, port: u16) {
|
||||
// buffering channel because readsb is very sensitive
|
||||
let (tx, mut rx) = channel(16 * 1024);
|
||||
|
||||
// network input
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
let mut stream;
|
||||
if let Ok(stream_) = beast::connect(host, port).await {
|
||||
stream = Box::pin(stream_);
|
||||
} else {
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
// Retry
|
||||
continue;
|
||||
}
|
||||
|
||||
while let Some(frame) = stream.next().await {
|
||||
let _ = tx.send(frame).await;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// state update
|
||||
let state = self.state.clone();
|
||||
tokio::spawn(async move {
|
||||
while let Some(frame) = rx.recv().await {
|
||||
match frame.parse_adsb() {
|
||||
Some(adsb::Message {
|
||||
kind: adsb::MessageKind::ADSBMessage {
|
||||
icao_address,
|
||||
kind,
|
||||
crc,
|
||||
.. },
|
||||
.. }) if crc =>
|
||||
{
|
||||
state.write().unwrap()
|
||||
.entry(icao_address)
|
||||
.or_default()
|
||||
.write().unwrap()
|
||||
.update(kind);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// discard old states
|
||||
let state = self.state.clone();
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
state.write().unwrap().
|
||||
retain(|_, entry| {
|
||||
entry.read().unwrap()
|
||||
.last_update.map(|last_update| {
|
||||
last_update + Duration::from_secs(Entry::MAX_AGE) > Instant::now()
|
||||
})
|
||||
.unwrap_or(false)
|
||||
});
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
use futures::stream;
|
||||
use tokio::io::AsyncReadExt;
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
const DEFRAMER_DEFAULT_CAPACITY: usize = 22;
|
||||
|
||||
struct Deframer {
|
||||
buffer: Vec<u8>,
|
||||
escapes: usize,
|
||||
}
|
||||
|
||||
impl Deframer {
|
||||
pub fn new() -> Self {
|
||||
Deframer {
|
||||
buffer: Vec::with_capacity(DEFRAMER_DEFAULT_CAPACITY),
|
||||
escapes: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push(&mut self, c: u8) -> Option<Frame> {
|
||||
let mut result = None;
|
||||
if c == 0x1a {
|
||||
self.escapes += 1;
|
||||
} else {
|
||||
if self.escapes > 0 {
|
||||
for _ in 0..(self.escapes / 2) {
|
||||
self.buffer.push(0x1a);
|
||||
}
|
||||
if self.escapes & 1 == 1 {
|
||||
let new_buffer = Vec::with_capacity(DEFRAMER_DEFAULT_CAPACITY);
|
||||
let buffer = std::mem::replace(&mut self.buffer, new_buffer);
|
||||
if buffer.len() > 0 {
|
||||
result = Frame::new(buffer);
|
||||
}
|
||||
}
|
||||
self.escapes = 0;
|
||||
}
|
||||
|
||||
self.buffer.push(c);
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[repr(u8)]
|
||||
pub enum FrameType {
|
||||
ModeAC = '1' as u8,
|
||||
ModeSShort = '2' as u8,
|
||||
ModeSLong = '3' as u8,
|
||||
Config = '4' as u8,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Frame {
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Frame {
|
||||
pub fn new(data: Vec<u8>) -> Option<Self> {
|
||||
if data.len() < 1 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let this = Frame { data };
|
||||
match (this.frame_type(), this.data.len()) {
|
||||
(Some(FrameType::ModeAC), 10) =>
|
||||
Some(this),
|
||||
(Some(FrameType::ModeSShort), 15) =>
|
||||
Some(this),
|
||||
(Some(FrameType::ModeSLong), 22) =>
|
||||
Some(this),
|
||||
_ =>
|
||||
None // don't care
|
||||
}
|
||||
}
|
||||
|
||||
pub fn frame_type(&self) -> Option<FrameType> {
|
||||
match self.data[0] as char {
|
||||
'1' => Some(FrameType::ModeAC),
|
||||
'2' => Some(FrameType::ModeSShort),
|
||||
'3' => Some(FrameType::ModeSLong),
|
||||
'4' => Some(FrameType::Config),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn timestamp(&self) -> u64 {
|
||||
match self.frame_type() {
|
||||
Some(_) => {
|
||||
let mut result = 0;
|
||||
for i in 1..=6 {
|
||||
result |= u64::from(self.data[i]) << (8 * (6 - i));
|
||||
}
|
||||
result
|
||||
}
|
||||
None => 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn signal(&self) -> u8 {
|
||||
match self.frame_type() {
|
||||
Some(FrameType::ModeAC) |
|
||||
Some(FrameType::ModeSShort) |
|
||||
Some(FrameType::ModeSLong) => {
|
||||
self.data[7]
|
||||
}
|
||||
_ => 255
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_adsb(&self) -> Option<adsb::Message> {
|
||||
match self.frame_type() {
|
||||
Some(FrameType::ModeSShort) | Some(FrameType::ModeSLong) => {
|
||||
if let Ok((msg, _rest)) = adsb::parse_binary(&self.data[8..]) {
|
||||
Some(msg)
|
||||
} else {
|
||||
eprintln!("adsb decode error");
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn connect(host: &str, port: u16) -> Result<impl futures::Stream<Item = Frame>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
println!("Connecting to {}:{}", host, port);
|
||||
let conn = TcpStream::connect((host, port)).await?;
|
||||
println!("Connected to {}:{}", host, port);
|
||||
let stream = stream::unfold((conn, vec![], Deframer::new()), |(mut conn, mut buf, mut deframe)| async {
|
||||
loop {
|
||||
for i in 0..buf.len() {
|
||||
if let Some(frame) = deframe.push(buf[i]) {
|
||||
buf = buf.split_off(i + 1);
|
||||
return Some((frame, (conn, buf, deframe)));
|
||||
}
|
||||
} // buf consumed
|
||||
|
||||
if buf.len() < DEFRAMER_DEFAULT_CAPACITY {
|
||||
buf = vec![0; 1024];
|
||||
}
|
||||
match conn.read(&mut buf).await {
|
||||
Ok(0) | Err(_) => {
|
||||
println!("Disconnected");
|
||||
return None;
|
||||
}
|
||||
Ok(len) =>
|
||||
buf.truncate(len),
|
||||
}
|
||||
}
|
||||
});
|
||||
Ok(stream)
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
pub mod beast;
|
||||
pub mod aircrafts;
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "collectd-stats"
|
||||
description = "ADS-B statistics in collectd"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
nav-types = "0.5"
|
||||
beast = { path = "../beast" }
|
|
@ -0,0 +1,91 @@
|
|||
use std::time::Duration;
|
||||
use tokio::time::sleep;
|
||||
use nav_types::WGS84;
|
||||
|
||||
const INTERVAL: u64 = 10;
|
||||
|
||||
fn update_min<T: Clone + PartialOrd>(value: &Option<T>, target: &mut Option<T>) {
|
||||
match (value, target) {
|
||||
(Some(value), target) if target.is_none() =>
|
||||
*target = Some(value.clone()),
|
||||
(Some(value), Some(target)) if value < target =>
|
||||
*target = value.clone(),
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
||||
fn update_max<T: Clone + PartialOrd>(value: &Option<T>, target: &mut Option<T>) {
|
||||
match (value, target) {
|
||||
(Some(value), target) if target.is_none() =>
|
||||
*target = Some(value.clone()),
|
||||
(Some(value), Some(target)) if value > target =>
|
||||
*target = value.clone(),
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let home = WGS84::from_degrees_and_meters(51.081, 13.728, 0.0);
|
||||
|
||||
let aircrafts = beast::aircrafts::Aircrafts::new();
|
||||
aircrafts.connect("radiobert.serv.zentralwerk.org", 30005);
|
||||
let hostname_line = std::fs::read_to_string("/proc/sys/kernel/hostname")
|
||||
.unwrap();
|
||||
let hostname = hostname_line.split(char::is_whitespace)
|
||||
.next()
|
||||
.unwrap();
|
||||
|
||||
loop {
|
||||
sleep(Duration::from_secs(INTERVAL)).await;
|
||||
|
||||
let mut count = 0;
|
||||
let mut min_altitude = None;
|
||||
let mut max_altitude = None;
|
||||
let mut min_speed = None;
|
||||
let mut max_speed = None;
|
||||
let mut min_distance = None;
|
||||
let mut max_distance = None;
|
||||
let aircrafts = aircrafts.read();
|
||||
for (_, entry) in aircrafts.iter() {
|
||||
let entry = entry.read().unwrap();
|
||||
count += 1;
|
||||
|
||||
update_min(&entry.altitude, &mut min_altitude);
|
||||
update_max(&entry.altitude, &mut max_altitude);
|
||||
|
||||
update_min(&entry.ground_speed, &mut min_speed);
|
||||
update_max(&entry.ground_speed, &mut max_speed);
|
||||
|
||||
if let Some(pos) = entry.location() {
|
||||
let altitude_m = entry.altitude.unwrap_or(0) as f64 * 0.3048;
|
||||
let distance_km = WGS84::from_degrees_and_meters(pos.latitude, pos.longitude, altitude_m)
|
||||
.distance(&home) / 1000.0;
|
||||
update_min(&Some(distance_km), &mut min_distance);
|
||||
update_max(&Some(distance_km), &mut max_distance);
|
||||
}
|
||||
}
|
||||
println!("PUTVAL \"{}/beast-aircrafts/records\" interval={} N:{}", hostname, INTERVAL, count);
|
||||
|
||||
min_altitude.map(|min_altitude| {
|
||||
println!("PUTVAL \"{}/beast-altitude/current-min\" interval={} N:{}", hostname, INTERVAL, min_altitude);
|
||||
});
|
||||
max_altitude.map(|max_altitude| {
|
||||
println!("PUTVAL \"{}/beast-altitude/current-max\" interval={} N:{}", hostname, INTERVAL, max_altitude);
|
||||
});
|
||||
|
||||
min_speed.map(|min_speed| {
|
||||
println!("PUTVAL \"{}/beast-speed/current-min\" interval={} N:{:.3}", hostname, INTERVAL, min_speed);
|
||||
});
|
||||
max_speed.map(|max_speed| {
|
||||
println!("PUTVAL \"{}/beast-speed/current-max\" interval={} N:{:.3}", hostname, INTERVAL, max_speed);
|
||||
});
|
||||
|
||||
min_distance.map(|min_distance| {
|
||||
println!("PUTVAL \"{}/beast-distance/current-min\" interval={} N:{:.3}", hostname, INTERVAL, min_distance);
|
||||
});
|
||||
max_distance.map(|max_distance| {
|
||||
println!("PUTVAL \"{}/beast-distance/current-max\" interval={} N:{:.3}", hostname, INTERVAL, max_distance);
|
||||
});
|
||||
}
|
||||
}
|
18
flake.nix
18
flake.nix
|
@ -21,16 +21,26 @@
|
|||
cargo = rust;
|
||||
rustc = rust;
|
||||
};
|
||||
in rec {
|
||||
# `nix build`
|
||||
packages.heliwatch = naersk-lib.buildPackage {
|
||||
pname = "heliwatch";
|
||||
|
||||
buildRustPackage = args: naersk-lib.buildPackage ({
|
||||
root = ./.;
|
||||
src = ./heliwatch;
|
||||
nativeBuildInputs = with pkgs; [ pkg-config ];
|
||||
buildInputs = with pkgs; [ openssl ];
|
||||
} // args);
|
||||
in rec {
|
||||
# `nix build`
|
||||
packages.heliwatch = buildRustPackage {
|
||||
pname = "heliwatch";
|
||||
};
|
||||
packages.http-json = buildRustPackage {
|
||||
pname = "http-json";
|
||||
};
|
||||
packages.collectd-stats = buildRustPackage {
|
||||
pname = "collectd-stats";
|
||||
};
|
||||
defaultPackage = packages.heliwatch;
|
||||
checks = packages;
|
||||
|
||||
# `nix run`
|
||||
apps.heliwatch = utils.lib.mkApp {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "http-json"
|
||||
description = "Serves http://:8080/data.json for dump1090's HTML map"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
beast = { path = "../beast" }
|
||||
warp = "0.3"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
adsb = "0.3"
|
|
@ -0,0 +1,58 @@
|
|||
use warp::{http::Response, Filter};
|
||||
use adsb::ICAOAddress;
|
||||
use beast::aircrafts::Entry;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Aircraft {
|
||||
hex: String,
|
||||
flight: Option<String>,
|
||||
category: Option<u8>,
|
||||
lat: Option<f64>,
|
||||
lon: Option<f64>,
|
||||
/// ft
|
||||
altitude: Option<u16>,
|
||||
track: Option<i16>,
|
||||
/// kts
|
||||
speed: Option<u16>,
|
||||
}
|
||||
|
||||
impl Aircraft {
|
||||
pub fn new(icao_address: &ICAOAddress, entry: &Entry) -> Self {
|
||||
let pos = entry.location();
|
||||
Aircraft {
|
||||
hex: format!("{}", icao_address),
|
||||
flight: entry.callsign.clone(),
|
||||
category: entry.emitter_category.clone(),
|
||||
lat: pos.as_ref().map(|pos| pos.latitude),
|
||||
lon: pos.as_ref().map(|pos| pos.longitude),
|
||||
altitude: entry.altitude.clone(),
|
||||
track: entry.heading.map(|heading| heading as i16),
|
||||
speed: entry.ground_speed.map(|speed| speed as u16),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let aircrafts = beast::aircrafts::Aircrafts::new();
|
||||
aircrafts.connect("radiobert.serv.zentralwerk.org", 30005);
|
||||
|
||||
let hello = warp::path!("data.json")
|
||||
.map(move || {
|
||||
let data = aircrafts.read()
|
||||
.iter()
|
||||
.map(|(icao_address, entry)| Aircraft::new(icao_address, &entry.read().unwrap()))
|
||||
.collect::<Vec<Aircraft>>();
|
||||
let json = serde_json::ser::to_vec_pretty(&data)
|
||||
.unwrap_or_else(|_| vec![]);
|
||||
|
||||
Response::builder()
|
||||
.header("Content-Type", "application/json")
|
||||
.body(json)
|
||||
});
|
||||
|
||||
warp::serve(hello)
|
||||
.run(([0, 0, 0, 0], 8080))
|
||||
.await;
|
||||
}
|
Loading…
Reference in New Issue