working with hardcoded devnode. need to change

This commit is contained in:
Luke D Jones
2020-08-02 21:38:48 +12:00
parent a879907bc3
commit d757a936e8
6 changed files with 44 additions and 186 deletions

View File

@@ -119,6 +119,7 @@ Models GA401, GA502, GU502 support LED brightness change only (no RGB).
- `libdbus-1-dev`
- `llvm`
- `libclang-dev`
- `libudev-dev`
## Installing

View File

@@ -23,6 +23,12 @@ pub mod anime_matrix;
pub mod error;
// static LED_INIT1: [u8; 2] = [0x5d, 0xb9];
// static LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
// static LED_INIT3: [u8; 6] = [0x5d, 0x05, 0x20, 0x31, 0, 0x08];
// static LED_INIT4: &str = "^ASUS Tech.Inc."; // ^ == 0x5e
// static LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08];
/// Writes aout the correct byte string for brightness
///
/// The HID descriptor looks like:

View File

@@ -34,21 +34,7 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
info!("Config loaded");
let mut rogcore = RogCore::new(
laptop.usb_vendor(),
laptop.usb_product(),
laptop.key_endpoint(),
)
.map_or_else(
|err| {
error!("{}", err);
panic!("{}", err);
},
|daemon| {
info!("RogCore loaded");
daemon
},
);
let mut rogcore = RogCore::new(laptop.usb_vendor(), laptop.usb_product());
// Reload settings
rogcore
@@ -59,8 +45,7 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
.unwrap_or_else(|err| warn!("Battery charge limit: {}", err));
let mut led_writer = LedWriter::new(
rogcore.get_raw_device_handle(),
laptop.led_endpoint(),
"/dev/hidraw2".to_string(),
laptop.supported_modes().to_owned(),
);
@@ -136,6 +121,7 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
// spawning this in a function causes a segfault for reasons I haven't investigated yet
tokio::spawn(async move {
loop {
// TODO: MAKE SYS COMMANDS OPERATE USING CHANNEL LIKE AURA MODES
// Fan mode
if let Ok(mut lock) = fan_mode.try_lock() {
if let Some(n) = lock.take() {
@@ -154,7 +140,7 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
.unwrap_or_else(|err| warn!("{:?}", err));
}
}
std::thread::sleep(std::time::Duration::from_millis(500));
}
});
@@ -262,4 +248,3 @@ async fn send_boot_signals(
.unwrap_or_else(|_| 0);
Ok(())
}

View File

@@ -1,10 +1,8 @@
use rog_client::{
aura_modes::{
AuraModes, BREATHING, COMET, FLASH, HIGHLIGHT, LASER, MULTISTATIC, PULSE, RAIN, RAINBOW,
RGB, RIPPLE, SINGLE, STAR, STROBE,
},
};
use log::{info, warn};
use rog_client::aura_modes::{
AuraModes, BREATHING, COMET, FLASH, HIGHLIGHT, LASER, MULTISTATIC, PULSE, RAIN, RAINBOW, RGB,
RIPPLE, SINGLE, STAR, STROBE,
};
static HELP_ADDRESS: &str = "https://github.com/flukejones/rog-core";
@@ -21,8 +19,6 @@ pub(crate) fn match_laptop() -> LaptopBase {
usb_product: 0x1854,
//from `lsusb -vd 0b05:1866`
led_endpoint: 0x04,
//from `lsusb -vd 0b05:1866`
key_endpoint: 0x83,
supported_modes: vec![SINGLE, BREATHING, STROBE],
support_animatrix: false,
};
@@ -47,8 +43,6 @@ fn select_1866_device(prod: u16) -> LaptopBase {
usb_product: prod,
//from `lsusb -vd 0b05:1866`
led_endpoint: 0x04,
//from `lsusb -vd 0b05:1866`
key_endpoint: 0x83,
supported_modes: vec![],
support_animatrix: false,
};
@@ -72,12 +66,22 @@ fn select_1866_device(prod: u16) -> LaptopBase {
SINGLE, BREATHING, STROBE, RAINBOW, STAR, RAIN, HIGHLIGHT, LASER, RIPPLE, PULSE, COMET,
FLASH, RGB,
];
} else if board_name.starts_with("G531")
|| board_name.starts_with("G731")
{
} else if board_name.starts_with("G531") || board_name.starts_with("G731") {
laptop.supported_modes = vec![
SINGLE, BREATHING, STROBE, RAINBOW, STAR, RAIN, HIGHLIGHT, LASER, RIPPLE, PULSE, COMET,
FLASH, MULTISTATIC, RGB,
SINGLE,
BREATHING,
STROBE,
RAINBOW,
STAR,
RAIN,
HIGHLIGHT,
LASER,
RIPPLE,
PULSE,
COMET,
FLASH,
MULTISTATIC,
RGB,
];
// RGB, limited effects, no zones
} else if board_name.starts_with("G512LI") || board_name.starts_with("G712LI") {
@@ -116,7 +120,6 @@ pub(super) struct LaptopBase {
usb_vendor: u16,
usb_product: u16,
led_endpoint: u8,
key_endpoint: u8,
supported_modes: Vec<u8>,
support_animatrix: bool,
}
@@ -125,9 +128,6 @@ impl LaptopBase {
pub(super) fn led_endpoint(&self) -> u8 {
self.led_endpoint
}
pub(super) fn key_endpoint(&self) -> u8 {
self.key_endpoint
}
pub(super) fn usb_vendor(&self) -> u16 {
self.usb_vendor
}

View File

@@ -1,9 +1,3 @@
static LED_INIT1: [u8; 2] = [0x5d, 0xb9];
static LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
static LED_INIT3: [u8; 6] = [0x5d, 0x05, 0x20, 0x31, 0, 0x08];
static LED_INIT4: &str = "^ASUS Tech.Inc."; // ^ == 0x5e
static LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08];
// Only these two packets must be 17 bytes
static LED_APPLY: [u8; 17] = [0x5d, 0xb4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
static LED_SET: [u8; 17] = [0x5d, 0xb5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
@@ -13,104 +7,46 @@ use log::{error, info, warn};
use rog_client::{
aura_brightness_bytes, aura_modes::AuraModes, fancy::KeyColourArray, LED_MSG_LEN,
};
use rusb::DeviceHandle;
use std::marker::PhantomData;
use std::ptr::NonNull;
use std::time::Duration;
use std::fs::OpenOptions;
use std::io::Write;
/// UNSAFE: Must live as long as RogCore
///
/// Because we're holding a pointer to something that *may* go out of scope while the
/// pointer is held. We're relying on access to struct to be behind a Mutex, and for behaviour
/// that may cause invalididated pointer to cause the program to panic rather than continue.
pub struct LedWriter<'d, C: 'd>
where
C: rusb::UsbContext,
{
handle: NonNull<DeviceHandle<C>>,
pub struct LedWriter {
dev_node: String,
supported_modes: Vec<u8>,
led_endpoint: u8,
initialised: bool,
flip_effect_write: bool,
_phantom: PhantomData<&'d DeviceHandle<C>>,
}
/// UNSAFE
unsafe impl<'d, C> Send for LedWriter<'d, C> where C: rusb::UsbContext {}
unsafe impl<'d, C> Sync for LedWriter<'d, C> where C: rusb::UsbContext {}
impl<'d, C> LedWriter<'d, C>
where
C: rusb::UsbContext,
{
impl LedWriter {
#[inline]
pub fn new(
device_handle: NonNull<DeviceHandle<C>>,
led_endpoint: u8,
supported_modes: Vec<u8>,
) -> Self {
pub fn new(dev_node: String, supported_modes: Vec<u8>) -> Self {
LedWriter {
handle: device_handle,
led_endpoint,
dev_node,
supported_modes,
initialised: false,
flip_effect_write: false,
_phantom: PhantomData,
}
}
async fn initialise(&mut self) -> Result<(), RogError> {
if !self.initialised {
self.write_bytes(&LED_INIT1).await?;
self.write_bytes(LED_INIT2.as_bytes()).await?;
self.write_bytes(&LED_INIT3).await?;
self.write_bytes(LED_INIT4.as_bytes()).await?;
self.write_bytes(&LED_INIT5).await?;
self.initialised = true;
}
Ok(())
}
pub async fn do_command(
&mut self,
mode: AuraModes,
config: &mut Config,
) -> Result<(), RogError> {
self.initialise().await?;
self.set_and_save(mode, config).await
}
/// Should only be used if the bytes you are writing are verified correct
#[inline]
async fn write_bytes(&self, message: &[u8]) -> Result<(), RogError> {
println!("1 Wrote: {:X?}", message);
match unsafe { self.handle.as_ref() }.write_interrupt(
self.led_endpoint,
message,
Duration::from_millis(5),
) {
Ok(_) => {
let mut buf = [0; 32];
match unsafe { self.handle.as_ref() }.read_interrupt(
0x83,
&mut buf,
Duration::from_millis(5),
) {
Ok(_) => {
println!("2 Read: {:X?}", buf);
}
Err(err) => match err {
rusb::Error::Timeout => {}
_ => error!("Failed to read to led interrupt: {:?}", err),
},
}
}
Err(err) => match err {
rusb::Error::Timeout => {}
_ => error!("Failed to write to led interrupt: {:?}", err),
},
if let Ok(mut file) = OpenOptions::new().write(true).open(&self.dev_node) {
file.write_all(message).unwrap();
return Ok(());
}
Ok(())
Err(RogError::NotSupported)
}
/// Write an effect block
@@ -150,10 +86,6 @@ where
config.current_mode = mode_num;
config.set_mode_data(mode);
config.write();
info!(
"Switched LED mode to {}",
<&str>::from(&<AuraModes>::from(config.current_mode))
);
}
}
Ok(())
@@ -198,7 +130,6 @@ where
#[inline]
pub async fn reload_last_builtin(&mut self, config: &mut Config) -> Result<(), RogError> {
self.initialise().await?;
// set current mode (if any)
if self.supported_modes.len() > 1 {
if self.supported_modes.contains(&config.current_mode) {

View File

@@ -2,14 +2,11 @@
use crate::{config::Config, error::RogError};
use log::{error, info, warn};
use rusb::{Device, DeviceHandle};
use std::error::Error;
use std::fs::OpenOptions;
use std::io::Write;
use std::marker::{PhantomPinned};
use std::path::Path;
use std::process::Command;
use std::ptr::NonNull;
use std::str::FromStr;
static FAN_TYPE_1_PATH: &str = "/sys/devices/platform/asus-nb-wmi/throttle_thermal_policy";
@@ -26,72 +23,11 @@ static BAT_CHARGE_PATH: &str = "/sys/class/power_supply/BAT0/charge_control_end_
/// - `LED_INIT4`
/// - `LED_INIT2`
/// - `LED_INIT4`
pub struct RogCore {
handle: DeviceHandle<rusb::GlobalContext>,
_pin: PhantomPinned,
}
pub struct RogCore {}
impl RogCore {
pub fn new(vendor: u16, product: u16, match_endpoint: u8) -> Result<RogCore, Box<dyn Error>> {
let device = RogCore::get_device(vendor, product).map_err(|err| {
error!("Could not find keyboard device: {:?}", err);
err
})?;
let dev_config = device.config_descriptor(0).map_err(|err| {
error!("Could not get keyboard device config: {:?}", err);
err
})?;
info!("ACTIVE CONFIG: {:?}", dev_config.number());
// Interface with outputs
let mut interface = 2; // The interface with keyboard consumer device and LED control
// is #2 on 0x1866 device at least
for iface in dev_config.interfaces() {
for desc in iface.descriptors() {
for endpoint in desc.endpoint_descriptors() {
if endpoint.address() == match_endpoint {
info!("INTERVAL: {:?}", endpoint.interval());
info!("MAX_PKT_SIZE: {:?}", endpoint.max_packet_size());
info!("SYNC: {:?}", endpoint.sync_type());
info!("TRANSFER_TYPE: {:?}", endpoint.transfer_type());
info!("ENDPOINT: {:X?}", endpoint.address());
info!("INTERFACE: {:X?}", desc.interface_number());
interface = desc.interface_number();
break;
}
}
}
}
let mut device = device.open().map_err(|err| {
error!("Could not open device: {:?}", err);
err
})?;
if let Err(err) = device.set_auto_detach_kernel_driver(true) {
warn!("Auto-detach kernel driver failed: {:?}", err);
warn!("Trying device reset");
device.reset()?;
std::thread::sleep(std::time::Duration::from_millis(500));
device.set_auto_detach_kernel_driver(true)?;
}
// std::thread::sleep(std::time::Duration::from_millis(500));
Ok(RogCore {
handle: device,
_pin: PhantomPinned,
})
}
fn get_device(vendor: u16, product: u16) -> Result<Device<rusb::GlobalContext>, rusb::Error> {
for device in rusb::devices()?.iter() {
let device_desc = device.device_descriptor()?;
if device_desc.vendor_id() == vendor && device_desc.product_id() == product {
return Ok(device);
}
}
Err(rusb::Error::NoDevice)
pub fn new(vendor: u16, product: u16) -> Self {
RogCore {}
}
fn get_fan_path() -> Result<&'static str, std::io::Error> {
@@ -318,7 +254,6 @@ impl RogCore {
}
}
#[derive(Debug)]
pub enum FanLevel {
Normal,