From 1c5c9199d42b06858680889c95bb55e4f3bbb3da Mon Sep 17 00:00:00 2001 From: asonix Date: Sat, 5 Jun 2021 11:10:22 -0500 Subject: [PATCH] Desktop-side handshake + property checks --- .gitignore | 3 + Cargo.lock | 257 +++++++++++++++++++++++++++++ Cargo.toml | 11 ++ build-aux/cargo.sh | 23 +++ build.sh | 5 + dog.asonix.git.asonix.DeviceLs.yml | 40 +++++ meson.build | 13 ++ src/main.rs | 84 ++++++++++ src/meson.build | 25 +++ 9 files changed, 461 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100755 build-aux/cargo.sh create mode 100755 build.sh create mode 100644 dog.asonix.git.asonix.DeviceLs.yml create mode 100644 meson.build create mode 100644 src/main.rs create mode 100644 src/meson.build diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba5a416 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +/.flatpak-builder +/build diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..b546ffc --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,257 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "CoreFoundation-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0e9889e6db118d49d88d84728d0e964d973a5680befb5f85f55141beea5c20b" +dependencies = [ + "libc", + "mach 0.1.2", +] + +[[package]] +name = "IOKit-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99696c398cbaf669d2368076bdb3d627fb0ce51a26899d7c61228c5c0af3bf4a" +dependencies = [ + "CoreFoundation-sys", + "libc", + "mach 0.1.2", +] + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "cc" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "device-ls" +version = "0.1.0" +dependencies = [ + "rand", + "serialport", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" + +[[package]] +name = "libudev" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea626d3bdf40a1c5aee3bcd4f40826970cae8d80a8fec934c82a63840094dcfe" +dependencies = [ + "libc", + "libudev-sys", +] + +[[package]] +name = "libudev-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "mach" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd13ee2dd61cc82833ba05ade5a30bb3d63f7ced605ef827063c63078302de9" +dependencies = [ + "libc", +] + +[[package]] +name = "mach" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" + +[[package]] +name = "nix" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0eaf8df8bab402257e0a5c17a254e4cc1f72a93588a1ddfb5d356c801aa7cb" +dependencies = [ + "bitflags", + "cc", + "cfg-if 0.1.10", + "libc", + "void", +] + +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "serialport" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cd7c0f22290ee2c01457009fa6fc1cae4153d5608a924e5dc423babc2c655" +dependencies = [ + "CoreFoundation-sys", + "IOKit-sys", + "bitflags", + "cfg-if 0.1.10", + "libudev", + "mach 0.2.3", + "nix", + "regex", + "winapi", +] + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..9f1a71e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "device-ls" +version = "0.1.0" +authors = ["asonix "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.3" +serialport = "4.0.1" diff --git a/build-aux/cargo.sh b/build-aux/cargo.sh new file mode 100755 index 0000000..eedbb81 --- /dev/null +++ b/build-aux/cargo.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +export MESON_BUILD_ROOT="$1" +export MESON_SOURCE_ROOT="$2" +export CARGO_TARGET_DIR="$MESON_BUILD_ROOT"/target +export CARGO_HOME="$MESON_BUILD_ROOT"/cargo-home +export OUTPUT="$3" +export BUILDTYPE="$4" +export APP_BIN="$5" + + +if [ $BUILDTYPE = "release" ] +then + echo "RELEASE MODE" + cargo build --manifest-path \ + "$MESON_SOURCE_ROOT"/Cargo.toml --release && \ + cp "$CARGO_TARGET_DIR"/release/"$APP_BIN" "$OUTPUT" +else + echo "DEBUG MODE" + cargo build --manifest-path \ + "$MESON_SOURCE_ROOT"/Cargo.toml && \ + cp "$CARGO_TARGET_DIR"/debug/"$APP_BIN" "$OUTPUT" +fi diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..81c0d6f --- /dev/null +++ b/build.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -xe + +flatpak-builder build dog.asonix.git.asonix.DeviceLs.yml --user --install --force-clean diff --git a/dog.asonix.git.asonix.DeviceLs.yml b/dog.asonix.git.asonix.DeviceLs.yml new file mode 100644 index 0000000..7562d69 --- /dev/null +++ b/dog.asonix.git.asonix.DeviceLs.yml @@ -0,0 +1,40 @@ +app-id: dog.asonix.git.asonix.DeviceLs + +runtime: io.elementary.Platform +runtime-version: 'daily' +sdk: io.elementary.Sdk +sdk-extensions: + - 'org.freedesktop.Sdk.Extension.rust-stable' + +command: device-ls + +finish-args: + - '--device=all' + +build-options: + append-path: /usr/lib/sdk/rust-stable/bin + build-args: + - '--share=network' + env: + RUST_BACKTRACE: "1" + RUST_LOG: device_ls=debug + +cleanup: + - '/include' + - '/lib/pkgconfig' + - '/man' + - '/share/doc' + - '/share/gtk-doc' + - '/share/man' + - '/share/pkgconfig' + - '*.la' + - '*.a' + +modules: + - name: device-ls + buildsystem: meson + config-opts: + - -Dbuildtype=debug + sources: + - type: dir + path: . diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..0816a27 --- /dev/null +++ b/meson.build @@ -0,0 +1,13 @@ +project('device-ls', + version: '0.1.0', + meson_version: '>= 0.51.0', + default_options: [ 'warning_level=2', + ], +) + +cargo_sources = files( + 'Cargo.toml', + 'Cargo.lock', +) + +subdir('src') diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..2d616d4 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,84 @@ +fn main() -> Result<(), Box> { + for port in serialport::available_ports()? { + if let Ok(mut port) = perform_handshake(port) { + println!("Handshake success"); + if let Ok(ident) = get_prop(&mut port, b"ident") { + println!("ident success: {:?}", ident); + } + + if let Ok(name) = get_prop(&mut port, b"name") { + println!("name success: {}", String::from_utf8_lossy(&name)); + } + + if let Ok(author) = get_prop(&mut port, b"author") { + println!("author success: {}", String::from_utf8_lossy(&author)); + } + } + } + + Ok(()) +} + +fn get_prop( + port: &mut Box, + prop: &[u8], +) -> Result, Box> { + port.write_all(prop)?; + port.flush()?; + + let mut len_buf = [0u8; 1]; + port.read_exact(&mut len_buf)?; + let input_len = len_buf[0]; + println!("LEN: {}", input_len); + let mut input = vec![0u8; input_len as usize]; + port.read_exact(&mut input)?; + Ok(input) +} + +#[derive(Clone, Copy, Debug)] +struct HandshakeError; + +fn perform_handshake( + port: serialport::SerialPortInfo, +) -> Result, Box> { + use rand::Fill; + use std::io::{Read, Write}; + std::fs::metadata(&port.port_name)?; + + const INPUT_LEN: usize = 16; + + let mut output = [0u8; INPUT_LEN * 2]; + let mut input = [0u8; INPUT_LEN]; + + let mut port = serialport::new(&port.port_name, 9600) + .timeout(std::time::Duration::from_millis(500)) + .open()?; + + let mut rng = rand::thread_rng(); + output.try_fill(&mut rng)?; + port.write_all(&output)?; + port.flush()?; + port.read_exact(&mut input)?; + + for (index, byte) in input.iter().enumerate() { + if *byte != (output[index] ^ output[index + INPUT_LEN]) { + return Err(HandshakeError.into()); + } + + output[index] = *byte; + output[index + INPUT_LEN] = *byte; + } + + port.write_all(&output)?; + port.flush()?; + + Ok(port) +} + +impl std::fmt::Display for HandshakeError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "HandshakeError") + } +} + +impl std::error::Error for HandshakeError {} diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000..b54f5fa --- /dev/null +++ b/src/meson.build @@ -0,0 +1,25 @@ +rust_sources = files( + 'main.rs' +) + +sources = [cargo_sources, rust_sources] + +cargo_script = find_program(join_paths(meson.source_root(), 'build-aux/cargo.sh')) + +cargo_release = custom_target( + 'cargo-build', + build_by_default: true, + input: sources, + output: 'device-ls', + console: true, + install: true, + install_dir: get_option('bindir'), + command: [ + cargo_script, + meson.build_root(), + meson.source_root(), + '@OUTPUT@', + get_option('buildtype'), + 'device-ls', + ] +)