Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
61a94a14cd v0.0.1 Proof of Concept for PDR (#6)
Communication between world server (Unity) and external test device (SoC) proven, as shown in logs.

Still TODO:
- [ ] REST endpoint to export data [likely going to be a unique repo]
- [ ] VDMA for image processing

Reviewed-on: #6
Reviewed-by: Isaacsouthwell <ias4117@rit.edu>
Co-authored-by: Blizzard Finnegan <blizzardfinnegan@gmail.com>
Co-committed-by: Blizzard Finnegan <blizzardfinnegan@gmail.com>
2024-03-29 11:13:12 -04:00
9 changed files with 920 additions and 4 deletions

4
.gitignore vendored
View file

@ -1 +1,3 @@
/target
target/
logs/
test.png

627
Cargo.lock generated
View file

@ -2,6 +2,633 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bumpalo"
version = "3.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa"
[[package]]
name = "bytemuck"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets 0.52.4",
]
[[package]]
name = "color_quant"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "communication-layer"
version = "0.1.0"
dependencies = [
"chrono",
"fern",
"image",
"ipnet",
"local-ip-address",
"log",
"rand",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "crc32fast"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
dependencies = [
"cfg-if",
]
[[package]]
name = "either"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
[[package]]
name = "fdeflate"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645"
dependencies = [
"simd-adler32",
]
[[package]]
name = "fern"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee"
dependencies = [
"log",
]
[[package]]
name = "flate2"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "getrandom"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "gif"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2"
dependencies = [
"color_quant",
"weezl",
]
[[package]]
name = "iana-time-zone"
version = "0.1.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "image"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9b4f005360d32e9325029b38ba47ebd7a56f3316df09249368939562d518645"
dependencies = [
"bytemuck",
"byteorder",
"color_quant",
"gif",
"num-traits",
"png",
]
[[package]]
name = "ipnet"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
name = "js-sys"
version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "local-ip-address"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "136ef34e18462b17bf39a7826f8f3bbc223341f8e83822beb8b77db9a3d49696"
dependencies = [
"libc",
"neli",
"thiserror",
"windows-sys",
]
[[package]]
name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "miniz_oxide"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
dependencies = [
"adler",
"simd-adler32",
]
[[package]]
name = "neli"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1100229e06604150b3becd61a4965d5c70f3be1759544ea7274166f4be41ef43"
dependencies = [
"byteorder",
"libc",
"log",
"neli-proc-macros",
]
[[package]]
name = "neli-proc-macros"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c168194d373b1e134786274020dae7fc5513d565ea2ebb9bc9ff17ffb69106d4"
dependencies = [
"either",
"proc-macro2",
"quote",
"serde",
"syn 1.0.109",
]
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "png"
version = "0.17.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1"
dependencies = [
"bitflags",
"crc32fast",
"fdeflate",
"flate2",
"miniz_oxide",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "serde"
version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
]
[[package]]
name = "simd-adler32"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.53",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]]
name = "weezl"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
[[package]]
name = "windows-core"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets 0.52.4",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
dependencies = [
"windows_aarch64_gnullvm 0.52.4",
"windows_aarch64_msvc 0.52.4",
"windows_i686_gnu 0.52.4",
"windows_i686_msvc 0.52.4",
"windows_x86_64_gnu 0.52.4",
"windows_x86_64_gnullvm 0.52.4",
"windows_x86_64_msvc 0.52.4",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"

View file

@ -6,3 +6,10 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chrono = "0.4.35"
fern = "0.6.2"
image = { version = "0.25.0", default-features = false, features = ["png","ff","gif"] }
ipnet = "2.9.0"
local-ip-address = "0.6.1"
log = "0.4.21"
rand = "0.8.5"

View file

@ -1,3 +1,13 @@
# virtual-camera
Library and server for dissemination of images obtained from the world server.
Library and server for dissemination of images obtained from the world server.
Currently uses TCP to stream images from the world server. Images are saved temporarily for testing purposes.
## Development
For development, you must first have Rust installed. This can be done by following the instructions found at [https://rustup.rs/](https://rustup.rs/). Once this is done, clone this repository, and in the root folder of the repository, run `cargo build --release`. This will both build the dependencies, install the correct toolchains, and create a final executable.
## Testing
To test this, first download the `comms-testing` branch of the World Server repository, open the `tennis` project, and run the project. Once this is done, build the latest version of this repository, as mentioned above. Finally, run this project, using `cargo run`.

BIN
logScreeenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

View file

@ -0,0 +1,7 @@
2024-03-21T14:47:31.759962308-04:00 - [INFO, communication_layer] - aggregating all IPs... This may take several minutes...
2024-03-21T14:47:36.825148581-04:00 - [INFO, communication_layer] - Stream connected to address: Ok(192.168.0.80:55001)
2024-03-21T14:47:36.825292754-04:00 - [INFO, communication_layer] - Start reading...
2024-03-21T14:47:38.021199638-04:00 - [INFO, communication_layer] - Image successfully recieved
2024-03-21T14:47:38.021453459-04:00 - [INFO, communication_layer] - Building image...
2024-03-21T14:47:39.127447553-04:00 - [INFO, communication_layer] - Image built, saving to file...
2024-03-21T14:47:44.733286335-04:00 - [INFO, communication_layer] - image saved!

View file

@ -1,5 +1,13 @@
<<<<<<< HEAD
Communication layer:
Add image resolution to initial handshake
unity: send x and y resolution
SOC: send back colour bit depth
unity: check bitdepth before beginning image transfer
=======
Rust Crate: `image-0.24.9`
Read image using `ImageBuffer::from_raw(w,h,bytes)`
image size: 4608 x 2592 x 3 [BGR]
>>>>>>> main

View file

@ -1,5 +1,5 @@
[toolchain]
channel="1.76.0-2024-02-08"
components = [ "rustc", "cargo", "rust-std", "rustfmt", "rust-docs", "rust-analyzer" ]
targets = [ "armv7-unknown-linux-musleabi" ]
targets = [ "armv7-unknown-linux-gnueabihf" ]
profile = "default"

View file

@ -1,3 +1,258 @@
use std::{ fs, io::{Bytes, stdin, BufReader, Error, ErrorKind, Read, Write}, net::{IpAddr, Ipv4Addr, SocketAddrV4, TcpStream}, path::Path, thread::{self, JoinHandle}, time::Duration};
use chrono::{DateTime, Local};
use image::{Rgb, RgbImage};
use ipnet::{Ipv4Net,PrefixLenError};
use local_ip_address::linux::local_ip;
use log::{LevelFilter, trace,debug,warn,error,info};
use fern::{log_file, Dispatch};
//RTSP port is 554; prepare for real world situations
const PORT_NUMBER:u16 = 55001;
const PORT_PROBE_TIMEOUT:Duration = Duration::new(5,0);
const SUBNET_SIZE:u8 = 24;
//These subnets are well documented;
///RIT owns the subnet 129.21.0.0/16; probing by attempting to open thousands of TCP streams
///simultaneously is unwise.
const UNSAFE_SUBNET:Result<Ipv4Net,PrefixLenError> = Ipv4Net::new(Ipv4Addr::new(129,21,0,0),16);
///This subnet is universally considered the "local" subnet. This results in 256 addresses, and can
///be probed both safely and efficiently, and as long as the world server on the LAN is running it
///is functionally guaranteeed to be found.
const HOME_SUBNET:Result<Ipv4Net,PrefixLenError> = Ipv4Net::new(Ipv4Addr::new(192,168,0,0),24);
fn main() {
println!("Hello, world!");
setup_logs(&true);
//Get host IP
let host_ip = local_ip().expect("No real IP address!");
trace!("Host IP: {:?}",host_ip);
let mut thread_list:Vec<JoinHandle<Result<TcpStream,Error>>> = Vec::new();
let mut port_list:Vec<TcpStream> = Vec::new();
if let IpAddr::V4(host_v4_ip) = host_ip{
//Check current subnet
let net = Ipv4Net::new(host_v4_ip,SUBNET_SIZE);
if let Ok(net) = net{
//RIT owns 129.21.0.0/16; DO NOT SPAM THIS NETWORK
if UNSAFE_SUBNET.unwrap().contains(&net){
//Request world server address from user
let address = manual_address_prompt();
if address.is_ok(){
port_list.push(address.unwrap());
//thread_list won't be added to, so the thread for loop won't execute
}
} else if net.contains(&HOME_SUBNET.unwrap()){
//Collect all Hosts on the current subnet
info!("aggregating all IPs... This may take several minutes...");
for net_address in net.hosts(){
thread_list.push(
thread::spawn(move ||{
let ip_port = std::net::SocketAddr::V4(SocketAddrV4::new(net_address, PORT_NUMBER));
//Attempt to open a TCP stream with this IP address, exit the thread
//returning the open TcpStream, or an error
return TcpStream::connect_timeout(&ip_port, PORT_PROBE_TIMEOUT);
})
);
}
}
}
}
//Multithread the port-sniffing block, only save sucessful connections
for thread in thread_list{
let output = thread.join().unwrap();
if let Ok(real_output) = output{
port_list.push(real_output);
}
}
//For all available ports, try the custom communication protocol
for mut stream in port_list{
info!("Stream connected to address: {:?}",stream.peer_addr());
send_processing_time(&mut stream, 2.7f64);
read_response(&mut stream);
}
//TODO: Document/implement RTSP client-side comms
//Currently using custom port and custom protocol, but if real-world cameras will
//be in use, we will likely need to be portable to the RTSP protocol, or similar
}
//Used to send the calculated time value to the world server
pub fn send_processing_time(stream:&mut TcpStream ,sent_value:f64){
debug!("Begin handshake; sending timestamp float...");
//Write the f64 value, in bytes, to the stream, and ensure it has been sent
stream.write(&sent_value.to_le_bytes()).unwrap();
stream.flush().unwrap();
debug!("Timestamp sent!");
}
//Used to recieve images from the world server
pub fn read_response(stream:&mut TcpStream){
//Buffer the incoming stream
let reader = BufReader::new(stream.try_clone().expect("Failed clone"));
//Create a storage point for the bytes
let mut recieved_bytes:Vec<u8> = Vec::new();
//Create an iterator over the stream's bytes
let mut iter = reader.bytes();
debug!("Continue handshake, read back image packet length...");
//The first values sent will always be a u32 containing the length of the message (without the
//length counted), followed by the image width and height
let length = bytes_to_u32(&mut iter);
debug!("Image packet length read as {:?}!",length);
debug!("Continue handshake, read back image width...");
let image_width = bytes_to_u32(&mut iter);
debug!("Image width read as {:?}!",image_width);
debug!("Continue handshake, read back image height...");
let image_height = bytes_to_u32(&mut iter);
debug!("Image height read as {:?}!",image_height);
//The length of the image is the total number of bytes
let byte_depth = length / (image_width * image_height);
debug!("Image bitdepth calculated as {:?}!", byte_depth);
//Confirm to world server the correct number of bytes
stream.write(&byte_depth.to_le_bytes()).unwrap();
stream.flush().unwrap();
//TODO: Remove assumption
//Always assumes world server will send image
info!("Start reading...");
//Recieve the rest of the message
for _ in 0..length{
recieved_bytes.push(iter.next().unwrap().unwrap_or(0));
}
info!("Image successfully recieved");
//Create a blank pane on which to store the read in pixels
let mut img = RgbImage::new(image_width,image_height);
//Create a temporary storage point for u8s when generating pixels
let mut temp:Vec<u8> = Vec::new();
//Iterate over bytes
info!("Building image...");
for i in 0..recieved_bytes.len(){
let byte = recieved_bytes.get(i).expect("Index does not exist!");
temp.push(byte.clone());
//Each pixel is composed of [byte_depth] u8s
if ((i as u32)+1) % byte_depth == 0{
//Coordinate in the pane = i/3
let pixel_number:u32 = (i as u32) /byte_depth;
//Insert the pixel into the pane
img.put_pixel(
//Pixels coming directly from Unity are sent "upside down", that is,
//starting at the bottom right, and iterating horizontally, then vertically.
//This line compensates and creates a properly-oriented image
(image_width-1)-(pixel_number%image_width), (image_height-1)-(pixel_number / image_width),
//Extract image from temporary storage, ang generate pixel
Rgb::<u8>{0:temp.clone().try_into().expect("bad vector length!")}
);
//Clear temporary storage
temp.clear();
}
}
//Dump image to file
//ONLY FOR EXPERIMENTATION AND TESTING PURPOSES
info!("Image built, saving to file...");
_ = img.save("./test.png");
info!("image saved!");
}
///Borrows an iterator over the bytes in a buffered-reader of a TcpStream; reads the next 4 bytes,
///outputs the generated u32
fn bytes_to_u32(iter:&mut Bytes<BufReader<TcpStream>>) -> u32{
let mut array:[u8;4] = [0;4];
for i in 0..4{
array[i] = iter.next().unwrap().unwrap();
}
return u32::from_le_bytes(array);
}
///Request the user to input the world server's address into stdin
fn manual_address_prompt() -> Result<TcpStream,Error>{
let return_val:Result<TcpStream,Error> = Err(Error::new(ErrorKind::AddrNotAvailable,"Invalid Address"));
while return_val.is_err(){
let mut user_input:String = String::default();
match stdin().read_line(&mut user_input){
Ok(_) => {
match user_input.trim().parse::<SocketAddrV4>(){
Ok(address) => {
//Test if the address is accurate
let stream = TcpStream::connect_timeout(&std::net::SocketAddr::V4(address), PORT_PROBE_TIMEOUT);
if stream.is_ok(){
return stream;
} else {
warn!("Address unavailable!");
debug!("{:?}",stream.unwrap_err());
}
},
Err(error) => {
error!("Unable to properly parse user input!");
debug!("{:?}",error);
}
}
},
Err(error) => {
error!("Unable to read user input!");
debug!("{:?}",error);
}
}
}
return return_val;
}
///Set up logging macros to be used throughout the program
fn setup_logs(debug:&bool){
//Get the current time
let chrono_now: DateTime<Local> = Local::now();
//Create a log directory, if it does not exist
if ! Path::new("logs").is_dir(){
_ = fs::create_dir("logs");
};
//Create a log macro listener
_ = fern::Dispatch::new()
//Format the output messages
.format(|out,message,record|{
out.finish(format_args!(
"{} - [{}, {}] - {}",
Local::now().to_rfc3339(),
record.level(),
record.target(),
message
))
})
//Output to the file
.chain({
let mut file_logger = Dispatch::new();
let date_format = chrono_now.format("%Y-%m-%d_%H.%M").to_string();
let local_log_file = log_file(format!("logs/{}.log",date_format)).unwrap();
//Set filter based on whether the command is being run in "debug" mode
if *debug{
file_logger = file_logger.level(LevelFilter::Trace);
}
else {
file_logger = file_logger.level(LevelFilter::Debug);
}
//Apply the filter and file formatting rules described above
file_logger.chain(local_log_file)
})
.chain({
//Also log to stdout
let mut stdout_logger = fern::Dispatch::new();
if *debug {
stdout_logger = stdout_logger.level(LevelFilter::Debug);
}
else {
stdout_logger = stdout_logger.level(LevelFilter::Info);
}
stdout_logger.chain(std::io::stdout())
})
//Start listening to macros
.apply();
}