Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 36 additions & 5 deletions src/device.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
use std::{sync::atomic::Ordering, time::Duration};
use std::{
sync::{atomic::Ordering, Mutex},
time::Duration,
};

use crate::{muxer::STARTED, Errors, Res};
use log::{error, info};
use log::{error, info, warn};
use once_cell::sync::Lazy;
use rusty_libimobiledevice::idevice::{self, Device};

/// Cached UDID from the pairing file — fallback when C library can't detect device (iOS 26+)
pub static PAIRING_UDID: Lazy<Mutex<Option<String>>> = Lazy::new(|| Mutex::new(None));

/// Called by muxer after parsing the pairing file to cache the UDID
pub fn set_pairing_udid(udid: String) {
if let Ok(mut cache) = PAIRING_UDID.lock() {
*cache = Some(udid);
info!("Cached pairing UDID for fallback");
}
}

#[swift_bridge::bridge]
mod ffi {
#[swift_bridge(already_declared, swift_name = "MinimuxerError")]
Expand All @@ -22,6 +37,10 @@ mod ffi {
/// Returns an error once the timeout expires
///
/// Timeout is 5 seconds, 250 ms sleep between attempts
///
/// On iOS 26+, the C library may fail to detect the device even when the
/// pairing file is valid. This function falls back to constructing a Device
/// from the cached pairing UDID when the C library returns no devices.
pub fn fetch_first_device() -> Res<Device> {
const TIMEOUT: u16 = 5000;
const SLEEP: u16 = 250;
Expand All @@ -30,16 +49,28 @@ pub fn fetch_first_device() -> Res<Device> {
loop {
match idevice::get_first_device() {
Ok(d) => return Ok(d),
Err(e) => {
Err(_e) => {
t -= SLEEP;
if t == 0 {
error!("Couldn't fetch first device: {:?}", e);
return Err(Errors::NoDevice);
break;
}
}
}
std::thread::sleep(Duration::from_millis(SLEEP.into()));
}

// C library failed — try the pairing file UDID fallback (iOS 26 fix)
warn!("C library could not find device, trying pairing file UDID fallback");
if let Ok(cache) = PAIRING_UDID.lock() {
if let Some(ref udid) = *cache {
info!("Using cached pairing UDID: {}", udid);
let ip = Some(std::net::IpAddr::V4(std::net::Ipv4Addr::new(10, 7, 0, 1)));
return Ok(Device::new(udid.clone(), ip, 420));
}
}

error!("No device found via C library or pairing file fallback");
Err(Errors::NoDevice)
}

/// Tests if the device is on and listening without jumping through hoops
Expand Down
9 changes: 7 additions & 2 deletions src/muxer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,9 +335,13 @@ pub fn startWithLogger(
}
};

match pairing_file.get("UDID") {
let udid_str = match pairing_file.get("UDID") {
Some(u) => match u.as_string() {
Some(_) => {}
Some(s) => {
// Cache UDID for iOS 26 fallback
crate::device::set_pairing_udid(s.to_string());
s.to_string()
}
None => {
error!("Couldn't convert UDID to string");
return Err(Errors::PairingFile);
Expand All @@ -349,6 +353,7 @@ pub fn startWithLogger(
}
};

info!("Pairing UDID cached: {}", udid_str);
listen(pairing_file);
start_beat();

Expand Down