/// <summary> /// 开启Session。Session需要在调用服务前先行打开,然后完成服务操作后自行关闭(函数会自动关闭),否则可能会遇到无法打开服务的错误 /// </summary> /// <returns></returns> public kAMDError StartSession(bool isRretry = false) { var kAMDSuccess = kAMDError.kAMDSuccess; try { if (!isSessionOpen) { kAMDSuccess = (kAMDError)MobileDevice.AMDeviceStartSession(DevicePtr); if (kAMDSuccess != kAMDError.kAMDInvalidHostIDError) { if (kAMDSuccess != (int)kAMDError.kAMDSuccess) { //修复:Session关闭后一段时间无法再次打开的问题 if (!isRretry) { Disconnect(); Connect(); return(StartSession(true)); } return(kAMDSuccess); } isSessionOpen = true; return(kAMDSuccess); } if (MobileDevice.AMDeviceUnpair(DevicePtr) == (int)kAMDError.kAMDSuccess && MobileDevice.AMDevicePair(DevicePtr) == (int)kAMDError.kAMDSuccess) { kAMDSuccess = (kAMDError)MobileDevice.AMDeviceStartSession(DevicePtr); if (kAMDSuccess != kAMDError.kAMDSuccess) { return(kAMDSuccess); } isSessionOpen = true; return(kAMDSuccess); } } return(kAMDSuccess); } catch { kAMDSuccess = kAMDError.kAMDUndefinedError; } return(kAMDSuccess); }
/// <summary> /// 获取设备信息 /// </summary> /// <param name="domain">The domain.</param> /// <param name="key">The key.</param> /// <returns>System.Object.</returns> public object GetDeviceValue(string domain, string key) { object resultValue = null; try { var isReconnect = false; var isReOpenSession = false; if (!isConnected) { if (Connect() != (int)kAMDError.kAMDSuccess) { return(null); } isReconnect = true; } if (!isSessionOpen) { if (StartSession(false) == (int)kAMDError.kAMDSuccess) { isReOpenSession = true; } else { if (isReconnect) { Disconnect(); } } } resultValue = MobileDevice.AMDeviceCopyValue(DevicePtr, domain, key); if (isReOpenSession) { StopSession(); } if (isReconnect) { Disconnect(); } } catch { } return(resultValue); }
/// <summary> /// 开启AFC服务 /// </summary> /// <param name="inSocket">socket句柄</param> /// <returns></returns> public bool OpenConnection(int inSocket, out IntPtr connPtr) { connPtr = IntPtr.Zero; try { if (MobileDevice.AFCConnectionOpen(new IntPtr(inSocket), 0, ref connPtr) == (int)kAMDError.kAMDSuccess) { return(true); } } catch { } return(false); }
/// <summary> /// 断开设备链接,但不会断开USB树链接,因而可以通过调用Connect来重新链接到设备 /// </summary> /// <returns></returns> public kAMDError Disconnect() { var kAMDSuccess = kAMDError.kAMDSuccess; isConnected = false; try { kAMDSuccess = (kAMDError)MobileDevice.AMDeviceDisconnect(DevicePtr); } catch (Exception exception) { Console.WriteLine(exception.ToString()); } return(kAMDSuccess); }
/// <summary> /// 停止Socket服务 /// </summary> /// <param name="inSocket"></param> /// <returns></returns> private bool StopSocketService(ref int socket) { kAMDError kAMDSuccess = kAMDError.kAMDSuccess; if (socket > 0) { try { kAMDSuccess = (kAMDError)MobileDevice.closesocket(socket); } catch (Exception ex) { return(false); } } socket = 0; return(kAMDSuccess != kAMDError.kAMDSuccess); }
/// <summary> /// 链接到设备,用于设备链接失效或者手动推出后重链接操作,此函数只要设备还在USB树上,是无需用户插拔的 /// </summary> /// <returns></returns> public kAMDError Connect() { kAMDError kAMDSuccess = kAMDError.kAMDSuccess; try { if (!isConnected) { kAMDSuccess = (kAMDError)MobileDevice.AMDeviceConnect(DevicePtr); if (kAMDSuccess == kAMDError.kAMDSuccess) { isConnected = true; } } } catch (Exception exception) { Console.WriteLine(exception.ToString()); } return(kAMDSuccess); }
/// <summary> /// 开始监听链接 /// 需要使用线程方式调用 /// </summary> public void StartListen() { if (!iSStartListen) { iSStartListen = true; try { deviceNotificationCallback = NotificationCallback; deviceDFUConnectedNotificationCallback = DfuConnectCallback; deviceRecoveryConnectedNotificationCallback = RecoveryConnectCallback; deviceDFUDisConnectedNotificationCallback = DfuDisconnectCallback; deviceRecoveryDisConnectedNotificationCallback = RecoveryDisconnectCallback; IntPtr zero = IntPtr.Zero; kAMDError error = (kAMDError)MobileDevice.AMDeviceNotificationSubscribe(deviceNotificationCallback, 0, 1, 0, ref zero); if (error != kAMDError.kAMDSuccess) { //Check "Apple Mobile Device Service" status ListenErrorEvent?.Invoke(this, new ListenErrorEventHandlerEventArgs("AMDeviceNotificationSubscribe failed with error : " + error, ListenErrorEventType.StartListen)); } IntPtr userInfo = IntPtr.Zero; error = (kAMDError)MobileDevice.AMRestoreRegisterForDeviceNotifications(deviceDFUConnectedNotificationCallback, deviceRecoveryConnectedNotificationCallback, deviceDFUDisConnectedNotificationCallback, deviceRecoveryDisConnectedNotificationCallback, 0, ref userInfo); if (error != kAMDError.kAMDSuccess) { ListenErrorEvent?.Invoke(this, new ListenErrorEventHandlerEventArgs("AMRestoreRegisterForDeviceNotifications failed with error : " + error, ListenErrorEventType.StartListen)); } //LoopRun CoreFoundation.CFRunLoopRun(); } catch (Exception ex) { if (ListenErrorEvent != null) { ListenErrorEvent(this, new ListenErrorEventHandlerEventArgs(ex.Message, ListenErrorEventType.StartListen)); } } } }
/// <summary> /// 连接设备并初始化基础服务 /// </summary> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> private bool ConnectAndInitService() { bool result = false; kAMDError kAMDUndefinedError = kAMDError.kAMDUndefinedError; try { if (Connect() != (int)kAMDError.kAMDSuccess) { return(false); } //TODO:初始化设备信息 if (MobileDevice.AMDeviceValidatePairing(DevicePtr) != (int)kAMDError.kAMDSuccess) { kAMDUndefinedError = (kAMDError)MobileDevice.AMDevicePair(DevicePtr); if (kAMDUndefinedError != kAMDError.kAMDSuccess) { Disconnect(); return(false); } } isSessionOpen = false; //确保Session已打开 if (StartSession(false) == (int)kAMDError.kAMDSuccess) { //TODO:初始化服务,填充基础数据 isConnected = true; StopSession(); result = true; } } catch { } return(result); }
/// <summary> /// 接收Socket消息,主要为接收设备返回的指令结果,大部分为Plist,所以函数内将会自行作转换 /// </summary> /// <param name="sock"></param> /// <returns></returns> public object ReceiveMessageFromSocket(int sock) { if (sock < 0) { return(null); } int recvCount; uint buffer = 0; uint reviceSize = 0; uint dataSize = 0; IntPtr zero = IntPtr.Zero; if (DeviceSecureIOContext != IntPtr.Zero && SocketContext != IntPtr.Zero) { if (MobileDevice.AMDServiceConnectionReceive(SocketContext, ref buffer, 4) == 4) { dataSize = MobileDevice.ntohl(buffer); //获取数据总长度 if (dataSize <= 0) { Console.WriteLine("receive size error, dataSize:" + dataSize); return(null); } zero = Marshal.AllocCoTaskMem((int)dataSize); if (zero == IntPtr.Zero) { Console.WriteLine("Could not allocate message buffer."); return(null); } var tempPtr = zero; while (reviceSize < dataSize) { recvCount = MobileDevice.AMDServiceConnectionReceive_1(SocketContext, tempPtr, (int)(dataSize - reviceSize)); if (recvCount <= -1) { Console.WriteLine("Could not receive secure message: " + recvCount); reviceSize = dataSize + 1; } else if (recvCount == 0) { Console.WriteLine("receive size is zero. "); break; } tempPtr = new IntPtr(tempPtr.ToInt64() + recvCount); reviceSize += (uint)recvCount; } } } else if (MobileDevice.recv_UInt(sock, ref buffer, 4, 0) == 4) { dataSize = MobileDevice.ntohl(buffer); //获取数据总长度 if (dataSize <= 0) { Console.WriteLine("receive size error, dataSize:" + dataSize); return(null); } zero = Marshal.AllocCoTaskMem((int)dataSize); if (zero == IntPtr.Zero) { Console.WriteLine("Could not allocate message buffer."); return(null); } var tempPtr = zero; while (reviceSize < dataSize) { recvCount = MobileDevice.recv(sock, tempPtr, (int)(dataSize - reviceSize), 0); if (recvCount <= -1) { Console.WriteLine("Could not receive secure message: " + recvCount); reviceSize = dataSize + 1; } else if (recvCount == 0) { Console.WriteLine("receive size is zero. "); break; } tempPtr = new IntPtr(tempPtr.ToInt64() + recvCount); reviceSize += (uint)recvCount; } } var datas = IntPtr.Zero; var srcRef = IntPtr.Zero; if (reviceSize == dataSize) { datas = CoreFoundation.CFDataCreate(CoreFoundation.kCFAllocatorDefault, zero, (int)dataSize); if (datas == IntPtr.Zero) { Console.WriteLine("Could not create CFData for message"); } else { var errorString = IntPtr.Zero; srcRef = CoreFoundation.CFPropertyListCreateFromXMLData(CoreFoundation.kCFAllocatorDefault, datas, CFPropertyListMutabilityOptions.kCFPropertyListImmutable, ref errorString); if (srcRef == IntPtr.Zero) { Console.WriteLine("Could not convert raw xml into a dictionary: " + Convert.ToString(CoreFoundation.ManagedTypeFromCFType(ref errorString))); return(null); } } } if (datas != IntPtr.Zero) { try { CoreFoundation.CFRelease(datas); } catch { } } if (zero != IntPtr.Zero) { Marshal.FreeCoTaskMem(zero); } var result = CoreFoundation.ManagedTypeFromCFType(ref srcRef); if (srcRef != IntPtr.Zero) { CoreFoundation.CFRelease(srcRef); } return(result); }
/// <summary> /// 发送消息通过Socket,大部分用途为发送plist文件(指令)给设备 /// </summary> /// <param name="sock"></param> /// <param name="message"></param> /// <returns></returns> public bool SendMessageToSocket(int sock, IntPtr message) { if (sock < 1 || message == IntPtr.Zero) { return(false); } var flag = false; var stream = CoreFoundation.CFWriteStreamCreateWithAllocatedBuffers(IntPtr.Zero, IntPtr.Zero); if (stream != IntPtr.Zero) { if (!CoreFoundation.CFWriteStreamOpen(stream)) { return(false); } var zero = IntPtr.Zero; if (CoreFoundation.CFPropertyListWriteToStream(message, stream, CFPropertyListFormat.kCFPropertyListBinaryFormat_v1_0, ref zero) > 0) { IntPtr srcRef = CoreFoundation.CFWriteStreamCopyProperty(stream, CoreFoundation.kCFStreamPropertyDataWritten); IntPtr buffer = CoreFoundation.CFDataGetBytePtr(srcRef); var bufferlen = CoreFoundation.CFDataGetLength(srcRef); var structure = MobileDevice.htonl((uint)bufferlen); var structureSize = Marshal.SizeOf(structure); if (DeviceSecureIOContext == IntPtr.Zero || SocketContext == IntPtr.Zero) { if (MobileDevice.send_UInt32(sock, ref structure, structureSize, 0) != structureSize) { Console.WriteLine("could not send message size"); } else if (MobileDevice.send(sock, buffer, bufferlen, 0) != bufferlen) { Console.WriteLine("Could not send message."); } else { flag = true; } } else if (MobileDevice.AMDServiceConnectionSend_UInt32(SocketContext, ref structure, structureSize) != structureSize) { Console.WriteLine("could not send message size with socket"); } else if (MobileDevice.AMDServiceConnectionSend(SocketContext, buffer, bufferlen) != bufferlen) { Console.WriteLine("could not send message size"); } else { flag = true; } CoreFoundation.CFRelease(srcRef); } CoreFoundation.CFWriteStreamClose(stream); } return(flag); }