Created by: lopsided98
This PR fixes issues that occur when a device sleeps or wakes up, or is powered on or off with the power switch.
I believe all HID++ >=2.0 devices have a sleep mode (I know my HID++ 1.0 M705 does not, while my HID++ 4.5 M705 does, but I don't have any other devices to test), which appears to act equivalently to turning the device on or off with the power switch. After five minutes, my device disconnects, and then reconnects if it is moved or the buttons are pressed. The same notifications are sent when the device sleeps as when it is turned off, and the same notifications are sent when it wakes as when it is turned on. This makes debugging much easier as I don't have to wait five minutes for the device to sleep, I can simply use the power switch to get the same behavior. When the device sleeps or is powered off, all settings are lost.
The one of the fixes is the same as #414. As mentioned in that PR, this fix is a revert of a4b71944 (in #382), which introduced behavior that seems incorrect, because the 0x41
notification is sent every time a device goes to sleep, wakes, powers on or powers off. That commit supposedly fixes a race condition, but neither @SonicFrog nor I were able to reproduce anything like it. It would nice to know more details about that issue.
Next, this PR includes a fix which applies the saved configuration every time a 0x41
notification is received. This prevents devices from reverting to their default configuration when they sleep.
This fix had the side effect of clearing the current status because status.attach_to()
is no longer only called when the device first connects. Therefore I added a check to prevent this function from attaching the status if it already exists.
I added a hacky fix for a race condition that can occur when the device is powered on/woken from sleep (I do not believe this is the race described in #382). If a read or write is attempted immediately after the device is powered on, it fails with EPIPE and breaks the file handle, causing all future transfers to fail. I assume this is because the device is not ready to communicate yet, and this causes a problem with the driver. It is possible to detect when this race can occur, because it follows a 0x41
connection notification with the "payload" bit set. I'm not sure what the "payload" bit is supposed to be, but it seems to indicate that the device is waking from sleep or begin powered on. The 0x41
notification is always immediately followed by an undocumented 0x42
notification. This could possibly be a notification that the device is ready to communicate. I attempted to delay communication until after a 0x42
notification was received, but I was unable to make this work, because there are a lot of functions that assume that they can write to the device immediately after receiving a 0x41
notification. Implementing this without creating new bugs would have been a large amount of work, and I'm not even sure that it is the right solution. Instead, I simply added a short delay after receiving a 0x41
notification with the payload bit set. This solves the problem for me, but is inelegant.
This PR also includes the Python 3.7 compatibility fix from #448, because it is impossible to run Solaar on up-to-date Linux distros without it. Lastly, I also included #450 (my other PR), because it is required for me to test these changes.
This PR supersedes/includes #414, #448 and #450. It is likely that this PR solves: #356 (closed), #418 (closed), #430 (closed), #437 (closed), #443 (closed), [#444 (closed)?], [#445 (closed)?] (also: #405 (closed), #447 (closed) and #449 (closed) from included PRs)
I have tested this PR on my two M705s (M-R0009 and M-R0073).