From 6aba60f604c613ef7c5bbec276b5af709104b989 Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" Date: Fri, 27 Aug 2021 22:31:50 +1200 Subject: [PATCH] Try to re-get AniMe dev handle on write error --- daemon/src/ctrl_anime/mod.rs | 63 +++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/daemon/src/ctrl_anime/mod.rs b/daemon/src/ctrl_anime/mod.rs index e96d2dc0..f33f0c2a 100644 --- a/daemon/src/ctrl_anime/mod.rs +++ b/daemon/src/ctrl_anime/mod.rs @@ -13,11 +13,7 @@ use rog_anime::{ }; use rog_supported::AnimeSupportedFunctions; use rusb::{Device, DeviceHandle}; -use std::{ - error::Error, - sync::{Arc, Mutex}, - thread::sleep, -}; +use std::{cell::{RefCell}, error::Error, sync::{Arc, Mutex}, thread::sleep}; use std::{ sync::atomic::{AtomicBool, Ordering}, time::Duration, @@ -36,7 +32,7 @@ impl GetSupported for CtrlAnime { } pub struct CtrlAnime { - handle: DeviceHandle, + handle: RefCell>, cache: AnimeConfigCached, config: AnimeConfig, // set to force thread to exit @@ -48,6 +44,25 @@ pub struct CtrlAnime { impl CtrlAnime { #[inline] pub fn new(config: AnimeConfig) -> Result> { + let device = Self::get_dev_handle()?; + + info!("Device has an AniMe Matrix display"); + let mut cache = AnimeConfigCached::default(); + cache.init_from_config(&config)?; + + let ctrl = CtrlAnime { + handle: RefCell::new(device), + cache, + config, + thread_exit: Arc::new(AtomicBool::new(false)), + thread_running: Arc::new(AtomicBool::new(false)), + }; + ctrl.do_initialization(); + + Ok(ctrl) + } + + fn get_dev_handle() -> Result, Box> { // We don't expect this ID to ever change let device = CtrlAnime::get_device(0x0b05, 0x193b)?; @@ -64,20 +79,7 @@ impl CtrlAnime { err })?; - info!("Device has an AniMe Matrix display"); - let mut cache = AnimeConfigCached::default(); - cache.init_from_config(&config)?; - - let ctrl = CtrlAnime { - handle: device, - cache, - config, - thread_exit: Arc::new(AtomicBool::new(false)), - thread_running: Arc::new(AtomicBool::new(false)), - }; - ctrl.do_initialization(); - - Ok(ctrl) + Ok(device) } fn get_device(vendor: u16, product: u16) -> Result, rusb::Error> { @@ -186,7 +188,9 @@ impl CtrlAnime { } fn write_bytes(&self, message: &[u8]) { - match self.handle.write_control( + let mut error = false; + + match self.handle.borrow().write_control( 0x21, // request_type 0x09, // request 0x35e, // value @@ -197,9 +201,24 @@ impl CtrlAnime { Ok(_) => {} Err(err) => match err { rusb::Error::Timeout => {} - _ => error!("Failed to write to led interrupt: {}", err), + _ => { + error = true; + error!("Failed to write to led interrupt: {}", err); + } }, } + + if error { + warn!("Will attempt to get AniMe device handle again"); + match Self::get_dev_handle() { + Ok(dev) => { + self.handle.replace(dev); + } + Err(err) => { + error!("Failed to get AniMe device: {}", err); + } + } + } } /// Write only a data packet. This will modify the leds brightness using the