Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement LED source output device #246

Closed
wants to merge 23 commits into from
Closed
Changes from 6 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
cd3dbdd
feat(VSCode IDE): add debug button
NeroReflex Dec 28, 2024
57271e6
improv(manager): reorganize code and reduce dependency of UdevDevice:…
NeroReflex Dec 30, 2024
53edb30
feat(VSCode IDE): specify the language as being rust for remote debug…
NeroReflex Dec 30, 2024
005be00
improv(composite_device): better error reporting
NeroReflex Dec 30, 2024
48772bd
fix(udev::Device): bufix for number being u32 and code cleanup
NeroReflex Dec 30, 2024
7135d06
improv(udev::Device): don't use udevadm to inspect devices
NeroReflex Dec 30, 2024
bd6c100
manager: check for devnode() validity for device types that actually …
NeroReflex Dec 30, 2024
3e21daa
feat(config) implement LED configuration
NeroReflex Dec 30, 2024
006df63
feat(LED): LEDs initial implementation
NeroReflex Dec 31, 2024
0fc2c59
feat(LED): implement leds as a source output device
NeroReflex Dec 31, 2024
b6f0803
fix(manager): avoid cycling twice configurations
NeroReflex Dec 31, 2024
27f33ec
improv(CompositeDevice): make the code more readable
NeroReflex Dec 31, 2024
54db7ae
improv(main) do not lose the reference to the ctrl+C signal watcher
NeroReflex Dec 31, 2024
368cf3e
improv(LED): add configuration for the ASUS ROG Ally device
NeroReflex Dec 31, 2024
45d1cdf
improv(LED): increase code readability
NeroReflex Dec 31, 2024
45eb711
improv(code): cargo fmt
NeroReflex Dec 31, 2024
79a2bc6
fix(MultiColorChassis): solve a warning about an unused field
NeroReflex Dec 31, 2024
bbee9b3
improv(code): increase readability by replacing if let() with match
NeroReflex Dec 31, 2024
c65effe
fix(dbus) make dbus path parth of a CompositeDevice at construction
NeroReflex Dec 31, 2024
7d9f0cc
fix(manager): avoid borrowing syntax from typescript
NeroReflex Dec 31, 2024
0b79670
improv(code): cargo fmt
NeroReflex Dec 31, 2024
ac25809
fix(comments): apply suggestions from the PR feedback
NeroReflex Dec 31, 2024
00efbb9
fix(LED): fix inverted b and r components
NeroReflex Dec 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Remote launch",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/target/debug/inputplumber",
"sourceLanguages": ["rust"],
"initCommands": [
"platform select remote-linux",
"platform connect connect://192.168.1.19:1234",
"settings set target.inherit-env false"
],
"env": {
"PATH": "/usr/bin:/usr/local/sbin:/usr/local/bin:/var/lib/flatpak/exports/bin:/usr/lib/rustup/bin"
}
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in library 'inputplumber'",
"cargo": {
"args": [
"test",
"--no-run",
"--lib",
"--package=inputplumber"
],
"filter": {
"name": "inputplumber",
"kind": "lib"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'inputplumber'",
"cargo": {
"args": [
"build",
"--bin=inputplumber",
"--package=inputplumber"
],
"filter": {
"name": "inputplumber",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in executable 'inputplumber'",
"cargo": {
"args": [
"test",
"--no-run",
"--bin=inputplumber",
"--package=inputplumber"
],
"filter": {
"name": "inputplumber",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
}
]
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't commit editor-specific configurations

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't commit editor-specific configurations

This is not editor configuration as in "dev favourite color palette" this is what is needed to remote debug it. The PATH env var is important too as it specify where to find udevadm.

8 changes: 5 additions & 3 deletions src/dbus/interface/source/evdev.rs
Original file line number Diff line number Diff line change
@@ -19,9 +19,11 @@ pub struct SourceEventDeviceInterface {

impl SourceEventDeviceInterface {
pub fn new(device: UdevDevice) -> SourceEventDeviceInterface {
let handler = device.devnode();
let capabilities = get_capabilities(handler.as_str()).unwrap_or_else(|e| {
log::warn!("Failed to get capabilities for source evdev device '{handler}': {e:?}");
let capabilities = get_capabilities(device.devnode().as_str()).unwrap_or_else(|e| {
log::warn!(
"Failed to get capabilities for source evdev device '{}': {e:?}",
device.name()
);
HashMap::new()
});
SourceEventDeviceInterface {
17 changes: 15 additions & 2 deletions src/drivers/opineo/driver.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{
error::Error,
ffi::CString,
path::Path,
time::{Duration, Instant},
};

@@ -51,12 +52,24 @@ pub struct Driver {
impl Driver {
pub fn new(udevice: UdevDevice) -> Result<Self, Box<dyn Error + Send + Sync>> {
let path = udevice.devnode();
let cs_path = CString::new(path.clone())?;
if !Path::new(path.as_str()).exists() {
return Err(format!(
"Device '{}' does not have a devnode: a valid OrangePi NEO Controller has one",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The phrasing of this is a little strange. "Failed to find device node for {}, aborting initialization." Or something closer to that effect would be better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want the message to include the fact it's coming from an opi device... Can you give me a phrase that includes that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Failed to find device node for {}, aborting initialization as OrangePi NEO Controller."

udevice.name()
)
.into());
}

let cs_path = CString::new(path)?;
let api = hidapi::HidApi::new()?;
let device = api.open_path(&cs_path)?;
let info = device.get_device_info()?;
if info.vendor_id() != VID || info.product_id() != PID {
return Err(format!("Device '{path}' is not a OrangePi NEO Controller").into());
return Err(format!(
"Device '{}' is not a OrangePi NEO Controller",
udevice.name()
)
.into());
}

Ok(Self {
13 changes: 11 additions & 2 deletions src/drivers/rog_ally/driver.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{error::Error, ffi::OsStr, time::Duration};
use std::{error::Error, ffi::OsStr, path::Path, time::Duration};

use udev::Device;

@@ -19,8 +19,17 @@ impl Driver {
let vid = udevice.id_vendor();
let pid = udevice.id_product();
if VID != vid || !PIDS.contains(&pid) {
return Err(format!("'{}' is not an ROG Ally controller", udevice.devnode()).into());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R starts with a vowel sound, "an ROG" is correct here.

return Err(format!("Device {} is not a ROG Ally controller", udevice.name()).into());
}

if !Path::new(udevice.devnode().as_str()).exists() {
return Err(format!(
"Device {}, part of a ROG Ally controller does not have a devnode",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use wording to similar to comment in orange pi

udevice.name()
)
.into());
}

// TODO: When resuming from sleep, if mcu_powersave is set, the device init takes longer.
// inotify will trigger this driver before the attribute tree is fully built and the driver
// will error and exit, leaving some controls unusable. We should find a way to only
22 changes: 17 additions & 5 deletions src/drivers/xpad_uhid/driver.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{error::Error, ffi::CString};
use std::{error::Error, ffi::CString, path::Path};

use hidapi::HidDevice;
use packed_struct::PackedStruct;
@@ -47,17 +47,29 @@ pub struct Driver {

impl Driver {
pub fn new(udevice: UdevDevice) -> Result<Self, Box<dyn Error + Send + Sync>> {
let path = udevice.devnode();
let driver = udevice.drivers();
if !driver.contains(&"microsoft".to_string()) {
return Err(format!("Device '{path}' is not using the hid-microsoft driver").into());
return Err(format!(
"Device '{}' is not using the hid-microsoft driver",
udevice.name()
)
.into());
}

if !Path::new(udevice.devnode().as_str()).exists() {
return Err(format!(
"Device {} an xpad controller does not have a devnode",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as previous

udevice.name()
)
.into());
}

let syspath = udevice.syspath();
if !syspath.contains("uhid") {
return Err(format!("Device '{path}' is not a uhid virtual device").into());
return Err(format!("Device '{}' is not a uhid virtual device", udevice.name()).into());
}

let cs_path = CString::new(path.clone())?;
let cs_path = CString::new(udevice.devnode().clone())?;
let api = hidapi::HidApi::new()?;
let device = api.open_path(&cs_path)?;

Loading