@@ -222,8 +222,12 @@ final internal class MinimuxerImpl: MinimuxerAPI {
222222 // start our fake usbmuxd server for lockdown protocol based clients if required
223223 try await restartMuxerServer ( )
224224
225- try await matchingPriority {
226- try await Mounter . shared. mount ( docsPath: mountPath)
225+ do {
226+ try await matchingPriority {
227+ try await Mounter . shared. mount ( docsPath: mountPath)
228+ }
229+ } catch {
230+ debugLog ( " [minimuxer] WARN: Initial DDI mount skipped during startup: \( error. localizedDescription) " )
227231 }
228232 // mark ready!
229233 try await state. with {
@@ -300,12 +304,10 @@ final internal class MinimuxerImpl: MinimuxerAPI {
300304 }
301305 }
302306
303- func testDeviceConnection( ifaddr: String ? ) -> Bool {
304- guard let ip = ifaddr else { return false }
305-
307+ private func testTCPPort( ip: String , port: UInt16 ) -> Bool {
306308 var addr = sockaddr_in ( )
307309 addr. sin_family = sa_family_t ( AF_INET)
308- addr. sin_port = isrppairing ? MinimuxerConstants . rsdPort . bigEndian : MinimuxerConstants . lockdowndPort . bigEndian
310+ addr. sin_port = port . bigEndian
309311 inet_pton ( AF_INET, ip, & addr. sin_addr)
310312
311313 let fd = socket ( AF_INET, SOCK_STREAM, 0 )
@@ -326,6 +328,14 @@ final internal class MinimuxerImpl: MinimuxerAPI {
326328 return result > 0 && ( pfd. revents & Int16 ( POLLOUT) ) != 0
327329 }
328330
331+ func testDeviceConnection( ifaddr: String ? ) -> Bool {
332+ guard let ip = ifaddr else { return false }
333+ if testTCPPort ( ip: ip, port: MinimuxerConstants . rsdPort) {
334+ return true
335+ }
336+ return testTCPPort ( ip: ip, port: MinimuxerConstants . lockdowndPort)
337+ }
338+
329339
330340 func yeetAppAfc( bundleId: String , ipaBytes: Data ) async throws {
331341 try await matchingPriority {
@@ -345,13 +355,28 @@ final internal class MinimuxerImpl: MinimuxerAPI {
345355 }
346356 }
347357
358+ private func ensureDDIMounted( ) async throws {
359+ let isMounted = ( try ? await IdeviceGateway . shared. isDDIMounted ( ) ) ?? false
360+ if isMounted {
361+ return
362+ }
363+ guard let mountPath = await state. lastDocsPath else {
364+ let activeProtocol : PairingProtocol = isrppairing ? . rppairing : . lockdown
365+ throw MinimuxerError . mount ( protocol: activeProtocol, reason: " DDI mount path not set " )
366+ }
367+ verboseLog ( " [minimuxer] DDI not mounted, mounting now before launching debug session... " )
368+ _ = try await Mounter . shared. mount ( docsPath: mountPath)
369+ }
370+
348371 func debugApp( appId: String ) async throws {
372+ try await ensureDDIMounted ( )
349373 try await matchingPriority {
350374 try IdeviceGateway . shared. debugApp ( appId: appId)
351375 }
352376 }
353377
354378 func attachDebugger( pid: UInt32 ) async throws {
379+ try await ensureDDIMounted ( )
355380 try await matchingPriority {
356381 try IdeviceGateway . shared. debugProcess ( pid: pid)
357382 }
0 commit comments