Replace some unwrap by Result
authorGreg Burri <greg.burri@gmail.com>
Fri, 6 Oct 2023 10:06:30 +0000 (12:06 +0200)
committerGreg Burri <greg.burri@gmail.com>
Fri, 6 Oct 2023 10:06:30 +0000 (12:06 +0200)
Output panic to log

Cargo.toml
src/a770.rs
src/asus_aura_usb.rs
src/machine.rs
src/main.rs
src/main_loop.rs
src/tests.rs

index b44964a..d72d7c9 100644 (file)
@@ -10,14 +10,15 @@ edition = "2021"
 
 [dependencies]
 serde = { version = "1.0", features = ["derive"] }
-ron = "0.8" # Rust object notation, to load configuration files.
+ron = "0.8"                                        # Rust object notation, to load configuration files.
 
 num = "0.4"
 
 dirs = "5.0"
 anyhow = "1.0"
 
-flexi_logger = "0.26"
+flexi_logger = "0.27"
+log-panics = { version = "2", features = ["with-backtrace"] }
 log = "0.4"
 
 windows-service = "0.6"
@@ -33,7 +34,7 @@ libc = "0.2"
 wmi = "0.13"
 crc = "3.0"
 
-libloading = "0.8"
+libloading = "0.8"
 # netcorehost = "0.15"
 
 [dependencies.windows]
@@ -56,6 +57,6 @@ features = [
 bindgen = "0.68"
 
 [profile.release]
-strip = "debuginfo"
+strip = "debuginfo"
 codegen-units = 1
 lto = true
index 29c3028..ed6c18e 100644 (file)
@@ -40,6 +40,8 @@
 //   internal static \u0024ArrayType\u0024\u0024\u0024BY08E \u003FA0x171ed149\u002E\u003FprevData\u0040\u003F1\u003F\u003FSetLEDBehavior\u0040CVGAAdaptor\u0040\u0040UEAA_NEEEEEEEEE\u0040Z\u00404PAEA;
 // public static __FnPtr<_ctl_result_t (_ctl_init_args_t*, _ctl_api_handle_t**)> __m2mep\u0040\u003FctlInit\u0040\u0040\u0024\u0024J0YA\u003FAW4_ctl_result_t\u0040\u0040PEAU_ctl_init_args_t\u0040\u0040PEAPEAU_ctl_api_handle_t\u0040\u0040\u0040Z;
 
+use log::error;
+
 use std::{
     io::prelude::*,
     net::TcpStream,
@@ -52,24 +54,24 @@ pub struct A770 {
 }
 
 impl A770 {
-    pub fn new() -> Self {
-        A770 {
-            process: Command::new(r"IntelOC.exe")
-                .spawn()
-                .expect("failed to execute process"),
-            stream: TcpStream::connect("127.0.0.1:6577").unwrap(),
-        }
+    pub fn new() -> anyhow::Result<Self> {
+        Ok(A770 {
+            process: Command::new(r"IntelOC.exe").spawn()?,
+            stream: TcpStream::connect("127.0.0.1:6577")?,
+        })
     }
 
-    pub fn set_color(&mut self, r: u8, g: u8, b: u8) {
+    pub fn set_color(&mut self, r: u8, g: u8, b: u8) -> anyhow::Result<()> {
         let buffer: [u8; 3] = [r, g, b];
-        self.stream.write(&buffer).unwrap();
+        self.stream.write(&buffer).map(|_| ())?;
+        Ok(())
     }
 }
 
 impl Drop for A770 {
     fn drop(&mut self) {
-        self.process.kill().unwrap();
-        self.process.try_wait().unwrap();
+        if let Err(error) = self.process.kill().and(self.process.try_wait()) {
+            error!("Unable to kill the child process: {:?}", error);
+        }
     }
 }
index e639d38..31a2b27 100644 (file)
@@ -27,38 +27,36 @@ pub struct Device {
 }
 
 impl Device {
-    pub fn new(api: &hidapi::HidApi, motherboard: Motherboard) -> Self {
+    pub fn new(api: &hidapi::HidApi, motherboard: Motherboard) -> anyhow::Result<Self> {
         let device = Device {
-            device: api
-                .open(
-                    VID,
-                    match motherboard {
-                        Motherboard::Asus650e => PID_650_E,
-                        Motherboard::AsusCrosshairVIIIHero => PID_CROSSHAIR,
-                    },
-                )
-                .unwrap(),
+            device: api.open(
+                VID,
+                match motherboard {
+                    Motherboard::Asus650e => PID_650_E,
+                    Motherboard::AsusCrosshairVIIIHero => PID_CROSSHAIR,
+                },
+            )?,
             motherboard,
         };
 
-        device.set_fixed_mode();
-        device
+        device.set_fixed_mode()?;
+        Ok(device)
     }
 
-    pub fn get_firmware_string(&self) -> String {
+    pub fn get_firmware_string(&self) -> anyhow::Result<String> {
         let mut buffer = [0u8; 65];
         buffer[0] = 0xEC;
         buffer[1] = AURA_REQUEST_FIRMWARE_VERSION;
-        let n_write = self.device.write(&buffer).unwrap();
+        let n_write = self.device.write(&buffer)?;
         assert_eq!(n_write, 65);
 
         buffer.fill(0);
-        let n_read = self.device.read(&mut buffer).unwrap();
+        let n_read = self.device.read(&mut buffer)?;
         assert_eq!(n_read, 65);
         assert_eq!(buffer[0], 0xEC);
         assert_eq!(buffer[1], 0x02);
 
-        String::from(str::from_utf8(&buffer[2..17]).unwrap())
+        Ok(String::from(str::from_utf8(&buffer[2..17])?))
     }
 
     /*
@@ -76,25 +74,23 @@ impl Device {
     00 00 00 00 00 00
     00 00 00 00 00 00
     */
-    pub fn get_configuration_table(&self) -> [u8; 60] {
+    pub fn get_configuration_table(&self) -> anyhow::Result<[u8; 60]> {
         let mut buffer = [0u8; 65];
         buffer[0] = 0xEC;
         buffer[1] = AURA_REQUEST_CONFIG_TABLE;
-        let n_write = self.device.write(&buffer).unwrap();
+        let n_write = self.device.write(&buffer)?;
         assert_eq!(n_write, 65);
 
         buffer.fill(0);
-        let n_read = self.device.read(&mut buffer).unwrap();
+        let n_read = self.device.read(&mut buffer)?;
         assert_eq!(n_read, 65);
         assert_eq!(buffer[0], 0xEC);
         assert_eq!(buffer[1], 0x30);
 
-        buffer[4..64]
-            .try_into()
-            .expect("slice with incorrect length")
+        Ok(buffer[4..64].try_into()?)
     }
 
-    fn set_fixed_mode(&self) {
+    fn set_fixed_mode(&self) -> anyhow::Result<()> {
         let mut buffer = [0u8; 65];
         buffer[0] = 0xEC;
         buffer[1] = 0x35; // Control mode.
@@ -103,12 +99,13 @@ impl Device {
 
         for channel_effect_id in 0..2 {
             buffer[2] = channel_effect_id; // Channel effect id: Fixed.
-            let n_write = self.device.write(&buffer).unwrap();
+            let n_write = self.device.write(&buffer)?;
             assert_eq!(n_write, 65);
         }
+        Ok(())
     }
 
-    pub fn set_color(&self, color: &RGB) {
+    pub fn set_color(&self, color: &RGB) -> anyhow::Result<()> {
         let mut buffer = [0u8; 65];
         buffer[0] = 0xEC;
         buffer[1] = 0x36;
@@ -126,17 +123,19 @@ impl Device {
             buffer[5 + 3 * n + 2] = color.blue;
         }
 
-        let n_write = self.device.write(&buffer).unwrap();
+        let n_write = self.device.write(&buffer)?;
         assert_eq!(n_write, 65);
+        Ok(())
     }
 
-    pub fn save_current_color(&self) {
+    pub fn save_current_color(&self) -> anyhow::Result<()> {
         let mut buffer = [0u8; 65];
         buffer[0] = 0xEC;
         buffer[1] = 0x3F;
         buffer[2] = 0x55;
 
-        let n_write = self.device.write(&buffer).unwrap();
+        let n_write = self.device.write(&buffer)?;
         assert_eq!(n_write, 65);
+        Ok(())
     }
 }
index 9436f49..9d150db 100644 (file)
@@ -1,7 +1,15 @@
+use log::error;
+use nvapi::sys::i2c;
+
 use crate::{
     a770, asus_aura_usb, corsair_lighting_pro, corsair_vengeance, cpu_temperature, intel_arc, rgb,
 };
 
+const RGB_FUSION2_GPU_REG_COLOR: u8 = 0x40;
+const RGB_FUSION2_GPU_REG_MODE: u8 = 0x88;
+
+const GIGABYTE_RTX3080TI_VISION_OC_ADDR: u8 = 0x63;
+
 pub trait Machine {
     fn set_color(&mut self, color: &rgb::RGB);
     fn get_gpu_tmp(&self) -> f32;
@@ -16,17 +24,17 @@ pub struct MachineJiji {
 }
 
 impl MachineJiji {
-    pub fn new() -> Self {
+    pub fn new() -> anyhow::Result<Self> {
         let api = hidapi::HidApi::new().unwrap();
-        MachineJiji {
+        Ok(MachineJiji {
             ram: vec![
                 corsair_vengeance::Controller::new(0x19),
                 corsair_vengeance::Controller::new(0x1B),
             ],
-            b650e_device: asus_aura_usb::Device::new(&api, asus_aura_usb::Motherboard::Asus650e),
-            a770: a770::A770::new(),
+            b650e_device: asus_aura_usb::Device::new(&api, asus_aura_usb::Motherboard::Asus650e)?,
+            a770: a770::A770::new()?,
             gpu_devices: unsafe { intel_arc::GetDevices() },
-        }
+        })
     }
 }
 
@@ -36,7 +44,9 @@ impl Machine for MachineJiji {
             controller.set_color(&color);
         }
         self.b650e_device.set_color(&color);
-        self.a770.set_color(color.red, color.green, color.blue);
+        if let Err(error) = self.a770.set_color(color.red, color.green, color.blue) {
+            error!("Unable to set color: {:?}", error);
+        }
     }
 
     fn get_gpu_tmp(&self) -> f32 {
@@ -63,16 +73,16 @@ pub struct MachineLyssMetal {
 }
 
 impl MachineLyssMetal {
-    pub fn new() -> Self {
-        let api = hidapi::HidApi::new().unwrap();
+    pub fn new() -> anyhow::Result<Self> {
+        let api = hidapi::HidApi::new()?;
 
         nvapi::initialize().expect("Unable to initialize nvapi (Nvidia API)");
 
-        MachineLyssMetal {
+        let machine = MachineLyssMetal {
             crosshair_device: asus_aura_usb::Device::new(
                 &api,
                 asus_aura_usb::Motherboard::AsusCrosshairVIIIHero,
-            ),
+            )?,
             corsair_lignting_pro: corsair_lighting_pro::Device::new(
                 &api,
                 &rgb::RGB {
@@ -81,8 +91,63 @@ impl MachineLyssMetal {
                     blue: 40,
                 },
             ),
-            gpus: nvapi::PhysicalGpu::enumerate().unwrap(),
-        }
+            gpus: nvapi::PhysicalGpu::enumerate()?,
+        };
+
+        // machine.set_mode_3080ti();
+        Ok(machine)
+    }
+
+    // Doesn't work: "Error: NotSupported".
+    // From OpenRGB, see the following files:
+    //  * Controllers\GigabyteRGBFusion2GPUController\GigabyteRGBFusion2GPUControllerDetect.cpp
+    //  * Controllers\GigabyteRGBFusion2GPUController\RGBController_GigabyteRGBFusion2GPU.cpp
+    //  * Controllers\GigabyteRGBFusion2GPUController\GigabyteRGBFusion2GPUController.cpp
+    //  * i2c_smbus\i2c_smbus_nvapi.cpp
+    // Implementation of nvapi-rs: https://github.com/arcnmx/nvapi-rs/blob/master/src/gpu.rs#L645
+    pub fn test_i2c(&self) {
+        // Test from 'GigabyteRGBFusion2GPUControllerDetect.cpp'
+        let data = [0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
+        self.gpus[0]
+            .i2c_write(
+                0,
+                Some(1),
+                false,
+                GIGABYTE_RTX3080TI_VISION_OC_ADDR,
+                &[],
+                &data,
+                i2c::I2cSpeed::Default,
+            )
+            .expect("Error");
+    }
+
+    fn set_mode_3080ti(&self) {
+        let data = [
+            RGB_FUSION2_GPU_REG_MODE,
+            0x01, // Mode (1: static).
+            0x00, // Speed.
+            0x63, // Brightness max.
+            0x00, // Mistery flag.
+            0x01, // Zone.
+            0x00,
+            0x00,
+        ];
+        self.gpus[0]
+            .i2c_write(
+                0,
+                Some(1),
+                false,
+                GIGABYTE_RTX3080TI_VISION_OC_ADDR,
+                &[],
+                &data,
+                i2c::I2cSpeed::Default,
+            )
+            .expect("Error");
+    }
+
+    fn set_color_3080ti(&self, color: &rgb::RGB) {
+        // TODO.
+        self.test_i2c();
     }
 }
 
@@ -90,6 +155,7 @@ impl Machine for MachineLyssMetal {
     fn set_color(&mut self, color: &rgb::RGB) {
         self.crosshair_device.set_color(&color);
         self.corsair_lignting_pro.set_color(&color);
+        // self.set_color_3080ti(&color); // TODO.
     }
 
     fn get_gpu_tmp(&self) -> f32 {
index 34feec7..fdbb104 100644 (file)
@@ -75,6 +75,8 @@ fn main() -> Result<()> {
         .print_message()
         .start()?;
 
+    log_panics::init();
+
     let args: Vec<String> = env::args().collect();
 
     info!("Temperature to RGB");
index c787250..bc2f6ee 100644 (file)
@@ -24,8 +24,12 @@ pub fn main_loop(completed: Arc<AtomicBool>) {
     println!("Settings: {settings:?}");
 
     let mut machine: Box<dyn machine::Machine> = match settings.machine_name {
-        settings::MachineName::Jiji => Box::new(machine::MachineJiji::new()),
-        settings::MachineName::LyssMetal => Box::new(machine::MachineLyssMetal::new()),
+        settings::MachineName::Jiji => {
+            Box::new(machine::MachineJiji::new().expect("Unable to create MachineJiji"))
+        }
+        settings::MachineName::LyssMetal => {
+            Box::new(machine::MachineLyssMetal::new().expect("Unable to create MachineLyssMetal"))
+        }
     };
 
     let mut kernel = [0f32; consts::KERNEL_SIZE_SAMPLES];
index 09c75e4..0cf81ad 100644 (file)
@@ -12,13 +12,14 @@ pub fn tests() {
 
     winring0::init();
 
-    test_asus_aura_usb(asus_aura_usb::Motherboard::AsusCrosshairVIIIHero);
+    // test_asus_aura_usb(asus_aura_usb::Motherboard::AsusCrosshairVIIIHero);
     // test_corsair_lighting_pro();
     // list_usb_devices();
     // test_roccat();
     // test_wmi();
     // test_corsair();
     // test_a770();
+    test_3080ti();
     // test_read_temperature_cpu();
     // test_read_temperature_a770()
     // test_read_temperature_3080();
@@ -85,11 +86,11 @@ fn list_usb_devices() {
 fn test_asus_aura_usb(motherboard: asus_aura_usb::Motherboard) {
     let api = hidapi::HidApi::new().unwrap();
 
-    let device = asus_aura_usb::Device::new(&api, motherboard);
+    let device = asus_aura_usb::Device::new(&api, motherboard).unwrap();
 
-    println!("Firmware: {}", device.get_firmware_string());
+    println!("Firmware: {}", device.get_firmware_string().unwrap());
 
-    let configuration = device.get_configuration_table();
+    let configuration = device.get_configuration_table().unwrap();
     println!("Configuration:");
     for i in 0..60 {
         print!("{:02X} ", configuration[i]);
@@ -101,13 +102,15 @@ fn test_asus_aura_usb(motherboard: asus_aura_usb::Motherboard) {
     println!("Number of leds: {}", configuration[0x1B]);
     println!("Number of RGB headers: {}", configuration[0x1D]);
 
-    device.set_color(&RGB {
-        red: 0,
-        green: 0,
-        blue: 255,
-    });
+    device
+        .set_color(&RGB {
+            red: 0,
+            green: 0,
+            blue: 255,
+        })
+        .unwrap();
 
-    device.save_current_color();
+    device.save_current_color().unwrap();
 }
 
 fn test_corsair_lighting_pro() {
@@ -150,8 +153,18 @@ fn test_corsair() {
 
 fn test_a770() {
     // a770::set_rgb(255, 0, 0);
-    let mut a770 = a770::A770::new();
-    a770.set_color(255, 0, 0);
+    let mut a770 = a770::A770::new().unwrap();
+    a770.set_color(255, 0, 0).unwrap();
+}
+
+fn test_3080ti() {
+    let machine: &mut dyn machine::Machine = &mut machine::MachineLyssMetal::new().unwrap();
+
+    machine.set_color(&RGB {
+        red: 255,
+        green: 0,
+        blue: 0,
+    });
 }
 
 const F17H_M01H_THM_TCON_CUR_TMP: u32 = 0x00059800;
@@ -163,7 +176,7 @@ fn test_read_temperature_cpu() {
 }
 
 fn test_read_temperature_a770() {
-    let jiji: &dyn machine::Machine = &machine::MachineJiji::new();
+    let jiji: &dyn machine::Machine = &machine::MachineJiji::new().unwrap();
     println!("temp gpu: {}", jiji.get_gpu_tmp());
 }