void StopNotificationSubscribeThread() { lock (this) { if (_loopingThread != IntPtr.Zero) { USBMuxInterop.CFRunLoopStop(_loopingThread); } } }
void AMDeviceNotificationSubscribeLoop() { IntPtr context = IntPtr.Zero; try { lock (this) { if (_loopingThread != IntPtr.Zero) { _logger?.LogError($"AMDeviceNotificationSubscribeLoop already running."); throw new Exception("AMDeviceNotificationSubscribeLoop already running."); } _loopingThread = USBMuxInterop.CFRunLoopGetCurrent(); } _logger?.LogTrace($"Calling AMDeviceNotificationSubscribe."); if (USBMuxInterop.AMDeviceNotificationSubscribe(AMDeviceNotificationCallback, 0, 0, 0, out context) != 0) { _logger?.LogError($"Failed AMDeviceNotificationSubscribe call."); throw new Exception("Failed AMDeviceNotificationSubscribe call."); } _logger?.LogTrace($"Start dispatching notifications."); USBMuxInterop.CFRunLoopRun(); _logger?.LogTrace($"Stop dispatching notifications."); } catch (Exception ex) { _logger?.LogError($"Failed running subscribe loop: {ex.Message}. Disabling detection of devices connected over USB."); } finally { lock (this) { if (_loopingThread != IntPtr.Zero) { _loopingThread = IntPtr.Zero; } DisconnectDevice(); } if (context != IntPtr.Zero) { _logger?.LogTrace($"Calling AMDeviceNotificationUnsubscribe."); USBMuxInterop.AMDeviceNotificationUnsubscribe(context); } } }
bool DisconnectDevice() { if (_device != IntPtr.Zero) { if (_deviceConnectionID != 0) { USBMuxInterop.AMDeviceDisconnect(_device); _logger?.LogInformation($"Successfully disconnected device, id={_deviceConnectionID}."); _deviceConnectionID = 0; } _device = IntPtr.Zero; } return(true); }
bool ConnectDevice(IntPtr newDevice) { if (_device != IntPtr.Zero) { return(false); } _device = newDevice; if (USBMuxInterop.AMDeviceConnect(_device) == 0) { _deviceConnectionID = USBMuxInterop.AMDeviceGetConnectionID(_device); _logger?.LogInformation($"Successfully connected new device, id={_deviceConnectionID}."); return(true); } else { _logger?.LogError($"Failed connecting new device."); return(false); } }
void AMDeviceNotificationCallback(ref USBMuxInterop.AMDeviceNotificationCallbackInfo info) { _logger?.LogTrace($"AMDeviceNotificationInternal callback, device={info.am_device}, action={info.message}"); try { lock (this) { int interfaceType = USBMuxInterop.AMDeviceGetInterfaceType(info.am_device); switch (info.message) { case USBMuxInterop.AMDeviceNotificationMessage.Connected: if (interfaceType == 1 && _device == IntPtr.Zero) { ConnectDevice(info.am_device); } else if (interfaceType == 1 && _device != IntPtr.Zero) { _logger?.LogInformation($"Discovered new device, but one is already connected, ignoring new device."); } else if (interfaceType == 0) { _logger?.LogInformation($"Discovered new device not connected over USB, ignoring new device."); } break; case USBMuxInterop.AMDeviceNotificationMessage.Disconnected: case USBMuxInterop.AMDeviceNotificationMessage.Unsubscribed: if (_device == info.am_device) { DisconnectDevice(); } break; } } } catch (Exception ex) { _logger?.LogError($"Failed AMDeviceNotificationCallback: {ex.Message}. Failed handling device={info.am_device} using action={info.message}"); } }
int ConnectTcpClientOverUSBMux() { uint result = 0; int handle = -1; ushort networkPort = (ushort)IPAddress.HostToNetworkOrder(unchecked ((short)_port)); lock (this) { if (_deviceConnectionID == 0) { throw new Exception($"Failed to connect device over USB, no device currently connected."); } result = USBMuxInterop.USBMuxConnectByPort(_deviceConnectionID, networkPort, out handle); } if (result != 0) { throw new Exception($"Failed to connect device over USB using connection {_deviceConnectionID} and port {_port}."); } return(handle); }