Try to ensure all aura are detected at start

This commit is contained in:
Luke D. Jones
2024-03-22 17:35:59 +13:00
parent 9119229d41
commit be05508110
10 changed files with 259 additions and 237 deletions

View File

@@ -116,7 +116,7 @@ pub struct AuraConfig {
impl AuraConfig {
/// Detect the keyboard type and load from default DB if data available
pub fn new_with(prod_id: AuraDevice) -> Self {
info!("creating new AuraConfig");
info!("Setting up AuraConfig for {prod_id:?}");
Self::from_default_support(prod_id, &LaptopLedData::get_data())
}
}

View File

@@ -2,9 +2,9 @@ use std::collections::BTreeMap;
use config_traits::{StdConfig, StdConfigLoad};
use inotify::Inotify;
use log::info;
use log::{info, warn};
use rog_aura::advanced::{LedUsbPackets, UsbPackets};
use rog_aura::aura_detection::{LaptopLedData, ASUS_KEYBOARD_DEVICES};
use rog_aura::aura_detection::LaptopLedData;
use rog_aura::usb::{AuraDevice, LED_APPLY, LED_SET};
use rog_aura::{AuraEffect, Direction, LedBrightness, Speed, GRADIENT, LED_MSG_LEN};
use rog_platform::hid_raw::HidRaw;
@@ -59,71 +59,61 @@ pub struct CtrlKbdLed {
}
impl CtrlKbdLed {
pub fn new(data: LaptopLedData) -> Result<Self, RogError> {
let mut led_prod = AuraDevice::Unknown;
let mut usb_node = None;
for prod in ASUS_KEYBOARD_DEVICES {
match HidRaw::new(prod.into()) {
Ok(node) => {
led_prod = prod;
usb_node = Some(node);
info!(
"Looked for keyboard controller 0x{}: Found",
<&str>::from(prod)
);
break;
pub fn find_all(data: &LaptopLedData) -> Result<Vec<Self>, RogError> {
let mut devices = Vec::new();
let mut enumerator = udev::Enumerator::new().map_err(|err| {
warn!("{}", err);
err
})?;
enumerator.match_subsystem("hidraw").map_err(|err| {
warn!("{}", err);
err
})?;
for end_point in enumerator.scan_devices()? {
if let Some(usb_device) =
end_point.parent_with_subsystem_devtype("usb", "usb_device")?
{
// Device is something like 002, while its parent is the MCU
// Think of it like the device is an endpoint of the USB device attached
if let Some(parent_id) = usb_device.attribute_value("idProduct") {
let prod_id = AuraDevice::from(parent_id.to_str().unwrap());
if prod_id == AuraDevice::Unknown {
log::debug!("Unknown or invalid device: {parent_id:?}, skipping");
continue;
}
}
Err(err) => info!(
"Looked for keyboard controller 0x{}: {err}",
<&str>::from(prod)
),
let dbus_path = dbus_path_for_dev(&usb_device).unwrap_or_default();
let dev = HidRaw::from_device(end_point)?;
let dev = Self::from_hidraw(dev, dbus_path, data)?;
devices.push(dev);
}
}
let mut dbus_path = Default::default();
let rgb_led = KeyboardLed::new()?;
let led_node = if let Some(rog) = usb_node {
info!("Found ROG USB keyboard");
dbus_path = dbus_path_for_dev(rog.1).unwrap_or_default();
LEDNode::Rog(rgb_led, rog.0)
} else if rgb_led.has_kbd_rgb_mode() {
info!("Found TUF keyboard");
LEDNode::KbdLed(rgb_led.clone())
} else {
return Err(RogError::NoAuraKeyboard);
// LEDNode::None
};
// New loads data from the DB also
let config = Self::init_config(led_prod, &data);
let ctrl = CtrlKbdLed {
led_prod,
led_node, // on TUF this is the same as rgb_led / kd_brightness
supported_data: data,
per_key_mode_active: false,
config,
dbus_path,
};
Ok(ctrl)
Ok(devices)
}
pub fn from_device(
pub fn from_hidraw(
device: HidRaw,
dbus_path: OwnedObjectPath,
data: LaptopLedData,
data: &LaptopLedData,
) -> Result<Self, RogError> {
let rgb_led = KeyboardLed::new()?;
let prod_id = AuraDevice::from(device.prod_id());
if prod_id == AuraDevice::Unknown {
log::error!("{} is AuraDevice::Unknown", device.prod_id());
return Err(RogError::NoAuraNode);
}
// New loads data from the DB also
let config = Self::init_config(prod_id, &data);
let config = Self::init_config(prod_id, data);
let ctrl = CtrlKbdLed {
led_prod: prod_id,
led_node: LEDNode::Rog(rgb_led, device), /* on TUF this is the same as rgb_led /
* kd_brightness */
supported_data: data,
led_node: LEDNode::Rog(rgb_led, device),
supported_data: data.clone(),
per_key_mode_active: false,
config,
dbus_path,
@@ -348,7 +338,7 @@ mod tests {
};
let mut controller = CtrlKbdLed {
led_prod: AuraDevice::X19b6,
led_node: LEDNode::Rog(KeyboardLed::default(), HidRaw::new("id_product").unwrap()),
led_node: LEDNode::Rog(KeyboardLed::default(), HidRaw::new("id_product").unwrap().0),
supported_data: supported_basic_modes,
per_key_mode_active: false,
config,
@@ -386,7 +376,7 @@ mod tests {
};
let mut controller = CtrlKbdLed {
led_prod: AuraDevice::X19b6,
led_node: LEDNode::Rog(KeyboardLed::default(), HidRaw::new("id_product").unwrap()),
led_node: LEDNode::Rog(KeyboardLed::default(), HidRaw::new("id_product").unwrap().0),
supported_data: supported_basic_modes,
per_key_mode_active: false,
config,

View File

@@ -4,7 +4,7 @@
// - Add it to Zbus server
// - If udev sees device removed then remove the zbus path
use std::collections::HashSet;
use std::collections::HashMap;
use std::sync::Arc;
use log::{error, info, warn};
@@ -26,7 +26,7 @@ use crate::{CtrlTask, Reloadable};
pub struct AuraManager {
_connection: Connection,
_interfaces: Arc<Mutex<HashSet<OwnedObjectPath>>>,
interfaces: Arc<Mutex<HashMap<String, OwnedObjectPath>>>,
}
impl AuraManager {
@@ -35,17 +35,13 @@ impl AuraManager {
let data = LaptopLedData::get_data();
// Do the initial keyboard detection:
match CtrlKbdLed::new(data.clone()) {
Ok(ctrl) => {
let path = ctrl.dbus_path.clone();
let sig_ctx = CtrlAuraZbus::signal_context(&connection)?;
let sig_ctx2 = sig_ctx.clone();
let zbus = CtrlAuraZbus::new(ctrl, sig_ctx);
start_tasks(zbus, &mut connection, sig_ctx2, &path).await?;
}
Err(err) => {
error!("Keyboard control: {}", err);
}
let all = CtrlKbdLed::find_all(&data)?;
for ctrl in all {
let path = ctrl.dbus_path.clone();
let sig_ctx = CtrlAuraZbus::signal_context(&connection)?;
let sig_ctx2 = sig_ctx.clone();
let zbus = CtrlAuraZbus::new(ctrl, sig_ctx);
start_tasks(zbus, &mut connection, sig_ctx2, &path).await?;
}
// connection.object_server().at("/org/asuslinux",
@@ -53,9 +49,10 @@ impl AuraManager {
let manager = Self {
_connection: connection,
_interfaces: Default::default(),
interfaces: Default::default(),
};
let interfaces_copy = manager.interfaces.clone();
// detect all plugged in aura devices (eventually)
tokio::spawn(async move {
let mut monitor = MonitorBuilder::new()?.match_subsystem("hidraw")?.listen()?;
@@ -77,19 +74,24 @@ impl AuraManager {
};
if action == "remove" {
if let Some(path) = dbus_path_for_dev(parent.clone()) {
info!("AuraManager removing: {path:?}");
if let Some(id_product) = parent.attribute_value("idProduct") {
let id_product = id_product.to_string_lossy().to_string();
let interfaces_copy = interfaces_copy.clone();
let conn_copy = conn_copy.clone();
tokio::spawn(async move {
let res = conn_copy
.object_server()
.remove::<CtrlAuraZbus, _>(&path)
.await
.map_err(|e| {
error!("Failed to remove {path:?}, {e:?}");
e
})?;
info!("AuraManager removed: {path:?}, {res}");
let mut interfaces = interfaces_copy.lock().await;
if let Some(path) = interfaces.remove(&id_product) {
info!("AuraManager removing: {path:?}");
let res = conn_copy
.object_server()
.remove::<CtrlAuraZbus, _>(&path)
.await
.map_err(|e| {
error!("Failed to remove {path:?}, {e:?}");
e
})?;
info!("AuraManager removed: {path:?}, {res}");
}
Ok::<(), RogError>(())
});
}
@@ -97,7 +99,7 @@ impl AuraManager {
let id_product =
if let Some(id_product) = parent.attribute_value("idProduct") {
id_product
id_product.to_string_lossy().to_string()
} else {
continue;
};
@@ -113,7 +115,7 @@ impl AuraManager {
}
// try conversion to known idProduct
let aura_device = AuraDevice::from(id_product.to_str().unwrap());
let aura_device = AuraDevice::from(id_product.as_str());
if aura_device != AuraDevice::Unknown {
if action == "add" {
let dev_node = if let Some(dev_node) = event.devnode() {
@@ -125,18 +127,21 @@ impl AuraManager {
if let Ok(raw) = HidRaw::from_device(event.device())
.map_err(|e| error!("device path error: {e:?}"))
{
let path = if let Some(path) = dbus_path_for_dev(parent) {
let path = if let Some(path) = dbus_path_for_dev(&parent) {
path
} else {
continue;
};
if let Ok(ctrl) =
CtrlKbdLed::from_device(raw, path.clone(), data.clone())
CtrlKbdLed::from_hidraw(raw, path.clone(), &data)
{
info!("AuraManager found device at: {:?}", dev_node);
let mut conn_copy = conn_copy.clone();
let interfaces_copy = interfaces_copy.clone();
//
tokio::spawn(async move {
let mut interfaces = interfaces_copy.lock().await;
interfaces.insert(id_product, path.clone());
let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?;
let zbus = CtrlAuraZbus::new(ctrl, sig_ctx);
// Now add it to device list
@@ -163,7 +168,7 @@ impl AuraManager {
}
}
pub(crate) fn dbus_path_for_dev(parent: Device) -> Option<OwnedObjectPath> {
pub(crate) fn dbus_path_for_dev(parent: &Device) -> Option<OwnedObjectPath> {
if let Some(id_product) = parent.attribute_value("idProduct") {
let id_product = id_product.to_string_lossy();
let path = if let Some(devnum) = parent.attribute_value("devnum") {