From 006a9cdb3759fabfcbfb9fcdefe68484f0249f08 Mon Sep 17 00:00:00 2001 From: Alexander Koz <888526+boozook@users.noreply.github.com> Date: Mon, 13 May 2024 00:07:13 +0400 Subject: [PATCH] Support devices connected via USB-hub on macOs (#358) * Support devices connected via USB-hub on macOs (fixes #326) * Bump bins, update deps --- Cargo.lock | 101 ++++++++++------------------ cargo/Cargo.toml | 2 +- support/device/Cargo.toml | 2 +- support/device/src/mount/mac.rs | 115 +++++++++++++++++++++++++++++--- support/tool/Cargo.toml | 2 +- 5 files changed, 144 insertions(+), 78 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5dbfec5..5b393b22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -335,7 +335,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -352,7 +352,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -488,7 +488,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.61", + "syn 2.0.63", "which 4.4.2", ] @@ -742,7 +742,7 @@ dependencies = [ [[package]] name = "cargo-playdate" -version = "0.4.12" +version = "0.4.13" dependencies = [ "anstyle", "anyhow", @@ -774,7 +774,7 @@ dependencies = [ "toml_edit 0.22.12", "try-lazy-init", "walkdir", - "zip 1.2.1", + "zip 1.2.3", ] [[package]] @@ -909,7 +909,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -951,7 +951,7 @@ dependencies = [ "nom", "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -1296,7 +1296,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -1340,7 +1340,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -1788,7 +1788,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -2242,7 +2242,7 @@ checksum = "1dff438f14e67e7713ab9332f5fd18c8f20eb7eb249494f6c2bf170522224032" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -3132,7 +3132,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -3398,7 +3398,7 @@ checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -3468,7 +3468,7 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -3648,27 +3648,6 @@ dependencies = [ "libc", ] -[[package]] -name = "num_enum" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.61", -] - [[package]] name = "num_threads" version = "0.1.7" @@ -4039,7 +4018,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -4120,7 +4099,7 @@ dependencies = [ "proc-macro2", "quote", "semver", - "syn 2.0.61", + "syn 2.0.63", "which 6.0.1", ] @@ -4176,7 +4155,7 @@ dependencies = [ [[package]] name = "playdate-device" -version = "0.2.9" +version = "0.2.10" dependencies = [ "async-std", "clap", @@ -4325,7 +4304,7 @@ dependencies = [ [[package]] name = "playdate-tool" -version = "0.3.4" +version = "0.3.5" dependencies = [ "clap", "console-subscriber", @@ -4436,7 +4415,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -4448,15 +4427,6 @@ dependencies = [ "elliptic-curve", ] -[[package]] -name = "proc-macro-crate" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" -dependencies = [ - "toml_edit 0.21.1", -] - [[package]] name = "proc-macro2" version = "1.0.82" @@ -4511,7 +4481,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -4810,7 +4780,7 @@ checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -4896,7 +4866,7 @@ checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -5428,9 +5398,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.61" +version = "2.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" dependencies = [ "proc-macro2", "quote", @@ -5520,7 +5490,7 @@ checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -5619,7 +5589,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -5785,7 +5755,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -6068,7 +6038,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", "wasm-bindgen-shared", ] @@ -6102,7 +6072,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6256,7 +6226,7 @@ checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -6267,7 +6237,7 @@ checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -6510,7 +6480,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -6530,7 +6500,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.63", ] [[package]] @@ -6547,9 +6517,9 @@ dependencies = [ [[package]] name = "zip" -version = "1.2.1" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006d078b7b6fc587bb25e022ad39e7086f44e5c4fef6076964ea601533241beb" +checksum = "c700ea425e148de30c29c580c1f9508b93ca57ad31c9f4e96b83c194c37a7a8f" dependencies = [ "aes", "arbitrary", @@ -6563,7 +6533,6 @@ dependencies = [ "hmac", "indexmap 2.2.6", "lzma-rs", - "num_enum", "pbkdf2", "rand", "sha1", diff --git a/cargo/Cargo.toml b/cargo/Cargo.toml index 673c6b28..94ff1d73 100644 --- a/cargo/Cargo.toml +++ b/cargo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargo-playdate" -version = "0.4.12" +version = "0.4.13" readme = "README.md" description = "Build tool for neat yellow console." keywords = ["playdate", "build", "cargo", "plugin", "cargo-subcommand"] diff --git a/support/device/Cargo.toml b/support/device/Cargo.toml index d8bd5100..cba60362 100644 --- a/support/device/Cargo.toml +++ b/support/device/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "playdate-device" -version = "0.2.9" +version = "0.2.10" readme = "README.md" description = "Cross-platform interface Playdate device, async & blocking." keywords = ["playdate", "usb", "serial"] diff --git a/support/device/src/mount/mac.rs b/support/device/src/mount/mac.rs index 4b135bf4..9b2aa38d 100644 --- a/support/device/src/mount/mac.rs +++ b/support/device/src/mount/mac.rs @@ -178,19 +178,26 @@ fn parse_spusb( { let data: SystemProfilerResponse = serde_json::from_slice(data)?; + /// Recursive function that flattens the items. + fn flatten_items(item: AnyDeviceInfo) -> Vec { + match item { + AnyDeviceInfo::Known(info) => vec![info], + AnyDeviceInfo::Hub(info) => { + trace!("Going into items of the hub"); + info.items.into_iter().flatten().flat_map(flatten_items).collect() + }, + AnyDeviceInfo::Other { name, .. } => { + trace!("Skip {name}"); + vec![] + }, + } + } + let result = data.data .into_iter() .filter_map(|c| c.items) .flatten() - .filter_map(|item| { - match item { - AnyDeviceInfo::Known(info) => Some(info), - AnyDeviceInfo::Other { name, .. } => { - trace!("Skip {name}"); - None - }, - } - }) + .flat_map(flatten_items) .filter(|item| item.vendor_id == VENDOR_ID_ENC) .filter(filter) .filter_map(|item| { @@ -285,6 +292,7 @@ struct ControllerInfo { #[serde(untagged)] enum AnyDeviceInfo { Known(DeviceInfo), + Hub(ControllerInfo), Other { #[serde(rename = "_name")] name: String, @@ -465,6 +473,95 @@ mod tests { assert_eq!("/Volumes/PLAYDATE", vol.to_string_lossy()); } + /// Special case with usb-hub: + /// https://github.com/boozook/playdate/issues/326#issuecomment-2105427181 + #[test] + fn parse_spusb_mount_hub() { + let data = r#" + { + "SPUSBDataType": [ + { + "_items": [ + { + "_items": [ + { + "_name": "Playdate", + "bcd_device": "2.00", + "bus_power": "500", + "bus_power_used": "100", + "device_speed": "full_speed", + "extra_current_used": "0", + "location_id": "0x05310000 / 24", + "manufacturer": "Panic Inc", + "Media": [ + { + "_name": "Playdate", + "bsd_name": "disk24", + "Logical Unit": 0, + "partition_map_type": "master_boot_record_partition_map_type", + "removable_media": "yes", + "size": "3.66 GB", + "size_in_bytes": 3662675968, + "smart_status": "Verified", + "USB Interface": 0, + "volumes": [ + { + "_name": "PLAYDATE", + "bsd_name": "disk24s1", + "file_system": "MS-DOS FAT32", + "free_space": "2.13 GB", + "free_space_in_bytes": 2133676032, + "iocontent": "Windows_FAT_32", + "mount_point": "/Volumes/PLAYDATE", + "size": "3.66 GB", + "size_in_bytes": 3662675456, + "volume_uuid": "83B4406D-", + "writable": "yes" + } + ] + } + ], + "product_id": "0x5741", + "serial_num": "PDU1-Y000042", + "vendor_id": "0x1331" + } + ], + "_name": "4-Port USB 2.0 Hub", + "bcd_device": "1.36", + "bus_power": "500", + "bus_power_used": "0", + "device_speed": "high_speed", + "extra_current_used": "0", + "location_id": "0x05300000 / 3", + "manufacturer": "Generic", + "product_id": "0x5411", + "vendor_id": "0x0bda (Realtek Semiconductor Corp.)" + } + ], + "_name": "USB31Bus", + "host_controller": "AppleASMediaUSBXHCI", + "pci_device": "0x1242 ", + "pci_revision": "0x0000 ", + "pci_vendor": "0x1b21 " + } + ] + } + "#; + + let dev = { + let mut devs: Vec<_> = parse_spusb(|_| true, data.as_bytes()).unwrap().collect(); + assert!(!devs.is_empty()); + assert_eq!(1, devs.len()); + devs.pop().unwrap() + }; + + assert_eq!(dev.name, "Playdate"); + assert_eq!(dev.serial, "PDU1-Y000042"); + + let vol = dev.volume.now_or_never().unwrap().unwrap(); + assert_eq!("/Volumes/PLAYDATE", vol.to_string_lossy()); + } + #[test] fn parse_spusb_mount_incomplete() { diff --git a/support/tool/Cargo.toml b/support/tool/Cargo.toml index fac2a0db..efe4b317 100644 --- a/support/tool/Cargo.toml +++ b/support/tool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "playdate-tool" -version = "0.3.4" +version = "0.3.5" readme = "README.md" description = "Tool for interaction with Playdate device and sim." keywords = ["playdate", "usb", "utility"]