updates
This commit is contained in:
parent
d70a8c6e56
commit
d7d6b3ab93
@ -1,11 +1,14 @@
|
|||||||
// client/src/app.rs
|
// client/src/app.rs
|
||||||
|
#![forbid(unsafe_code)]
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use futures::{FutureExt, StreamExt};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::{sync::mpsc, sync::broadcast, task::JoinHandle};
|
use tokio::{sync::mpsc, sync::broadcast, task::JoinHandle};
|
||||||
|
use tokio_stream::StreamExt as _;
|
||||||
use tokio_stream::wrappers::{ReceiverStream, BroadcastStream};
|
use tokio_stream::wrappers::{ReceiverStream, BroadcastStream};
|
||||||
use tonic::Request;
|
use tonic::Request;
|
||||||
use tracing::{info, warn, error};
|
use tracing::{info, warn, error};
|
||||||
|
|
||||||
use navka_common::navka::{relay_client::RelayClient, HidReport};
|
use navka_common::navka::{relay_client::RelayClient, HidReport};
|
||||||
use crate::input::inputs::InputAggregator;
|
use crate::input::inputs::InputAggregator;
|
||||||
|
|
||||||
@ -13,6 +16,7 @@ pub struct NavkaClientApp {
|
|||||||
aggregator: Option<InputAggregator>,
|
aggregator: Option<InputAggregator>,
|
||||||
server_addr: String,
|
server_addr: String,
|
||||||
dev_mode: bool,
|
dev_mode: bool,
|
||||||
|
tx: broadcast::Sender<HidReport>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NavkaClientApp {
|
impl NavkaClientApp {
|
||||||
@ -22,14 +26,16 @@ impl NavkaClientApp {
|
|||||||
.nth(1)
|
.nth(1)
|
||||||
.or_else(|| std::env::var("NAVKA_SERVER_ADDR").ok())
|
.or_else(|| std::env::var("NAVKA_SERVER_ADDR").ok())
|
||||||
.unwrap_or_else(|| "http://127.0.0.1:50051".to_owned());
|
.unwrap_or_else(|| "http://127.0.0.1:50051".to_owned());
|
||||||
let (tx, _rx) = mpsc::channel::<HidReport>(64);
|
|
||||||
let mut aggregator = InputAggregator::new(dev_mode, tx);
|
let (tx, _) = broadcast::channel::<HidReport>(128);
|
||||||
|
let mut aggregator = InputAggregator::new(dev_mode, tx.clone());
|
||||||
aggregator.init()?; // discover & grab
|
aggregator.init()?; // discover & grab
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
aggregator: Some(aggregator),
|
aggregator: Some(aggregator),
|
||||||
server_addr: addr,
|
server_addr: addr,
|
||||||
dev_mode,
|
dev_mode,
|
||||||
|
tx,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +50,7 @@ impl NavkaClientApp {
|
|||||||
let suicide_future = async {
|
let suicide_future = async {
|
||||||
if self.dev_mode {
|
if self.dev_mode {
|
||||||
info!("DEV-mode: will kill itself in 30s");
|
info!("DEV-mode: will kill itself in 30s");
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(30)).await;
|
tokio::time::sleep(Duration::from_secs(30)).await;
|
||||||
Err::<(), _>(anyhow::anyhow!("dev-mode timer expired - goodbye cruel world..."))
|
Err::<(), _>(anyhow::anyhow!("dev-mode timer expired - goodbye cruel world..."))
|
||||||
} else {
|
} else {
|
||||||
futures::future::pending().await
|
futures::future::pending().await
|
||||||
@ -77,7 +83,7 @@ impl NavkaClientApp {
|
|||||||
},
|
},
|
||||||
// reconnect loop
|
// reconnect loop
|
||||||
_ = self.reconnect_loop() => {
|
_ = self.reconnect_loop() => {
|
||||||
warn!("Reconnect loop ended?? We exit");
|
warn!("Reconnect loop ended??");
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,11 +104,8 @@ impl NavkaClientApp {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// fresh channel for aggregator => we do this with new (tx, rx)
|
// fresh reader over the *same* broadcast channel
|
||||||
let (tx, rx) = mpsc::channel::<HidReport>(64);
|
let outbound = BroadcastStream::new(self.tx.subscribe()).filter_map(|r| async { r.ok() });
|
||||||
let _unused = InputAggregator::new(self.dev_mode, tx.clone()); // TODO: wire this up properly
|
|
||||||
|
|
||||||
let outbound = ReceiverStream::new(rx);
|
|
||||||
let response = match client.stream(Request::new(outbound)).await {
|
let response = match client.stream(Request::new(outbound)).await {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -113,7 +116,6 @@ impl NavkaClientApp {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut inbound = response.into_inner();
|
let mut inbound = response.into_inner();
|
||||||
// read inbound
|
|
||||||
while let Some(res) = inbound.message().await.transpose() {
|
while let Some(res) = inbound.message().await.transpose() {
|
||||||
match res {
|
match res {
|
||||||
Ok(report) => {
|
Ok(report) => {
|
||||||
@ -125,7 +127,7 @@ impl NavkaClientApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
warn!("Inbound ended. Will try to reconnect in 1s");
|
warn!("Diconnected. Inbound ended. Will try to reconnect in 1s");
|
||||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use evdev::{Device, EventType, KeyCode, RelativeAxisCode};
|
use evdev::{Device, EventType, KeyCode, RelativeAxisCode};
|
||||||
use tokio::time::{interval, Duration};
|
use tokio::time::{interval, Duration};
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::broadcast::Sender;
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
|
|
||||||
use navka_common::navka::HidReport;
|
use navka_common::navka::HidReport;
|
||||||
|
|||||||
@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use evdev::{Device, InputEvent, KeyCode, EventType};
|
use evdev::{Device, InputEvent, KeyCode, EventType};
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::broadcast::Sender;
|
||||||
use tracing::{warn, error, info, debug};
|
use tracing::{warn, error, info, debug};
|
||||||
|
|
||||||
use navka_common::navka::HidReport;
|
use navka_common::navka::HidReport;
|
||||||
|
|
||||||
use crate::input::keymap::{keycode_to_usage, is_modifier};
|
use crate::input::keymap::{keycode_to_usage, is_modifier};
|
||||||
@ -108,10 +109,8 @@ impl KeyboardAggregator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn send_report(&self, report: [u8; 8]) {
|
fn send_report(&self, report: [u8; 8]) {
|
||||||
let _ = self.tx.try_send(HidReport {
|
let _ = self.tx.send(HidReport {
|
||||||
kind: Some(navka_common::navka::hid_report::Kind::KeyboardReport(
|
kind: Some(hid_report::Kind::KeyboardReport(report.to_vec())),
|
||||||
report.to_vec(),
|
|
||||||
)),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// client/src/input/mouse.rs
|
// client/src/input/mouse.rs
|
||||||
|
|
||||||
use evdev::{Device, InputEvent, EventType, KeyCode, RelativeAxisCode};
|
use evdev::{Device, InputEvent, EventType, KeyCode, RelativeAxisCode};
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::broadcast::Sender;
|
||||||
use tracing::{error, debug};
|
use tracing::{error, debug};
|
||||||
use navka_common::navka::HidReport;
|
use navka_common::navka::HidReport;
|
||||||
|
|
||||||
@ -55,13 +55,20 @@ impl MouseAggregator {
|
|||||||
|
|
||||||
fn handle_event(&mut self, ev: InputEvent) {
|
fn handle_event(&mut self, ev: InputEvent) {
|
||||||
match ev.event_type() {
|
match ev.event_type() {
|
||||||
EventType::RELATIVE => { /* fill dx/dy/wheel as i8 */ }
|
EventType::RELATIVE => {
|
||||||
EventType::KEY => { // buttons are REPORTED as KEYS (BTN_LEFT…)
|
match RelativeAxisCode::new(ev.code()) {
|
||||||
|
RelativeAxisCode::REL_X => self.dx = ev.value() as i8,
|
||||||
|
RelativeAxisCode::REL_Y => self.dy = ev.value() as i8,
|
||||||
|
RelativeAxisCode::REL_WHEEL => self.wheel = ev.value() as i8,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EventType::KEY => {
|
||||||
let pressed = ev.value() != 0;
|
let pressed = ev.value() != 0;
|
||||||
match ev.code() {
|
match ev.code() {
|
||||||
c if c == KeyCode::BTN_LEFT.0 => self.set_btn(0, pressed),
|
c if c == KeyCode::BTN_LEFT.0 => self.set_btn(0, pressed),
|
||||||
c if c == KeyCode::BTN_RIGHT.0 => self.set_btn(1, pressed),
|
c if c == KeyCode::BTN_RIGHT.0 => self.set_btn(1, pressed),
|
||||||
c if c == KeyCode::BTN_MIDDLE.0=> self.set_btn(2, pressed),
|
c if c == KeyCode::BTN_MIDDLE.0 => self.set_btn(2, pressed),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,11 +77,14 @@ impl MouseAggregator {
|
|||||||
|
|
||||||
// whenever we changed something, emit:
|
// whenever we changed something, emit:
|
||||||
let rep = [self.buttons, self.dx as u8, self.dy as u8, self.wheel as u8];
|
let rep = [self.buttons, self.dx as u8, self.dy as u8, self.wheel as u8];
|
||||||
let _ = self.tx.try_send(HidReport {
|
let _ = self.tx.send(HidReport {
|
||||||
kind: Some(navka_common::navka::hid_report::Kind::MouseReport(rep.to_vec())),
|
kind: Some(hid_report::Kind::MouseReport(rep.to_vec())),
|
||||||
});
|
});
|
||||||
|
|
||||||
// reset deltas so we send *relative* movement
|
// reset deltas so we send *relative* movement
|
||||||
self.dx = 0; self.dy = 0; self.wheel = 0;
|
self.dx = 0;
|
||||||
|
self.dy = 0;
|
||||||
|
self.wheel = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,21 +37,26 @@ echo "$(cat /proc/sys/kernel/random/uuid)" >"$G/strings/0x409/serialnumber"
|
|||||||
echo "Navka" >"$G/strings/0x409/manufacturer"
|
echo "Navka" >"$G/strings/0x409/manufacturer"
|
||||||
echo "Navka Composite" >"$G/strings/0x409/product"
|
echo "Navka Composite" >"$G/strings/0x409/product"
|
||||||
|
|
||||||
# HID (boot keyboard)
|
# ----------------------- HID keyboard (usb0) -----------------------
|
||||||
mkdir -p "$G/functions/hid.usb0"
|
mkdir -p "$G/functions/hid.usb0"
|
||||||
echo 1 >"$G/functions/hid.usb0/protocol"
|
echo 1 >"$G/functions/hid.usb0/protocol"
|
||||||
echo 1 >"$G/functions/hid.usb0/subclass"
|
echo 1 >"$G/functions/hid.usb0/subclass"
|
||||||
echo 8 >"$G/functions/hid.usb0/report_length"
|
echo 8 >"$G/functions/hid.usb0/report_length"
|
||||||
printf '\x05\x01\x09\x06\xa1\x01\x05\x07\x19\xe0\x29\xe7\x15\x00\x25\x01\x75\x01\x95\x08\x81\x02\x95\x01\x75\x08\x81\x01\x95\x05\x75\x01\x05\x08\x19\x01\x29\x05\x91\x02\x95\x01\x75\x03\x91\x01\x95\x06\x75\x08\x15\x00\x25\x65\x05\x07\x19\x00\x29\x65\x81\x00\xc0' \
|
printf '\x05\x01\x09\x06\xa1\x01\x05\x07\x19\xe0\x29\xe7\x15\x00\x25\x01'\
|
||||||
> "$G/functions/hid.usb0/report_desc"
|
'\x75\x01\x95\x08\x81\x02\x95\x01\x75\x08\x81\x01\x95\x05\x75\x01\x05'\
|
||||||
|
'\x08\x19\x01\x29\x05\x91\x02\x95\x01\x75\x03\x91\x01\x95\x06\x75\x08'\
|
||||||
|
'\x15\x00\x25\x65\x05\x07\x19\x00\x29\x65\x81\x00\xc0' \
|
||||||
|
>"$G/functions/hid.usb0/report_desc"
|
||||||
|
|
||||||
# usb1 = mouse
|
# ----------------------- HID mouse (usb1) --------------------------
|
||||||
mkdir -p "$G/functions/hid.usb1"
|
mkdir -p "$G/functions/hid.usb1"
|
||||||
echo 2 > "$G/functions/hid.usb1/protocol"
|
echo 2 > "$G/functions/hid.usb1/protocol"
|
||||||
echo 1 > "$G/functions/hid.usb1/subclass"
|
echo 1 > "$G/functions/hid.usb1/subclass"
|
||||||
echo 4 > "$G/functions/hid.usb1/report_length"
|
echo 4 > "$G/functions/hid.usb1/report_length"
|
||||||
printf '\x05\x01\x09\x06\xa1\x01\x05\x07\x19\xe0\x29\xe7\x15\x00\x25\x01\x75\x01\x95\x08\x81\x02\x95\x01\x75\x08\x81\x01\x95\x05\x75\x01\x05\x08\x19\x01\x29\x05\x91\x02\x95\x01\x75\x03\x91\x01\x95\x06\x75\x08\x15\x00\x25\x65\x05\x07\x19\x00\x29\x65\x81\x00\xc0' \
|
printf '\x05\x01\x09\x02\xa1\x01\x09\x01\xa1\x00\x05\x09\x19\x01\x29\x03'\
|
||||||
> "$G/functions/hid.usb1/report_desc"
|
'\x15\x00\x25\x01\x95\x03\x75\x01\x81\x02\x95\x01\x75\x05\x81\x03\x05'\
|
||||||
|
'\x01\x09\x30\x09\x31\x15\x81\x25\x7f\x75\x08\x95\x02\x81\x06\xc0\xc0' \
|
||||||
|
>"$G/functions/hid.usb1/report_desc"
|
||||||
|
|
||||||
# # -- UAC2 Audio
|
# # -- UAC2 Audio
|
||||||
# mkdir -p $G/functions/uac2.usb0
|
# mkdir -p $G/functions/uac2.usb0
|
||||||
@ -59,15 +64,16 @@ printf '\x05\x01\x09\x06\xa1\x01\x05\x07\x19\xe0\x29\xe7\x15\x00\x25\x01\x75\x01
|
|||||||
# echo 2 > $G/functions/uac2.usb0/c_ssize
|
# echo 2 > $G/functions/uac2.usb0/c_ssize
|
||||||
# echo 2 > $G/functions/uac2.usb0/p_chmask
|
# echo 2 > $G/functions/uac2.usb0/p_chmask
|
||||||
|
|
||||||
# -- Config
|
# ----------------------- configuration -----------------------------
|
||||||
mkdir -p "$G/configs/c.1/strings/0x409"
|
mkdir -p "$G/configs/c.1/strings/0x409"
|
||||||
echo 500 > "$G/configs/c.1/MaxPower"
|
echo 500 > "$G/configs/c.1/MaxPower"
|
||||||
echo "Config 1" > "$G/configs/c.1/strings/0x409/configuration"
|
echo "Config 1" > "$G/configs/c.1/strings/0x409/configuration"
|
||||||
|
|
||||||
# -- Bindings
|
# 6) Finally bind to first available UDC
|
||||||
ln -s $G/functions/hid.usb0 $G/configs/c.1/
|
ln -s $G/functions/hid.usb0 $G/configs/c.1/
|
||||||
|
ln -s $G/functions/hid.usb1 $G/configs/c.1/
|
||||||
# ln -s $G/functions/uac2.usb0 $G/configs/c.1/
|
# ln -s $G/functions/uac2.usb0 $G/configs/c.1/
|
||||||
|
|
||||||
# 6) Finally bind to first available UDC
|
# 7) Finally bind to first available UDC
|
||||||
echo $(ls /sys/class/udc | head -n1) > $G/UDC
|
echo $(ls /sys/class/udc | head -n1) > $G/UDC
|
||||||
echo "[navka-core] gadget ready on USB-C port"
|
echo "[navka-core] gadget ready (keyboard on hidg0, mouse on hidg1)"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user