mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
SCSI support: ROG Arion external drive LED control
This commit is contained in:
@@ -2,10 +2,13 @@
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- ROG Arion external driver LED support
|
||||||
|
- Add GA605W LED layout
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Fix attribute writes. At some point the kernel API seems to have changed.
|
- Fix attribute writes. At some point the kernel API seems to have changed.
|
||||||
- Extremely large refactor of Aura device handling. Should enable easy add of different kinds now.
|
- Extremely large refactor of Aura device handling. Should enable easy add of different kinds now.
|
||||||
- Add GA605W LED layout
|
|
||||||
- Rename CLI args for aura related properties. This will likely change further as more devices are added
|
- Rename CLI args for aura related properties. This will likely change further as more devices are added
|
||||||
|
|
||||||
## [v6.0.12]
|
## [v6.0.12]
|
||||||
|
|||||||
149
Cargo.lock
generated
149
Cargo.lock
generated
@@ -187,6 +187,7 @@ dependencies = [
|
|||||||
"rog_dbus",
|
"rog_dbus",
|
||||||
"rog_platform",
|
"rog_platform",
|
||||||
"rog_profiles",
|
"rog_profiles",
|
||||||
|
"rog_scsi",
|
||||||
"rog_slash",
|
"rog_slash",
|
||||||
"ron",
|
"ron",
|
||||||
"zbus 5.2.0",
|
"zbus 5.2.0",
|
||||||
@@ -210,6 +211,7 @@ dependencies = [
|
|||||||
"rog_aura",
|
"rog_aura",
|
||||||
"rog_platform",
|
"rog_platform",
|
||||||
"rog_profiles",
|
"rog_profiles",
|
||||||
|
"rog_scsi",
|
||||||
"rog_slash",
|
"rog_slash",
|
||||||
"serde",
|
"serde",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -549,12 +551,32 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex",
|
"regex",
|
||||||
"rustc-hash",
|
"rustc-hash 1.1.0",
|
||||||
"shlex",
|
"shlex",
|
||||||
"syn 2.0.90",
|
"syn 2.0.90",
|
||||||
"which",
|
"which",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bindgen"
|
||||||
|
version = "0.71.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
"cexpr",
|
||||||
|
"clang-sys",
|
||||||
|
"itertools 0.13.0",
|
||||||
|
"log",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"regex",
|
||||||
|
"rustc-hash 2.1.0",
|
||||||
|
"shlex",
|
||||||
|
"syn 2.0.90",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bit_field"
|
name = "bit_field"
|
||||||
version = "0.10.2"
|
version = "0.10.2"
|
||||||
@@ -648,18 +670,18 @@ checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.20.0"
|
version = "1.21.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a"
|
checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck_derive",
|
"bytemuck_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck_derive"
|
name = "bytemuck_derive"
|
||||||
version = "1.8.0"
|
version = "1.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec"
|
checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -731,9 +753,9 @@ checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.4"
|
version = "1.2.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf"
|
checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -930,7 +952,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "const-field-offset"
|
name = "const-field-offset"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"const-field-offset-macro",
|
"const-field-offset-macro",
|
||||||
"field-offset",
|
"field-offset",
|
||||||
@@ -939,7 +961,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "const-field-offset-macro"
|
name = "const-field-offset-macro"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -2150,8 +2172,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "i-slint-backend-linuxkms"
|
name = "i-slint-backend-linuxkms"
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"calloop 0.14.2",
|
"calloop 0.14.2",
|
||||||
"drm",
|
"drm",
|
||||||
@@ -2168,8 +2190,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "i-slint-backend-selector"
|
name = "i-slint-backend-selector"
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"i-slint-backend-linuxkms",
|
"i-slint-backend-linuxkms",
|
||||||
@@ -2181,8 +2203,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "i-slint-backend-winit"
|
name = "i-slint-backend-winit"
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ashpd",
|
"ashpd",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
@@ -2212,8 +2234,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "i-slint-common"
|
name = "i-slint-common"
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
@@ -2224,8 +2246,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "i-slint-compiler"
|
name = "i-slint-compiler"
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"by_address",
|
"by_address",
|
||||||
"codemap",
|
"codemap",
|
||||||
@@ -2254,8 +2276,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "i-slint-core"
|
name = "i-slint-core"
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"auto_enums",
|
"auto_enums",
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
@@ -2299,8 +2321,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "i-slint-core-macros"
|
name = "i-slint-core-macros"
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -2309,8 +2331,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "i-slint-renderer-femtovg"
|
name = "i-slint-renderer-femtovg"
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"const-field-offset",
|
"const-field-offset",
|
||||||
@@ -2339,8 +2361,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "i-slint-renderer-skia"
|
name = "i-slint-renderer-skia"
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
@@ -3195,6 +3217,7 @@ dependencies = [
|
|||||||
"cfg_aliases",
|
"cfg_aliases",
|
||||||
"libc",
|
"libc",
|
||||||
"memoffset",
|
"memoffset",
|
||||||
|
"pin-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3538,9 +3561,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.36.5"
|
version = "0.36.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
|
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
@@ -3670,9 +3693,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "png"
|
name = "png"
|
||||||
version = "0.17.15"
|
version = "0.17.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b67582bd5b65bdff614270e2ea89a1cf15bef71245cc1e5f7ea126977144211d"
|
checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
@@ -4145,6 +4168,7 @@ dependencies = [
|
|||||||
"rog_aura",
|
"rog_aura",
|
||||||
"rog_platform",
|
"rog_platform",
|
||||||
"rog_profiles",
|
"rog_profiles",
|
||||||
|
"rog_scsi",
|
||||||
"rog_slash",
|
"rog_slash",
|
||||||
"zbus 5.2.0",
|
"zbus 5.2.0",
|
||||||
]
|
]
|
||||||
@@ -4177,6 +4201,19 @@ dependencies = [
|
|||||||
"zbus 5.2.0",
|
"zbus 5.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rog_scsi"
|
||||||
|
version = "6.0.12"
|
||||||
|
dependencies = [
|
||||||
|
"cargo-husky",
|
||||||
|
"log",
|
||||||
|
"ron",
|
||||||
|
"serde",
|
||||||
|
"sg",
|
||||||
|
"typeshare",
|
||||||
|
"zbus 5.2.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rog_simulators"
|
name = "rog_simulators"
|
||||||
version = "6.0.12"
|
version = "6.0.12"
|
||||||
@@ -4218,7 +4255,7 @@ checksum = "0a542b0253fa46e632d27a1dc5cf7b930de4df8659dc6e720b647fc72147ae3d"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"countme",
|
"countme",
|
||||||
"hashbrown 0.14.5",
|
"hashbrown 0.14.5",
|
||||||
"rustc-hash",
|
"rustc-hash 1.1.0",
|
||||||
"text-size",
|
"text-size",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -4250,6 +4287,12 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@@ -4411,9 +4454,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.133"
|
version = "1.0.134"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
|
checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
@@ -4441,6 +4484,16 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sg"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "git+https://github.com/flukejones/sg-rs.git#b1ce961ae42b0aad22166bac84e5105a918debd3"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen 0.71.1",
|
||||||
|
"libc",
|
||||||
|
"nix",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
@@ -4512,7 +4565,7 @@ version = "0.78.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "29880a81b088de322e9c5306236c70761a61b5fa4df3c15c93bad3ce890ce34c"
|
checksum = "29880a81b088de322e9c5306236c70761a61b5fa4df3c15c93bad3ce890ce34c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen 0.69.5",
|
||||||
"cc",
|
"cc",
|
||||||
"flate2",
|
"flate2",
|
||||||
"heck",
|
"heck",
|
||||||
@@ -4546,8 +4599,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slint"
|
name = "slint"
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"const-field-offset",
|
"const-field-offset",
|
||||||
"i-slint-backend-selector",
|
"i-slint-backend-selector",
|
||||||
@@ -4563,8 +4616,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slint-build"
|
name = "slint-build"
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"i-slint-compiler",
|
"i-slint-compiler",
|
||||||
"i-slint-core-macros",
|
"i-slint-core-macros",
|
||||||
@@ -4575,8 +4628,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slint-macros"
|
name = "slint-macros"
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"i-slint-compiler",
|
"i-slint-compiler",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -5023,9 +5076,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinyvec"
|
name = "tinyvec"
|
||||||
version = "1.8.0"
|
version = "1.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938"
|
checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"tinyvec_macros",
|
"tinyvec_macros",
|
||||||
]
|
]
|
||||||
@@ -5357,7 +5410,7 @@ version = "1.0.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e24880fbcee511571ed9104b9a5273d1563d11ccaaf54b7c05cc6c100b652f9f"
|
checksum = "e24880fbcee511571ed9104b9a5273d1563d11ccaaf54b7c05cc6c100b652f9f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen 0.69.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5537,7 +5590,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "vtable"
|
name = "vtable"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"const-field-offset",
|
"const-field-offset",
|
||||||
"portable-atomic",
|
"portable-atomic",
|
||||||
@@ -5548,7 +5601,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "vtable-macro"
|
name = "vtable-macro"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "git+https://github.com/slint-ui/slint.git#09c9857082ff0e5cef6cdb4ed4396aab9eafb9d4"
|
source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -6176,9 +6229,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winit"
|
name = "winit"
|
||||||
version = "0.30.5"
|
version = "0.30.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0be9e76a1f1077e04a411f0b989cbd3c93339e1771cb41e71ac4aee95bfd2c67"
|
checksum = "7c3d72dfa0f47e429290cd0d236884ca02f22dbd5dd33a43ad2b8bf4d79b6c18"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"android-activity",
|
"android-activity",
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ members = [
|
|||||||
"rog-profiles",
|
"rog-profiles",
|
||||||
"rog-control-center",
|
"rog-control-center",
|
||||||
"rog-slash",
|
"rog-slash",
|
||||||
"simulators",
|
"simulators", "rog-scsi",
|
||||||
]
|
]
|
||||||
default-members = [
|
default-members = [
|
||||||
"asusctl",
|
"asusctl",
|
||||||
@@ -73,6 +73,8 @@ versions = "6.2"
|
|||||||
|
|
||||||
notify-rust = { version = "4.11.0", features = ["z", "async"] }
|
notify-rust = { version = "4.11.0", features = ["z", "async"] }
|
||||||
|
|
||||||
|
sg = {git = "https://github.com/flukejones/sg-rs.git"}
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
# thin = 57s, asusd = 9.0M
|
# thin = 57s, asusd = 9.0M
|
||||||
# fat = 72s, asusd = 6.4M
|
# fat = 72s, asusd = 6.4M
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ edition.workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rog_anime = { path = "../rog-anime" }
|
rog_anime = { path = "../rog-anime" }
|
||||||
|
rog_scsi = { path = "../rog-scsi" }
|
||||||
rog_slash = { path = "../rog-slash" }
|
rog_slash = { path = "../rog-slash" }
|
||||||
rog_aura = { path = "../rog-aura" }
|
rog_aura = { path = "../rog-aura" }
|
||||||
rog_dbus = { path = "../rog-dbus" }
|
rog_dbus = { path = "../rog-dbus" }
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use rog_platform::platform::ThrottlePolicy;
|
|||||||
use crate::anime_cli::AnimeCommand;
|
use crate::anime_cli::AnimeCommand;
|
||||||
use crate::aura_cli::{LedBrightness, LedPowerCommand1, LedPowerCommand2, SetAuraBuiltin};
|
use crate::aura_cli::{LedBrightness, LedPowerCommand1, LedPowerCommand2, SetAuraBuiltin};
|
||||||
use crate::fan_curve_cli::FanCurveCommand;
|
use crate::fan_curve_cli::FanCurveCommand;
|
||||||
|
use crate::scsi_cli::ScsiCommand;
|
||||||
use crate::slash_cli::SlashCommand;
|
use crate::slash_cli::SlashCommand;
|
||||||
|
|
||||||
#[derive(Default, Options)]
|
#[derive(Default, Options)]
|
||||||
@@ -46,6 +47,8 @@ pub enum CliCommand {
|
|||||||
Anime(AnimeCommand),
|
Anime(AnimeCommand),
|
||||||
#[options(name = "slash", help = "Manage Slash Ledbar")]
|
#[options(name = "slash", help = "Manage Slash Ledbar")]
|
||||||
Slash(SlashCommand),
|
Slash(SlashCommand),
|
||||||
|
#[options(name = "scsi", help = "Manage SCSI external drive")]
|
||||||
|
Scsi(ScsiCommand),
|
||||||
#[options(help = "Change bios settings")]
|
#[options(help = "Change bios settings")]
|
||||||
Platform(PlatformCommand),
|
Platform(PlatformCommand),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage,
|
|||||||
use rog_aura::keyboard::{AuraPowerState, LaptopAuraPower};
|
use rog_aura::keyboard::{AuraPowerState, LaptopAuraPower};
|
||||||
use rog_aura::{self, AuraDeviceType, AuraEffect, PowerZones};
|
use rog_aura::{self, AuraDeviceType, AuraEffect, PowerZones};
|
||||||
use rog_dbus::list_iface_blocking;
|
use rog_dbus::list_iface_blocking;
|
||||||
|
use rog_dbus::scsi_aura::ScsiAuraProxyBlocking;
|
||||||
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||||
use rog_dbus::zbus_aura::AuraProxyBlocking;
|
use rog_dbus::zbus_aura::AuraProxyBlocking;
|
||||||
use rog_dbus::zbus_fan_curves::FanCurvesProxyBlocking;
|
use rog_dbus::zbus_fan_curves::FanCurvesProxyBlocking;
|
||||||
@@ -21,8 +22,10 @@ use rog_dbus::zbus_platform::PlatformProxyBlocking;
|
|||||||
use rog_dbus::zbus_slash::SlashProxyBlocking;
|
use rog_dbus::zbus_slash::SlashProxyBlocking;
|
||||||
use rog_platform::platform::{GpuMode, Properties, ThrottlePolicy};
|
use rog_platform::platform::{GpuMode, Properties, ThrottlePolicy};
|
||||||
use rog_profiles::error::ProfileError;
|
use rog_profiles::error::ProfileError;
|
||||||
|
use rog_scsi::AuraMode;
|
||||||
use rog_slash::SlashMode;
|
use rog_slash::SlashMode;
|
||||||
use ron::ser::PrettyConfig;
|
use ron::ser::PrettyConfig;
|
||||||
|
use scsi_cli::ScsiCommand;
|
||||||
use zbus::blocking::proxy::ProxyImpl;
|
use zbus::blocking::proxy::ProxyImpl;
|
||||||
use zbus::blocking::Connection;
|
use zbus::blocking::Connection;
|
||||||
|
|
||||||
@@ -34,6 +37,7 @@ mod anime_cli;
|
|||||||
mod aura_cli;
|
mod aura_cli;
|
||||||
mod cli_opts;
|
mod cli_opts;
|
||||||
mod fan_curve_cli;
|
mod fan_curve_cli;
|
||||||
|
mod scsi_cli;
|
||||||
mod slash_cli;
|
mod slash_cli;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -180,6 +184,7 @@ fn do_parsed(
|
|||||||
Some(CliCommand::Graphics(_)) => do_gfx(),
|
Some(CliCommand::Graphics(_)) => do_gfx(),
|
||||||
Some(CliCommand::Anime(cmd)) => handle_anime(cmd)?,
|
Some(CliCommand::Anime(cmd)) => handle_anime(cmd)?,
|
||||||
Some(CliCommand::Slash(cmd)) => handle_slash(cmd)?,
|
Some(CliCommand::Slash(cmd)) => handle_slash(cmd)?,
|
||||||
|
Some(CliCommand::Scsi(cmd)) => handle_scsi(cmd)?,
|
||||||
Some(CliCommand::Platform(cmd)) => {
|
Some(CliCommand::Platform(cmd)) => {
|
||||||
handle_platform_properties(&conn, supported_properties, cmd)?
|
handle_platform_properties(&conn, supported_properties, cmd)?
|
||||||
}
|
}
|
||||||
@@ -579,6 +584,79 @@ fn handle_slash(cmd: &SlashCommand) -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_scsi(cmd: &ScsiCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
if (!cmd.list && cmd.enable.is_none() && cmd.mode.is_none() && cmd.colours.is_empty())
|
||||||
|
|| cmd.help
|
||||||
|
{
|
||||||
|
println!("Missing arg or command\n\n{}", cmd.self_usage());
|
||||||
|
if let Some(lst) = cmd.self_command_list() {
|
||||||
|
println!("\n{}", lst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let scsis = find_iface::<ScsiAuraProxyBlocking>("org.asuslinux.ScsiAura")?;
|
||||||
|
|
||||||
|
for scsi in scsis {
|
||||||
|
if let Some(enable) = cmd.enable {
|
||||||
|
scsi.set_enabled(enable)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(mode) = cmd.mode {
|
||||||
|
dbg!(mode as u8);
|
||||||
|
scsi.set_led_mode(mode).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut mode = scsi.led_mode_data()?;
|
||||||
|
let mut do_update = false;
|
||||||
|
if !cmd.colours.is_empty() {
|
||||||
|
let mut count = 0;
|
||||||
|
for c in &cmd.colours {
|
||||||
|
if count == 0 {
|
||||||
|
mode.colour1 = *c;
|
||||||
|
}
|
||||||
|
if count == 1 {
|
||||||
|
mode.colour2 = *c;
|
||||||
|
}
|
||||||
|
if count == 2 {
|
||||||
|
mode.colour3 = *c;
|
||||||
|
}
|
||||||
|
if count == 3 {
|
||||||
|
mode.colour4 = *c;
|
||||||
|
}
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
do_update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(speed) = cmd.speed {
|
||||||
|
mode.speed = speed;
|
||||||
|
do_update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(dir) = cmd.direction {
|
||||||
|
mode.direction = dir;
|
||||||
|
do_update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if do_update {
|
||||||
|
scsi.set_led_mode_data(mode.clone())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// let mode_ret = scsi.led_mode_data()?;
|
||||||
|
// assert_eq!(mode, mode_ret);
|
||||||
|
println!("{mode}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.list {
|
||||||
|
let res = AuraMode::list();
|
||||||
|
for p in &res {
|
||||||
|
println!("{:?}", p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_led_mode(mode: &LedModeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
fn handle_led_mode(mode: &LedModeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if mode.command.is_none() && !mode.prev_mode && !mode.next_mode {
|
if mode.command.is_none() && !mode.prev_mode && !mode.next_mode {
|
||||||
if !mode.help {
|
if !mode.help {
|
||||||
|
|||||||
35
asusctl/src/scsi_cli.rs
Normal file
35
asusctl/src/scsi_cli.rs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
use gumdrop::Options;
|
||||||
|
use rog_scsi::{AuraMode, Colour, Direction, Speed};
|
||||||
|
|
||||||
|
#[derive(Options)]
|
||||||
|
pub struct ScsiCommand {
|
||||||
|
#[options(help = "print help message")]
|
||||||
|
pub help: bool,
|
||||||
|
|
||||||
|
#[options(help = "Enable the SCSI drive LEDs")]
|
||||||
|
pub enable: Option<bool>,
|
||||||
|
|
||||||
|
#[options(meta = "", help = "Set LED mode (so 'list' for all options)")]
|
||||||
|
pub mode: Option<AuraMode>,
|
||||||
|
|
||||||
|
#[options(
|
||||||
|
meta = "",
|
||||||
|
help = "Set LED mode speed <slowest, slow, med, fast, fastest> (does not apply to all)"
|
||||||
|
)]
|
||||||
|
pub speed: Option<Speed>,
|
||||||
|
|
||||||
|
#[options(
|
||||||
|
meta = "",
|
||||||
|
help = "Set LED mode direction <forward, reverse> (does not apply to all)"
|
||||||
|
)]
|
||||||
|
pub direction: Option<Direction>,
|
||||||
|
|
||||||
|
#[options(
|
||||||
|
meta = "",
|
||||||
|
help = "Set LED colours <hex>, specify up to 4 with repeated arg"
|
||||||
|
)]
|
||||||
|
pub colours: Vec<Colour>,
|
||||||
|
|
||||||
|
#[options(help = "list available animations")]
|
||||||
|
pub list: bool,
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ config-traits = { path = "../config-traits" }
|
|||||||
rog_anime = { path = "../rog-anime", features = ["dbus"] }
|
rog_anime = { path = "../rog-anime", features = ["dbus"] }
|
||||||
rog_slash = { path = "../rog-slash", features = ["dbus"] }
|
rog_slash = { path = "../rog-slash", features = ["dbus"] }
|
||||||
rog_aura = { path = "../rog-aura", features = ["dbus"] }
|
rog_aura = { path = "../rog-aura", features = ["dbus"] }
|
||||||
|
rog_scsi = { path = "../rog-scsi", features = ["dbus"] }
|
||||||
rog_platform = { path = "../rog-platform" }
|
rog_platform = { path = "../rog-platform" }
|
||||||
rog_profiles = { path = "../rog-profiles" }
|
rog_profiles = { path = "../rog-profiles" }
|
||||||
dmi_id = { path = "../dmi-id" }
|
dmi_id = { path = "../dmi-id" }
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ use zbus::Connection;
|
|||||||
|
|
||||||
use crate::aura_anime::trait_impls::AniMeZbus;
|
use crate::aura_anime::trait_impls::AniMeZbus;
|
||||||
use crate::aura_laptop::trait_impls::AuraZbus;
|
use crate::aura_laptop::trait_impls::AuraZbus;
|
||||||
|
use crate::aura_scsi::trait_impls::ScsiZbus;
|
||||||
use crate::aura_slash::trait_impls::SlashZbus;
|
use crate::aura_slash::trait_impls::SlashZbus;
|
||||||
use crate::aura_types::DeviceHandle;
|
use crate::aura_types::DeviceHandle;
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
@@ -70,6 +71,17 @@ fn dbus_path_for_anime() -> OwnedObjectPath {
|
|||||||
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/anime")).into()
|
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/anime")).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dbus_path_for_scsi(prod_id: &str) -> OwnedObjectPath {
|
||||||
|
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{prod_id}_scsi")).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dev_prop_matches(dev: &Device, prop: &str, value: &str) -> bool {
|
||||||
|
if let Some(p) = dev.property_value(prop) {
|
||||||
|
return p == value;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// - make this the HID manager (and universal)
|
// - make this the HID manager (and universal)
|
||||||
// - *really* need to make most of this actual kernel drivers
|
// - *really* need to make most of this actual kernel drivers
|
||||||
@@ -83,7 +95,6 @@ fn dbus_path_for_anime() -> OwnedObjectPath {
|
|||||||
///
|
///
|
||||||
/// Each controller within should track its dbus path so it can be removed if
|
/// Each controller within should track its dbus path so it can be removed if
|
||||||
/// required.
|
/// required.
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct AsusDevice {
|
pub struct AsusDevice {
|
||||||
device: DeviceHandle,
|
device: DeviceHandle,
|
||||||
dbus_path: OwnedObjectPath,
|
dbus_path: OwnedObjectPath,
|
||||||
@@ -197,7 +208,75 @@ impl DeviceManager {
|
|||||||
{
|
{
|
||||||
devices.append(&mut Self::init_hid_devices(connection, device).await?);
|
devices.append(&mut Self::init_hid_devices(connection, device).await?);
|
||||||
}
|
}
|
||||||
// debug!("Found devices: {devices:?}");
|
|
||||||
|
Ok(devices)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn init_scsi(
|
||||||
|
connection: &Connection,
|
||||||
|
device: &Device,
|
||||||
|
path: OwnedObjectPath,
|
||||||
|
) -> Option<AsusDevice> {
|
||||||
|
// "ID_MODEL_ID" "1932"
|
||||||
|
// "ID_VENDOR_ID" "0b05"
|
||||||
|
if dev_prop_matches(&device, "ID_VENDOR_ID", "0b05") {
|
||||||
|
if let Some(dev_node) = device.devnode() {
|
||||||
|
let prod_id = device
|
||||||
|
.property_value("ID_MODEL_ID")
|
||||||
|
.unwrap_or_default()
|
||||||
|
.to_string_lossy();
|
||||||
|
if let Ok(dev_type) =
|
||||||
|
DeviceHandle::maybe_scsi(dev_node.as_os_str().to_str().unwrap(), &prod_id).await
|
||||||
|
{
|
||||||
|
if let DeviceHandle::Scsi(scsi) = dev_type.clone() {
|
||||||
|
let ctrl = ScsiZbus::new(scsi);
|
||||||
|
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
||||||
|
return Some(AsusDevice {
|
||||||
|
device: dev_type,
|
||||||
|
dbus_path: path,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn init_all_scsi(connection: &Connection) -> Result<Vec<AsusDevice>, RogError> {
|
||||||
|
// track and ensure we use only one hidraw per prod_id
|
||||||
|
// let mut interfaces = HashSet::new();
|
||||||
|
let mut devices: Vec<AsusDevice> = Vec::new();
|
||||||
|
|
||||||
|
let mut enumerator = udev::Enumerator::new().map_err(|err| {
|
||||||
|
warn!("{}", err);
|
||||||
|
PlatformError::Udev("enumerator failed".into(), err)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
enumerator.match_subsystem("block").map_err(|err| {
|
||||||
|
warn!("{}", err);
|
||||||
|
PlatformError::Udev("match_subsystem failed".into(), err)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let mut found = Vec::new();
|
||||||
|
for device in enumerator
|
||||||
|
.scan_devices()
|
||||||
|
.map_err(|e| PlatformError::IoPath("enumerator".to_owned(), e))?
|
||||||
|
{
|
||||||
|
if let Some(serial) = device.property_value("ID_SERIAL_SHORT") {
|
||||||
|
let serial = serial.to_string_lossy().to_string();
|
||||||
|
let path = dbus_path_for_scsi(&serial);
|
||||||
|
if found.contains(&path) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(dev) = Self::init_scsi(connection, &device, path.clone()).await {
|
||||||
|
devices.push(dev);
|
||||||
|
found.push(path);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warn!("No serial for SCSI device");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(devices)
|
Ok(devices)
|
||||||
}
|
}
|
||||||
@@ -252,6 +331,11 @@ impl DeviceManager {
|
|||||||
info!("Tested device was not AniMe Matrix");
|
info!("Tested device was not AniMe Matrix");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Ok(devs) = &mut Self::init_all_scsi(connection).await {
|
||||||
|
devices.append(devs);
|
||||||
|
}
|
||||||
|
|
||||||
devices
|
devices
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +352,7 @@ impl DeviceManager {
|
|||||||
// detect all plugged in aura devices (eventually)
|
// detect all plugged in aura devices (eventually)
|
||||||
// only USB devices are detected for here
|
// only USB devices are detected for here
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let mut monitor = MonitorBuilder::new()?.match_subsystem("hidraw")?.listen()?;
|
let mut monitor = MonitorBuilder::new()?.listen()?;
|
||||||
let mut poll = Poll::new()?;
|
let mut poll = Poll::new()?;
|
||||||
let mut events = Events::with_capacity(1024);
|
let mut events = Events::with_capacity(1024);
|
||||||
poll.registry()
|
poll.registry()
|
||||||
@@ -281,17 +365,74 @@ impl DeviceManager {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for event in monitor.iter() {
|
for event in monitor.iter() {
|
||||||
let action = event.action().unwrap_or_default();
|
let action = event
|
||||||
|
.action()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let subsys = if let Some(subsys) = event.subsystem() {
|
||||||
|
subsys.to_string_lossy().to_string()
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let devices = devices.clone();
|
||||||
|
let conn_copy = conn_copy.clone();
|
||||||
|
block_on(async move {
|
||||||
|
// SCSCI devs
|
||||||
|
if subsys == "block" {
|
||||||
|
if action == "remove" {
|
||||||
|
if let Some(serial) =
|
||||||
|
event.device().property_value("ID_SERIAL_SHORT")
|
||||||
|
{
|
||||||
|
let serial = serial.to_string_lossy().to_string();
|
||||||
|
let path = dbus_path_for_scsi(&serial);
|
||||||
|
|
||||||
|
let index = if let Some(index) = devices
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.iter()
|
||||||
|
.position(|dev| dev.dbus_path == path)
|
||||||
|
{
|
||||||
|
index
|
||||||
|
} else {
|
||||||
|
warn!("No device for dbus path: {path:?}");
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
info!("removing: {path:?}");
|
||||||
|
let dev = devices.lock().await.remove(index);
|
||||||
|
let path = path.clone();
|
||||||
|
match dev.device {
|
||||||
|
DeviceHandle::Scsi(_) => {
|
||||||
|
conn_copy
|
||||||
|
.object_server()
|
||||||
|
.remove::<ScsiZbus, _>(&path)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if action == "add" {
|
||||||
|
let evdev = event.device();
|
||||||
|
if let Some(serial) = evdev.property_value("ID_SERIAL_SHORT") {
|
||||||
|
let serial = serial.to_string_lossy().to_string();
|
||||||
|
let path = dbus_path_for_scsi(&serial);
|
||||||
|
if let Some(new_devs) =
|
||||||
|
Self::init_scsi(&conn_copy, &evdev, path).await
|
||||||
|
{
|
||||||
|
devices.lock().await.append(&mut vec![new_devs]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if subsys == "hidraw" {
|
||||||
if let Some(parent) =
|
if let Some(parent) =
|
||||||
event.parent_with_subsystem_devtype("usb", "usb_device")?
|
event.parent_with_subsystem_devtype("usb", "usb_device")?
|
||||||
{
|
{
|
||||||
let devices = devices.clone();
|
|
||||||
|
|
||||||
if action == "remove" {
|
if action == "remove" {
|
||||||
if let Some(path) = dbus_path_for_dev(&parent) {
|
if let Some(path) = dbus_path_for_dev(&parent) {
|
||||||
let conn_copy = conn_copy.clone();
|
|
||||||
tokio::spawn(async move {
|
|
||||||
// Find the indexs of devices matching the path
|
// Find the indexs of devices matching the path
|
||||||
let removals: Vec<usize> = devices
|
let removals: Vec<usize> = devices
|
||||||
.lock()
|
.lock()
|
||||||
@@ -333,31 +474,34 @@ impl DeviceManager {
|
|||||||
.remove::<AniMeZbus, _>(&path)
|
.remove::<AniMeZbus, _>(&path)
|
||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
DeviceHandle::Ally(_) => todo!(),
|
DeviceHandle::Scsi(_) => {
|
||||||
DeviceHandle::OldAura(_) => todo!(),
|
conn_copy
|
||||||
DeviceHandle::TufLedClass(_) => todo!(),
|
.object_server()
|
||||||
DeviceHandle::MulticolourLed => todo!(),
|
.remove::<ScsiZbus, _>(&path)
|
||||||
DeviceHandle::None => todo!(),
|
.await?
|
||||||
|
}
|
||||||
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
info!("AuraManager removed: {path:?}, {res}");
|
info!("AuraManager removed: {path:?}, {res}");
|
||||||
}
|
}
|
||||||
Ok::<(), RogError>(())
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else if action == "add" {
|
} else if action == "add" {
|
||||||
let evdev = event.device();
|
let evdev = event.device();
|
||||||
let conn_copy = conn_copy.clone();
|
if let Ok(mut new_devs) =
|
||||||
block_on(async move {
|
Self::init_hid_devices(&conn_copy, evdev)
|
||||||
if let Ok(mut new_devs) = Self::init_hid_devices(&conn_copy, evdev)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|e| error!("Couldn't add new device: {e:?}"))
|
.map_err(|e| error!("Couldn't add new device: {e:?}"))
|
||||||
{
|
{
|
||||||
devices.lock().await.append(&mut new_devs);
|
devices.lock().await.append(&mut new_devs);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok::<(), RogError>(())
|
||||||
|
})
|
||||||
|
.map_err(|e| error!("{e:?}"))
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Required for return type on spawn
|
// Required for return type on spawn
|
||||||
#[allow(unreachable_code)]
|
#[allow(unreachable_code)]
|
||||||
|
|||||||
114
asusd/src/aura_scsi/config.rs
Normal file
114
asusd/src/aura_scsi/config.rs
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
|
use rog_aura::AuraDeviceType;
|
||||||
|
use rog_scsi::{AuraEffect, AuraMode};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
const CONFIG_FILE: &str = "scsi.ron";
|
||||||
|
|
||||||
|
/// Config for base system actions for the anime display
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct ScsiConfig {
|
||||||
|
#[serde(skip)]
|
||||||
|
pub dev_type: AuraDeviceType,
|
||||||
|
pub enabled: bool,
|
||||||
|
pub current_mode: AuraMode,
|
||||||
|
pub modes: BTreeMap<AuraMode, AuraEffect>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ScsiConfig {
|
||||||
|
pub fn get_effect(&mut self, mode: AuraMode) -> Option<&AuraEffect> {
|
||||||
|
self.modes.get(&mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save_effect(&mut self, effect: AuraEffect) {
|
||||||
|
self.current_mode = effect.mode;
|
||||||
|
self.modes.insert(*effect.mode(), effect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ScsiConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
ScsiConfig {
|
||||||
|
enabled: true,
|
||||||
|
current_mode: AuraMode::Static,
|
||||||
|
dev_type: AuraDeviceType::ScsiExtDisk,
|
||||||
|
modes: BTreeMap::from([
|
||||||
|
(AuraMode::Off, AuraEffect::default_with_mode(AuraMode::Off)),
|
||||||
|
(
|
||||||
|
AuraMode::Static,
|
||||||
|
AuraEffect::default_with_mode(AuraMode::Static),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
AuraMode::Breathe,
|
||||||
|
AuraEffect::default_with_mode(AuraMode::Breathe),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
AuraMode::Flashing,
|
||||||
|
AuraEffect::default_with_mode(AuraMode::Flashing),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
AuraMode::RainbowCycle,
|
||||||
|
AuraEffect::default_with_mode(AuraMode::RainbowCycle),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
AuraMode::RainbowWave,
|
||||||
|
AuraEffect::default_with_mode(AuraMode::RainbowWave),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
AuraMode::RainbowCycleBreathe,
|
||||||
|
AuraEffect::default_with_mode(AuraMode::RainbowCycleBreathe),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
AuraMode::ChaseFade,
|
||||||
|
AuraEffect::default_with_mode(AuraMode::ChaseFade),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
AuraMode::RainbowCycleChaseFade,
|
||||||
|
AuraEffect::default_with_mode(AuraMode::RainbowCycleChaseFade),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
AuraMode::Chase,
|
||||||
|
AuraEffect::default_with_mode(AuraMode::Chase),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
AuraMode::RainbowCycleChase,
|
||||||
|
AuraEffect::default_with_mode(AuraMode::RainbowCycleChase),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
AuraMode::RainbowCycleWave,
|
||||||
|
AuraEffect::default_with_mode(AuraMode::RainbowCycleWave),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
AuraMode::RainbowPulseChase,
|
||||||
|
AuraEffect::default_with_mode(AuraMode::RainbowPulseChase),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
AuraMode::RandomFlicker,
|
||||||
|
AuraEffect::default_with_mode(AuraMode::RandomFlicker),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
AuraMode::DoubleFade,
|
||||||
|
AuraEffect::default_with_mode(AuraMode::DoubleFade),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StdConfig for ScsiConfig {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn file_name(&self) -> String {
|
||||||
|
CONFIG_FILE.to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn config_dir() -> std::path::PathBuf {
|
||||||
|
std::path::PathBuf::from(crate::CONFIG_PATH_BASE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StdConfigLoad for ScsiConfig {}
|
||||||
45
asusd/src/aura_scsi/mod.rs
Normal file
45
asusd/src/aura_scsi/mod.rs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use config::ScsiConfig;
|
||||||
|
use rog_scsi::{AuraEffect, Device, Task};
|
||||||
|
use tokio::sync::{Mutex, MutexGuard};
|
||||||
|
|
||||||
|
use crate::error::RogError;
|
||||||
|
|
||||||
|
pub mod config;
|
||||||
|
pub mod trait_impls;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ScsiAura {
|
||||||
|
device: Arc<Mutex<Device>>,
|
||||||
|
config: Arc<Mutex<ScsiConfig>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ScsiAura {
|
||||||
|
pub fn new(device: Arc<Mutex<Device>>, config: Arc<Mutex<ScsiConfig>>) -> Self {
|
||||||
|
Self { device, config }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn lock_config(&self) -> MutexGuard<ScsiConfig> {
|
||||||
|
self.config.lock().await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn write_effect(&self, effect: &AuraEffect) -> Result<(), RogError> {
|
||||||
|
let tasks: Vec<Task> = effect.into();
|
||||||
|
for task in &tasks {
|
||||||
|
self.device.lock().await.perform(task).ok();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initialise the device if required. Locks the internal config so be wary
|
||||||
|
/// of deadlocks.
|
||||||
|
pub async fn do_initialization(&self) -> Result<(), RogError> {
|
||||||
|
let config = self.config.lock().await;
|
||||||
|
let mode = config.current_mode;
|
||||||
|
if let Some(effect) = config.modes.get(&mode) {
|
||||||
|
self.write_effect(effect).await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
116
asusd/src/aura_scsi/trait_impls.rs
Normal file
116
asusd/src/aura_scsi/trait_impls.rs
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use config_traits::StdConfig;
|
||||||
|
use log::error;
|
||||||
|
use rog_aura::AuraDeviceType;
|
||||||
|
use rog_scsi::{AuraEffect, AuraMode};
|
||||||
|
use zbus::fdo::Error as ZbErr;
|
||||||
|
use zbus::zvariant::OwnedObjectPath;
|
||||||
|
use zbus::{interface, Connection};
|
||||||
|
|
||||||
|
use super::ScsiAura;
|
||||||
|
use crate::error::RogError;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ScsiZbus(ScsiAura);
|
||||||
|
|
||||||
|
impl ScsiZbus {
|
||||||
|
pub fn new(scsi: ScsiAura) -> Self {
|
||||||
|
Self(scsi)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn start_tasks(
|
||||||
|
self,
|
||||||
|
connection: &Connection,
|
||||||
|
path: OwnedObjectPath,
|
||||||
|
) -> Result<(), RogError> {
|
||||||
|
connection
|
||||||
|
.object_server()
|
||||||
|
.at(path.clone(), self)
|
||||||
|
.await
|
||||||
|
.map_err(|e| error!("Couldn't add server at path: {path}, {e:?}"))
|
||||||
|
.ok();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[interface(name = "org.asuslinux.ScsiAura")]
|
||||||
|
impl ScsiZbus {
|
||||||
|
/// Return the device type for this Aura keyboard
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn device_type(&self) -> AuraDeviceType {
|
||||||
|
self.0.config.lock().await.dev_type
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get enabled or not
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn enabled(&self) -> bool {
|
||||||
|
let lock = self.0.lock_config().await;
|
||||||
|
lock.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set enabled true or false
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_enabled(&self, enabled: bool) {
|
||||||
|
let mut config = self.0.lock_config().await;
|
||||||
|
config.enabled = enabled;
|
||||||
|
config.write();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn led_mode(&self) -> u8 {
|
||||||
|
let config = self.0.lock_config().await;
|
||||||
|
config.current_mode as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_led_mode(&self, mode: AuraMode) -> Result<(), zbus::Error> {
|
||||||
|
let mut config = self.0.lock_config().await;
|
||||||
|
if let Some(effect) = config.get_effect(mode) {
|
||||||
|
self.0
|
||||||
|
.write_effect(effect)
|
||||||
|
.await
|
||||||
|
.map_err(|e| zbus::Error::Failure(format!("{e:?}")))?;
|
||||||
|
} else {
|
||||||
|
return Err(zbus::Error::Failure("Mode data does not exist".to_string()));
|
||||||
|
}
|
||||||
|
config.current_mode = mode;
|
||||||
|
config.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The current mode data
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
|
||||||
|
// entirely possible to deadlock here, so use try instead of lock()
|
||||||
|
if let Ok(config) = self.0.config.try_lock() {
|
||||||
|
let mode = config.current_mode;
|
||||||
|
match config.modes.get(&mode) {
|
||||||
|
Some(effect) => Ok(effect.clone()),
|
||||||
|
None => Err(ZbErr::Failed("Could not get the current effect".into())),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(ZbErr::Failed("Aura control couldn't lock self".to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set an Aura effect if the effect mode or zone is supported.
|
||||||
|
///
|
||||||
|
/// On success the aura config file is read to refresh cached values, then
|
||||||
|
/// the effect is stored and config written to disk.
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_led_mode_data(&mut self, effect: AuraEffect) -> Result<(), ZbErr> {
|
||||||
|
self.0.write_effect(&effect).await?;
|
||||||
|
|
||||||
|
let mut config = self.0.config.lock().await;
|
||||||
|
config.save_effect(effect);
|
||||||
|
config.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the data set for every mode available
|
||||||
|
async fn all_mode_data(&self) -> BTreeMap<AuraMode, AuraEffect> {
|
||||||
|
let config = self.0.config.lock().await;
|
||||||
|
config.modes.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ use rog_aura::AuraDeviceType;
|
|||||||
use rog_platform::hid_raw::HidRaw;
|
use rog_platform::hid_raw::HidRaw;
|
||||||
use rog_platform::keyboard_led::KeyboardBacklight;
|
use rog_platform::keyboard_led::KeyboardBacklight;
|
||||||
use rog_platform::usb_raw::USBRaw;
|
use rog_platform::usb_raw::USBRaw;
|
||||||
|
use rog_scsi::{open_device, ScsiType};
|
||||||
use rog_slash::error::SlashError;
|
use rog_slash::error::SlashError;
|
||||||
use rog_slash::SlashType;
|
use rog_slash::SlashType;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
@@ -17,6 +18,8 @@ use crate::aura_anime::config::AniMeConfig;
|
|||||||
use crate::aura_anime::AniMe;
|
use crate::aura_anime::AniMe;
|
||||||
use crate::aura_laptop::config::AuraConfig;
|
use crate::aura_laptop::config::AuraConfig;
|
||||||
use crate::aura_laptop::Aura;
|
use crate::aura_laptop::Aura;
|
||||||
|
use crate::aura_scsi::config::ScsiConfig;
|
||||||
|
use crate::aura_scsi::ScsiAura;
|
||||||
use crate::aura_slash::config::SlashConfig;
|
use crate::aura_slash::config::SlashConfig;
|
||||||
use crate::aura_slash::Slash;
|
use crate::aura_slash::Slash;
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
@@ -31,12 +34,13 @@ pub enum _DeviceHandle {
|
|||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Clone)]
|
||||||
pub enum DeviceHandle {
|
pub enum DeviceHandle {
|
||||||
Aura(Aura),
|
Aura(Aura),
|
||||||
Slash(Slash),
|
Slash(Slash),
|
||||||
/// The AniMe devices require USBRaw as they are not HID devices
|
/// The AniMe devices require USBRaw as they are not HID devices
|
||||||
AniMe(AniMe),
|
AniMe(AniMe),
|
||||||
|
Scsi(ScsiAura),
|
||||||
Ally(Arc<Mutex<HidRaw>>),
|
Ally(Arc<Mutex<HidRaw>>),
|
||||||
OldAura(Arc<Mutex<HidRaw>>),
|
OldAura(Arc<Mutex<HidRaw>>),
|
||||||
/// TUF laptops have an aditional set of attributes added to the LED /sysfs/
|
/// TUF laptops have an aditional set of attributes added to the LED /sysfs/
|
||||||
@@ -146,6 +150,23 @@ impl DeviceHandle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn maybe_scsi(dev_node: &str, prod_id: &str) -> Result<Self, RogError> {
|
||||||
|
debug!("Testing for SCSI");
|
||||||
|
let prod_id = ScsiType::from(prod_id);
|
||||||
|
if prod_id == ScsiType::Unsupported {
|
||||||
|
log::info!("Unknown or invalid SCSI: {prod_id:?}, skipping");
|
||||||
|
return Err(RogError::NotFound("No SCSI device".to_string()));
|
||||||
|
}
|
||||||
|
info!("Found SCSI device {prod_id:?} on {dev_node}");
|
||||||
|
|
||||||
|
let mut config = ScsiConfig::new().load();
|
||||||
|
config.dev_type = AuraDeviceType::ScsiExtDisk;
|
||||||
|
let dev = Arc::new(Mutex::new(open_device(dev_node)?));
|
||||||
|
let scsi = ScsiAura::new(dev, Arc::new(Mutex::new(config)));
|
||||||
|
scsi.do_initialization().await?;
|
||||||
|
Ok(Self::Scsi(scsi))
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn maybe_laptop_aura(
|
pub async fn maybe_laptop_aura(
|
||||||
device: Arc<Mutex<HidRaw>>,
|
device: Arc<Mutex<HidRaw>>,
|
||||||
prod_id: &str,
|
prod_id: &str,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ pub mod ctrl_platform;
|
|||||||
pub mod aura_anime;
|
pub mod aura_anime;
|
||||||
pub mod aura_laptop;
|
pub mod aura_laptop;
|
||||||
pub mod aura_manager;
|
pub mod aura_manager;
|
||||||
|
pub mod aura_scsi;
|
||||||
pub mod aura_slash;
|
pub mod aura_slash;
|
||||||
pub mod aura_types;
|
pub mod aura_types;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|||||||
@@ -494,56 +494,6 @@ impl Display for AuraEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AuraParameters {
|
|
||||||
pub zone: bool,
|
|
||||||
pub colour1: bool,
|
|
||||||
pub colour2: bool,
|
|
||||||
pub speed: bool,
|
|
||||||
pub direction: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::fn_params_excessive_bools)]
|
|
||||||
impl AuraParameters {
|
|
||||||
pub const fn new(
|
|
||||||
zone: bool,
|
|
||||||
colour1: bool,
|
|
||||||
colour2: bool,
|
|
||||||
speed: bool,
|
|
||||||
direction: bool,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
zone,
|
|
||||||
colour1,
|
|
||||||
colour2,
|
|
||||||
speed,
|
|
||||||
direction,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AuraEffect {
|
|
||||||
/// A helper to provide detail on what effects have which parameters, e.g
|
|
||||||
/// the static factory mode accepts only one colour.
|
|
||||||
pub const fn allowed_parameters(mode: AuraModeNum) -> AuraParameters {
|
|
||||||
match mode {
|
|
||||||
AuraModeNum::Static
|
|
||||||
| AuraModeNum::Highlight
|
|
||||||
| AuraModeNum::Pulse
|
|
||||||
| AuraModeNum::Comet
|
|
||||||
| AuraModeNum::Flash => AuraParameters::new(true, true, false, false, false),
|
|
||||||
AuraModeNum::Breathe => AuraParameters::new(true, true, true, true, false),
|
|
||||||
AuraModeNum::RainbowCycle | AuraModeNum::Rain => {
|
|
||||||
AuraParameters::new(true, false, false, true, false)
|
|
||||||
}
|
|
||||||
AuraModeNum::RainbowWave => AuraParameters::new(true, false, false, true, true),
|
|
||||||
AuraModeNum::Star => AuraParameters::new(true, true, true, true, true),
|
|
||||||
AuraModeNum::Laser | AuraModeNum::Ripple => {
|
|
||||||
AuraParameters::new(true, true, false, true, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parses `AuraEffect` in to packet data for writing to the USB interface
|
/// Parses `AuraEffect` in to packet data for writing to the USB interface
|
||||||
///
|
///
|
||||||
/// Byte structure where colour is RGB, one byte per R, G, B:
|
/// Byte structure where colour is RGB, one byte per R, G, B:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"POT-Creation-Date: 2024-12-18 23:02+0000\n"
|
"POT-Creation-Date: 2024-12-22 03:56+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ description = "dbus interface methods for asusctl"
|
|||||||
asusd = { path = "../asusd" }
|
asusd = { path = "../asusd" }
|
||||||
rog_anime = { path = "../rog-anime", features = ["dbus"] }
|
rog_anime = { path = "../rog-anime", features = ["dbus"] }
|
||||||
rog_slash = { path = "../rog-slash", features = ["dbus"] }
|
rog_slash = { path = "../rog-slash", features = ["dbus"] }
|
||||||
|
rog_scsi = { path = "../rog-scsi", features = ["dbus"] }
|
||||||
rog_aura = { path = "../rog-aura" }
|
rog_aura = { path = "../rog-aura" }
|
||||||
rog_profiles = { path = "../rog-profiles" }
|
rog_profiles = { path = "../rog-profiles" }
|
||||||
rog_platform = { path = "../rog-platform" }
|
rog_platform = { path = "../rog-platform" }
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
pub use asusd::{DBUS_IFACE, DBUS_NAME, DBUS_PATH};
|
pub use asusd::{DBUS_IFACE, DBUS_NAME, DBUS_PATH};
|
||||||
|
|
||||||
|
pub mod scsi_aura;
|
||||||
pub mod zbus_anime;
|
pub mod zbus_anime;
|
||||||
pub mod zbus_aura;
|
pub mod zbus_aura;
|
||||||
pub mod zbus_fan_curves;
|
pub mod zbus_fan_curves;
|
||||||
|
|||||||
56
rog-dbus/src/scsi_aura.rs
Normal file
56
rog-dbus/src/scsi_aura.rs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
//! # D-Bus interface proxy for: `org.asuslinux.ScsiAura`
|
||||||
|
//!
|
||||||
|
//! This code was generated by `zbus-xmlgen` `5.0.1` from D-Bus introspection
|
||||||
|
//! data. Source: `Interface '/org/asuslinux/M3D0AP048745_scsi' from service
|
||||||
|
//! 'org.asuslinux.Daemon' on system bus`.
|
||||||
|
//!
|
||||||
|
//! You may prefer to adapt it, instead of using it verbatim.
|
||||||
|
//!
|
||||||
|
//! More information can be found in the [Writing a client proxy] section of the
|
||||||
|
//! zbus documentation.
|
||||||
|
//!
|
||||||
|
//! This type implements the [D-Bus standard interfaces],
|
||||||
|
//! (`org.freedesktop.DBus.*`) for which the following zbus API can be used:
|
||||||
|
//!
|
||||||
|
//! * [`zbus::fdo::PeerProxy`]
|
||||||
|
//! * [`zbus::fdo::PropertiesProxy`]
|
||||||
|
//! * [`zbus::fdo::IntrospectableProxy`]
|
||||||
|
//!
|
||||||
|
//! Consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||||
|
//!
|
||||||
|
//! [Writing a client proxy]: https://dbus2.github.io/zbus/client.html
|
||||||
|
//! [D-Bus standard interfaces]: https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces,
|
||||||
|
use rog_scsi::{AuraEffect, AuraMode};
|
||||||
|
use zbus::proxy;
|
||||||
|
#[proxy(
|
||||||
|
interface = "org.asuslinux.ScsiAura",
|
||||||
|
default_service = "org.asuslinux.Daemon",
|
||||||
|
default_path = "/org/asuslinux"
|
||||||
|
)]
|
||||||
|
pub trait ScsiAura {
|
||||||
|
/// AllModeData method
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
fn all_mode_data(&self) -> zbus::Result<std::collections::HashMap<AuraMode, AuraEffect>>;
|
||||||
|
|
||||||
|
/// DeviceType property
|
||||||
|
#[zbus(property)]
|
||||||
|
fn device_type(&self) -> zbus::Result<u32>;
|
||||||
|
|
||||||
|
/// Enabled property
|
||||||
|
#[zbus(property)]
|
||||||
|
fn enabled(&self) -> zbus::Result<bool>;
|
||||||
|
#[zbus(property)]
|
||||||
|
fn set_enabled(&self, value: bool) -> zbus::Result<()>;
|
||||||
|
|
||||||
|
/// LedMode property
|
||||||
|
#[zbus(property)]
|
||||||
|
fn led_mode(&self) -> zbus::Result<u8>;
|
||||||
|
#[zbus(property)]
|
||||||
|
fn set_led_mode(&self, mode: AuraMode) -> zbus::Result<()>;
|
||||||
|
|
||||||
|
/// LedModeData property
|
||||||
|
#[zbus(property)]
|
||||||
|
fn led_mode_data(&self) -> zbus::Result<AuraEffect>;
|
||||||
|
#[zbus(property)]
|
||||||
|
fn set_led_mode_data(&self, effect: AuraEffect) -> zbus::Result<()>;
|
||||||
|
}
|
||||||
29
rog-scsi/Cargo.toml
Normal file
29
rog-scsi/Cargo.toml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
[package]
|
||||||
|
name = "rog_scsi"
|
||||||
|
version.workspace = true
|
||||||
|
rust-version.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
readme.workspace = true
|
||||||
|
authors.workspace = true
|
||||||
|
repository.workspace = true
|
||||||
|
homepage.workspace = true
|
||||||
|
description.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["dbus", "ron"]
|
||||||
|
dbus = ["zbus"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
sg.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
zbus = { workspace = true, optional = true }
|
||||||
|
|
||||||
|
# cli and logging
|
||||||
|
log.workspace = true
|
||||||
|
typeshare.workspace = true
|
||||||
|
|
||||||
|
ron = { version = "*", optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
cargo-husky.workspace = true
|
||||||
398
rog-scsi/src/builtin_modes.rs
Normal file
398
rog-scsi/src/builtin_modes.rs
Normal file
@@ -0,0 +1,398 @@
|
|||||||
|
use std::fmt::Display;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use typeshare::typeshare;
|
||||||
|
#[cfg(feature = "dbus")]
|
||||||
|
use zbus::zvariant::{OwnedValue, Type, Value};
|
||||||
|
|
||||||
|
use crate::error::Error;
|
||||||
|
use crate::scsi::{apply_task, dir_task, mode_task, rgb_task, save_task, speed_task};
|
||||||
|
|
||||||
|
#[typeshare]
|
||||||
|
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Copy, Deserialize, Serialize)]
|
||||||
|
pub struct Colour {
|
||||||
|
pub r: u8,
|
||||||
|
pub g: u8,
|
||||||
|
pub b: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Colour {
|
||||||
|
fn default() -> Self {
|
||||||
|
Colour { r: 166, g: 0, b: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Colour {
|
||||||
|
type Err = Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
if s.len() < 6 {
|
||||||
|
return Err(Error::ParseColour);
|
||||||
|
}
|
||||||
|
let r = u8::from_str_radix(&s[0..2], 16).or(Err(Error::ParseColour))?;
|
||||||
|
let g = u8::from_str_radix(&s[2..4], 16).or(Err(Error::ParseColour))?;
|
||||||
|
let b = u8::from_str_radix(&s[4..6], 16).or(Err(Error::ParseColour))?;
|
||||||
|
Ok(Colour { r, g, b })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&[u8; 3]> for Colour {
|
||||||
|
fn from(c: &[u8; 3]) -> Self {
|
||||||
|
Self {
|
||||||
|
r: c[0],
|
||||||
|
g: c[1],
|
||||||
|
b: c[2],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Colour> for [u8; 3] {
|
||||||
|
fn from(c: Colour) -> Self {
|
||||||
|
[c.r, c.b, c.g]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[typeshare]
|
||||||
|
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "dbus",
|
||||||
|
derive(Type, Value, OwnedValue),
|
||||||
|
zvariant(signature = "u")
|
||||||
|
)]
|
||||||
|
pub enum Direction {
|
||||||
|
#[default]
|
||||||
|
Forward = 0,
|
||||||
|
Reverse = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Direction {
|
||||||
|
type Err = Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let s = s.to_lowercase();
|
||||||
|
match s.as_str() {
|
||||||
|
"forward" => Ok(Direction::Forward),
|
||||||
|
"reverse" => Ok(Direction::Reverse),
|
||||||
|
_ => Err(Error::ParseSpeed),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for Direction {
|
||||||
|
fn from(dir: u8) -> Self {
|
||||||
|
match dir {
|
||||||
|
1 => Direction::Reverse,
|
||||||
|
_ => Direction::Forward,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Direction> for u8 {
|
||||||
|
fn from(d: Direction) -> Self {
|
||||||
|
d as u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[typeshare]
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "dbus",
|
||||||
|
derive(Type, Value, OwnedValue),
|
||||||
|
zvariant(signature = "s")
|
||||||
|
)]
|
||||||
|
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
|
pub enum Speed {
|
||||||
|
Slowest = 4,
|
||||||
|
Slow = 3,
|
||||||
|
#[default]
|
||||||
|
Med = 2,
|
||||||
|
Fast = 1,
|
||||||
|
Fastest = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Speed {
|
||||||
|
type Err = Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let s = s.to_lowercase();
|
||||||
|
match s.as_str() {
|
||||||
|
"slowest" => Ok(Speed::Slowest),
|
||||||
|
"slow" => Ok(Speed::Slow),
|
||||||
|
"med" => Ok(Speed::Med),
|
||||||
|
"fast" => Ok(Speed::Fast),
|
||||||
|
"fastest" => Ok(Speed::Fastest),
|
||||||
|
_ => Err(Error::ParseSpeed),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Speed> for u8 {
|
||||||
|
fn from(s: Speed) -> u8 {
|
||||||
|
match s {
|
||||||
|
Speed::Slowest => 4,
|
||||||
|
Speed::Slow => 3,
|
||||||
|
Speed::Med => 2,
|
||||||
|
Speed::Fast => 1,
|
||||||
|
Speed::Fastest => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for Speed {
|
||||||
|
fn from(value: u8) -> Self {
|
||||||
|
match value {
|
||||||
|
4 => Self::Slowest,
|
||||||
|
3 => Self::Slow,
|
||||||
|
1 => Self::Fast,
|
||||||
|
0 => Self::Fastest,
|
||||||
|
_ => Self::Med,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enum of modes that convert to the actual number required by a USB HID packet
|
||||||
|
#[typeshare]
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "dbus",
|
||||||
|
derive(Type, Value, OwnedValue),
|
||||||
|
zvariant(signature = "u")
|
||||||
|
)]
|
||||||
|
#[derive(
|
||||||
|
Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Deserialize, Serialize,
|
||||||
|
)]
|
||||||
|
pub enum AuraMode {
|
||||||
|
Off = 0,
|
||||||
|
#[default]
|
||||||
|
Static = 1,
|
||||||
|
Breathe = 2,
|
||||||
|
Flashing = 3,
|
||||||
|
RainbowCycle = 4,
|
||||||
|
RainbowWave = 5,
|
||||||
|
RainbowCycleBreathe = 6,
|
||||||
|
ChaseFade = 7,
|
||||||
|
RainbowCycleChaseFade = 8,
|
||||||
|
Chase = 9,
|
||||||
|
RainbowCycleChase = 10,
|
||||||
|
RainbowCycleWave = 11,
|
||||||
|
RainbowPulseChase = 12,
|
||||||
|
RandomFlicker = 13,
|
||||||
|
DoubleFade = 14,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuraMode {
|
||||||
|
pub fn list() -> [String; 15] {
|
||||||
|
[
|
||||||
|
AuraMode::Off.to_string(),
|
||||||
|
AuraMode::Static.to_string(),
|
||||||
|
AuraMode::Breathe.to_string(),
|
||||||
|
AuraMode::Flashing.to_string(),
|
||||||
|
AuraMode::RainbowCycle.to_string(),
|
||||||
|
AuraMode::RainbowWave.to_string(),
|
||||||
|
AuraMode::RainbowCycleBreathe.to_string(),
|
||||||
|
AuraMode::ChaseFade.to_string(),
|
||||||
|
AuraMode::RainbowCycleChaseFade.to_string(),
|
||||||
|
AuraMode::Chase.to_string(),
|
||||||
|
AuraMode::RainbowCycleChase.to_string(),
|
||||||
|
AuraMode::RainbowCycleWave.to_string(),
|
||||||
|
AuraMode::RainbowPulseChase.to_string(),
|
||||||
|
AuraMode::RandomFlicker.to_string(),
|
||||||
|
AuraMode::DoubleFade.to_string(),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for AuraMode {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", <&str>::from(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AuraMode> for String {
|
||||||
|
fn from(mode: AuraMode) -> Self {
|
||||||
|
<&str>::from(&mode).to_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&AuraMode> for &str {
|
||||||
|
fn from(mode: &AuraMode) -> Self {
|
||||||
|
match mode {
|
||||||
|
AuraMode::Off => "Off",
|
||||||
|
AuraMode::Static => "Static",
|
||||||
|
AuraMode::Breathe => "Breathe",
|
||||||
|
AuraMode::RainbowCycle => "RainbowCycle",
|
||||||
|
AuraMode::RainbowWave => "RainbowWave",
|
||||||
|
AuraMode::Flashing => "Flashing",
|
||||||
|
AuraMode::RainbowCycleBreathe => "RainbowCycleBreathe",
|
||||||
|
AuraMode::ChaseFade => "ChaseFade",
|
||||||
|
AuraMode::RainbowCycleChaseFade => "RainbowCycleChaseFade",
|
||||||
|
AuraMode::Chase => "Chase",
|
||||||
|
AuraMode::RainbowCycleChase => "RainbowCycleChase",
|
||||||
|
AuraMode::RainbowCycleWave => "RainbowCycleWave",
|
||||||
|
AuraMode::RainbowPulseChase => "RainbowPulseChase",
|
||||||
|
AuraMode::RandomFlicker => "RandomFlicker",
|
||||||
|
AuraMode::DoubleFade => "DoubleFade",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for AuraMode {
|
||||||
|
type Err = Error;
|
||||||
|
|
||||||
|
fn from_str(mode: &str) -> Result<Self, Self::Err> {
|
||||||
|
match mode {
|
||||||
|
"Off" => Ok(Self::Off),
|
||||||
|
"Static" => Ok(Self::Static),
|
||||||
|
"Breathe" => Ok(Self::Breathe),
|
||||||
|
"RainbowCycle" => Ok(Self::RainbowCycle),
|
||||||
|
"RainbowWave" => Ok(Self::RainbowWave),
|
||||||
|
"Flashing" => Ok(Self::Flashing),
|
||||||
|
"RainbowCycleBreathe" => Ok(Self::RainbowCycleBreathe),
|
||||||
|
"ChaseFade" => Ok(Self::ChaseFade),
|
||||||
|
"RainbowCycleChaseFade" => Ok(Self::RainbowCycleChaseFade),
|
||||||
|
"Chase" => Ok(Self::Chase),
|
||||||
|
"RainbowCycleChase" => Ok(Self::RainbowCycleChase),
|
||||||
|
"RainbowCycleWave" => Ok(Self::RainbowCycleWave),
|
||||||
|
"RainbowPulseChase" => Ok(Self::RainbowPulseChase),
|
||||||
|
"RandomFlicker" => Ok(Self::RandomFlicker),
|
||||||
|
"DoubleFade" => Ok(Self::DoubleFade),
|
||||||
|
_ => Err(Error::ParseMode),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for AuraMode {
|
||||||
|
fn from(mode: &str) -> Self {
|
||||||
|
AuraMode::from_str(mode).unwrap_or_default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for AuraMode {
|
||||||
|
fn from(mode: u8) -> Self {
|
||||||
|
match mode {
|
||||||
|
0 => Self::Off,
|
||||||
|
1 => Self::Static,
|
||||||
|
2 => Self::Breathe,
|
||||||
|
3 => Self::Flashing,
|
||||||
|
4 => Self::RainbowCycle,
|
||||||
|
5 => Self::RainbowWave,
|
||||||
|
6 => Self::RainbowCycleBreathe,
|
||||||
|
7 => Self::ChaseFade,
|
||||||
|
8 => Self::RainbowCycleChaseFade,
|
||||||
|
9 => Self::Chase,
|
||||||
|
10 => Self::RainbowCycleChase,
|
||||||
|
11 => Self::RainbowCycleWave,
|
||||||
|
12 => Self::RainbowPulseChase,
|
||||||
|
13 => Self::RandomFlicker,
|
||||||
|
14 => Self::DoubleFade,
|
||||||
|
_ => Self::Static,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AuraEffect> for AuraMode {
|
||||||
|
fn from(value: AuraEffect) -> Self {
|
||||||
|
value.mode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Default factory modes structure.
|
||||||
|
#[typeshare]
|
||||||
|
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
|
||||||
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||||
|
pub struct AuraEffect {
|
||||||
|
/// The effect type
|
||||||
|
pub mode: AuraMode,
|
||||||
|
/// One of three speeds for modes that support speed (most that animate)
|
||||||
|
pub speed: Speed,
|
||||||
|
/// Up, down, left, right. Only Rainbow mode seems to use this
|
||||||
|
pub direction: Direction,
|
||||||
|
/// Primary colour for all modes
|
||||||
|
pub colour1: Colour,
|
||||||
|
/// Secondary colour in some modes like Breathing or Stars
|
||||||
|
pub colour2: Colour,
|
||||||
|
pub colour3: Colour,
|
||||||
|
pub colour4: Colour,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuraEffect {
|
||||||
|
pub fn mode(&self) -> &AuraMode {
|
||||||
|
&self.mode
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mode_name(&self) -> &str {
|
||||||
|
<&str>::from(&self.mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mode_num(&self) -> u8 {
|
||||||
|
self.mode as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_with_mode(mode: AuraMode) -> Self {
|
||||||
|
Self {
|
||||||
|
mode,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for AuraEffect {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
mode: AuraMode::Static,
|
||||||
|
colour1: Colour { r: 166, g: 0, b: 0 },
|
||||||
|
colour2: Colour { r: 0, g: 0, b: 0 },
|
||||||
|
colour3: Colour { r: 166, g: 0, b: 0 },
|
||||||
|
colour4: Colour { r: 0, g: 0, b: 0 },
|
||||||
|
speed: Speed::Med,
|
||||||
|
direction: Direction::Forward,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for AuraEffect {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
writeln!(f, "AuraEffect {{")?;
|
||||||
|
writeln!(f, " mode: {}", self.mode())?;
|
||||||
|
writeln!(f, " speed: {:?}", self.speed)?;
|
||||||
|
writeln!(f, " direction: {:?}", self.direction)?;
|
||||||
|
writeln!(f, " colour1: {:?}", self.colour1)?;
|
||||||
|
writeln!(f, " colour2: {:?}", self.colour2)?;
|
||||||
|
writeln!(f, " colour3: {:?}", self.colour3)?;
|
||||||
|
writeln!(f, " colour4: {:?}", self.colour4)?;
|
||||||
|
writeln!(f, "}}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&AuraEffect> for Vec<sg::Task> {
|
||||||
|
fn from(effect: &AuraEffect) -> Self {
|
||||||
|
let mut tasks = Vec::new();
|
||||||
|
|
||||||
|
tasks.append(&mut vec![
|
||||||
|
mode_task(effect.mode as u8),
|
||||||
|
rgb_task(0, &effect.colour1.into()),
|
||||||
|
rgb_task(1, &effect.colour2.into()),
|
||||||
|
rgb_task(2, &effect.colour3.into()),
|
||||||
|
rgb_task(3, &effect.colour4.into()),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if !matches!(effect.mode, AuraMode::Static | AuraMode::Off) {
|
||||||
|
tasks.push(speed_task(effect.speed as u8));
|
||||||
|
}
|
||||||
|
if matches!(
|
||||||
|
effect.mode,
|
||||||
|
AuraMode::RainbowWave
|
||||||
|
| AuraMode::ChaseFade
|
||||||
|
| AuraMode::RainbowCycleChaseFade
|
||||||
|
| AuraMode::Chase
|
||||||
|
| AuraMode::RainbowCycleChase
|
||||||
|
| AuraMode::RainbowCycleWave
|
||||||
|
| AuraMode::RainbowPulseChase
|
||||||
|
) {
|
||||||
|
tasks.push(dir_task(effect.direction as u8));
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.append(&mut vec![apply_task(), save_task()]);
|
||||||
|
tasks
|
||||||
|
}
|
||||||
|
}
|
||||||
41
rog-scsi/src/error.rs
Normal file
41
rog-scsi/src/error.rs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
use std::{error, fmt};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
ParseMode,
|
||||||
|
ParseColour,
|
||||||
|
ParseSpeed,
|
||||||
|
ParseDirection,
|
||||||
|
IoPath(String, std::io::Error),
|
||||||
|
Ron(ron::Error),
|
||||||
|
RonParse(ron::error::SpannedError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
// This trait requires `fmt` with this exact signature.
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Error::ParseColour => write!(f, "Could not parse colour"),
|
||||||
|
Error::ParseSpeed => write!(f, "Could not parse speed"),
|
||||||
|
Error::ParseDirection => write!(f, "Could not parse direction"),
|
||||||
|
Error::ParseMode => write!(f, "Could not parse mode"),
|
||||||
|
Error::IoPath(path, io) => write!(f, "IO Error: {path}, {io}"),
|
||||||
|
Error::Ron(e) => write!(f, "RON Parse Error: {e}"),
|
||||||
|
Error::RonParse(e) => write!(f, "RON Parse Error: {e}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl error::Error for Error {}
|
||||||
|
|
||||||
|
impl From<ron::Error> for Error {
|
||||||
|
fn from(e: ron::Error) -> Self {
|
||||||
|
Self::Ron(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ron::error::SpannedError> for Error {
|
||||||
|
fn from(e: ron::error::SpannedError) -> Self {
|
||||||
|
Self::RonParse(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
48
rog-scsi/src/lib.rs
Normal file
48
rog-scsi/src/lib.rs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
mod builtin_modes;
|
||||||
|
mod error;
|
||||||
|
mod scsi;
|
||||||
|
|
||||||
|
pub use builtin_modes::*;
|
||||||
|
pub use error::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
pub use sg::{Device, Task};
|
||||||
|
|
||||||
|
pub const PROD_SCSI_ARION: &str = "1932";
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
|
pub enum ScsiType {
|
||||||
|
Arion,
|
||||||
|
#[default]
|
||||||
|
Unsupported,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ScsiType {
|
||||||
|
pub const fn prod_id_str(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
ScsiType::Arion => PROD_SCSI_ARION,
|
||||||
|
ScsiType::Unsupported => "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for ScsiType {
|
||||||
|
fn from(s: &str) -> Self {
|
||||||
|
match s.to_lowercase().as_str() {
|
||||||
|
PROD_SCSI_ARION | "0x1932" => Self::Arion,
|
||||||
|
_ => Self::Unsupported,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ScsiType> for &str {
|
||||||
|
fn from(s: ScsiType) -> Self {
|
||||||
|
match s {
|
||||||
|
ScsiType::Arion => PROD_SCSI_ARION,
|
||||||
|
ScsiType::Unsupported => "Unsupported",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn open_device(path: &str) -> Result<Device, std::io::Error> {
|
||||||
|
Device::open(path)
|
||||||
|
}
|
||||||
80
rog-scsi/src/scsi.rs
Normal file
80
rog-scsi/src/scsi.rs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
extern crate sg;
|
||||||
|
|
||||||
|
pub use sg::Task;
|
||||||
|
|
||||||
|
static ENE_APPLY_VAL: u8 = 0x01; // Value for Apply Changes Register
|
||||||
|
static ENE_SAVE_VAL: u8 = 0xaa;
|
||||||
|
|
||||||
|
static ENE_REG_MODE: u32 = 0x8021; // Mode Selection Register
|
||||||
|
static ENE_REG_SPEED: u32 = 0x8022; // Speed Control Register
|
||||||
|
static ENE_REG_DIRECTION: u32 = 0x8023; // Direction Control Register
|
||||||
|
|
||||||
|
static ENE_REG_APPLY: u32 = 0x80a0;
|
||||||
|
static _ENE_REG_COLORS_DIRECT_V2: u32 = 0x8100; // to read the colurs
|
||||||
|
static ENE_REG_COLORS_EFFECT_V2: u32 = 0x8160;
|
||||||
|
|
||||||
|
fn data(reg: u32, arg_count: u8) -> [u8; 16] {
|
||||||
|
let mut cdb = [0u8; 16];
|
||||||
|
cdb[0] = 0xec;
|
||||||
|
cdb[1] = 0x41;
|
||||||
|
cdb[2] = 0x53;
|
||||||
|
cdb[3] = ((reg >> 8) & 0x00ff) as u8;
|
||||||
|
cdb[4] = (reg & 0x00ff) as u8;
|
||||||
|
cdb[5] = 0x00;
|
||||||
|
cdb[6] = 0x00;
|
||||||
|
cdb[7] = 0x00;
|
||||||
|
cdb[8] = 0x00;
|
||||||
|
cdb[9] = 0x00;
|
||||||
|
cdb[10] = 0x00;
|
||||||
|
cdb[11] = 0x00;
|
||||||
|
cdb[12] = 0x00;
|
||||||
|
cdb[13] = arg_count; // how many u8 in data packet
|
||||||
|
cdb[14] = 0x00;
|
||||||
|
cdb[15] = 0x00;
|
||||||
|
cdb
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn rgb_task(led: u32, rgb: &[u8; 3]) -> Task {
|
||||||
|
let mut task = Task::new();
|
||||||
|
task.set_cdb(data(led * 3 + ENE_REG_COLORS_EFFECT_V2, 3).as_slice());
|
||||||
|
task.set_data(rgb, sg::Direction::ToDevice);
|
||||||
|
task
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 0-13
|
||||||
|
pub(crate) fn mode_task(mode: u8) -> Task {
|
||||||
|
let mut task = Task::new();
|
||||||
|
task.set_cdb(data(ENE_REG_MODE, 1).as_slice());
|
||||||
|
task.set_data(&[mode.min(13)], sg::Direction::ToDevice);
|
||||||
|
task
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 0-4, fast to slow
|
||||||
|
pub(crate) fn speed_task(speed: u8) -> Task {
|
||||||
|
let mut task = Task::new();
|
||||||
|
task.set_cdb(data(ENE_REG_SPEED, 1).as_slice());
|
||||||
|
task.set_data(&[speed.min(4)], sg::Direction::ToDevice);
|
||||||
|
task
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 0 = forward, 1 = backward
|
||||||
|
pub(crate) fn dir_task(mode: u8) -> Task {
|
||||||
|
let mut task = Task::new();
|
||||||
|
task.set_cdb(data(ENE_REG_DIRECTION, 1).as_slice());
|
||||||
|
task.set_data(&[mode.min(1)], sg::Direction::ToDevice);
|
||||||
|
task
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn apply_task() -> Task {
|
||||||
|
let mut task = Task::new();
|
||||||
|
task.set_cdb(data(ENE_REG_APPLY, 1).as_slice());
|
||||||
|
task.set_data(&[ENE_APPLY_VAL], sg::Direction::ToDevice);
|
||||||
|
task
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn save_task() -> Task {
|
||||||
|
let mut task = Task::new();
|
||||||
|
task.set_cdb(data(ENE_REG_APPLY, 1).as_slice());
|
||||||
|
task.set_data(&[ENE_SAVE_VAL], sg::Direction::ToDevice);
|
||||||
|
task
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user