diff --git a/src/appcontext.cpp b/src/appcontext.cpp index 293b11c..20114dd 100644 --- a/src/appcontext.cpp +++ b/src/appcontext.cpp @@ -27,6 +27,7 @@ #include #include #include +#include AppContext *AppContext::sharedInstance() { @@ -92,7 +93,6 @@ void AppContext::cachePairedDevices() lockdowndir.filePath(fileName); } #else - // FIXME: implement caching for macOS /* MacOS */ qDebug() << "Caching paired network devices from usbmuxd"; auto conn = UsbmuxdConnection::default_new(0); @@ -183,165 +183,286 @@ void AppContext::cachePairedDevices() #endif } -void AppContext::addDevice(QString udid, +void AppContext::addDevice(iDescriptor::Uniq uniq, DeviceMonitorThread::IdeviceConnectionType conn_type, AddType addType, QString wifiMacAddress, QString ipAddress) { - emit initStarted(udid); + emit initStarted(uniq); try { - // iDescriptorInitDeviceResult initResult; auto initResult = std::make_shared(); - QFuture future = QtConcurrent::run([this, udid, conn_type, + + QFuture future = QtConcurrent::run([this, uniq, conn_type, addType, wifiMacAddress, ipAddress, initResult]() { if (addType == AddType::UpgradeToWireless) { qDebug() << "AddType::UpgradeToWireless"; - // FIXME: udid is actually macAddress here - const QString _pairingFilePath = getCachedPairingFile(udid); + const QString _pairingFilePath = getCachedPairingFile(uniq); if (_pairingFilePath.isEmpty()) { qDebug() << "Cannot upgrade to wireless, no cached pairing " "file for" - << udid; - emitNoPairingFileForWirelessDevice(udid); + << uniq; + emitNoPairingFileForWirelessDevice(uniq); return; } - *initResult = init_idescriptor_device( - udid, {ipAddress, _pairingFilePath}); + init_idescriptor_device(uniq, *initResult, + {ipAddress, _pairingFilePath}); } else if (addType == AddType::Wireless) { qDebug() << "AddType::Wireless"; - // FIXME: udid is actually macAddress here - const QString _pairingFilePath = getCachedPairingFile(udid); + const QString _pairingFilePath = getCachedPairingFile(uniq); if (_pairingFilePath.isEmpty()) { qDebug() << "Cannot upgrade to wireless, no cached pairing " "file for" - << udid; - emitNoPairingFileForWirelessDevice(udid); + << uniq; + emitNoPairingFileForWirelessDevice(uniq); return; } - *initResult = init_idescriptor_device( - udid, {ipAddress, _pairingFilePath}); + init_idescriptor_device(uniq, *initResult, + {ipAddress, _pairingFilePath}); } else { qDebug() << "AddType::Regular"; - *initResult = init_idescriptor_device(udid, {nullptr, nullptr}); + init_idescriptor_device(uniq, *initResult, {nullptr, nullptr}); } }); QFutureWatcher *watcher = new QFutureWatcher(); watcher->setFuture(future); - connect(watcher, &QFutureWatcher::finished, this, - [this, udid, initResult, addType, conn_type, watcher]() { - watcher->deleteLater(); - qDebug() << "init_idescriptor_device success ?: " - << initResult->success; - // qDebug() << "init_idescriptor_device error code: " << - // initResult.error; - if (!initResult->success) { - qDebug() << "Failed to initialize device with UDID: " - << udid; - emit initFailed(udid); - return; + connect( + watcher, &QFutureWatcher::finished, this, + [this, uniq, initResult, addType, conn_type, watcher]() { + watcher->deleteLater(); + qDebug() << "init_idescriptor_device success ?: " + << initResult->success; + + if (!initResult->success) { + qDebug() << "Failed to initialize device with" << uniq; + emit initFailed(uniq); + if (initResult->error && initResult->error->code == + PairingDialogResponsePending) { + if (addType == AddType::Regular) { + m_pendingDevices.append(uniq); + emit devicePasswordProtected(uniq); + emit deviceChange(); + QTimer::singleShot( + SettingsManager::sharedInstance() + ->connectionTimeout() * + 1000, + this, [this, uniq]() { + if (m_pendingDevices.contains(uniq)) { + qDebug() << "Pairing expired for " + "device UDID:" + << uniq; + m_pendingDevices.removeAll(uniq); + emit devicePairingExpired(uniq); + emit deviceChange(); + } + }); + // FIXME: free properly and move to a better place + QtConcurrent::run([uniq, this]() { + UsbmuxdConnectionHandle *usbmuxd_conn = nullptr; + UsbmuxdAddrHandle *addr_handle = nullptr; + IdeviceProviderHandle *provider = nullptr; + LockdowndClientHandle *lockdown = nullptr; + IdevicePairingFile *pairing_file = nullptr; + + IdeviceFfiError *err = + idevice_usbmuxd_new_default_connection( + 0, &usbmuxd_conn); + if (err) { + // if (!isWireless) { + qDebug() << "Failed to connect to usbmuxd"; + // goto cleanup; + return; + // } + } + + err = idevice_usbmuxd_default_addr_new( + &addr_handle); + if (err) { + qDebug() + << "Failed to create address handle"; + // goto cleanup; + return; + } + + UsbmuxdDeviceHandle **devices; + int device_count; + int actual_device_id = -1; + err = idevice_usbmuxd_get_devices( + usbmuxd_conn, &devices, &device_count); + + for (size_t i = 0; i < device_count; i++) { + const char *device_udid = + idevice_usbmuxd_device_get_udid( + devices[i]); + if (strcmp( + device_udid, + uniq.get().toUtf8().constData()) == + 0) { + actual_device_id = + idevice_usbmuxd_device_get_device_id( + devices[i]); + break; + } + } + + err = usbmuxd_provider_new( + addr_handle, 0, + uniq.get().toUtf8().constData(), + actual_device_id, APP_LABEL, &provider); + + err = lockdownd_connect(provider, &lockdown); + if (err) { + qDebug() << "Failed to connect to lockdown"; + return; + } + + QString hostId = QUuid::createUuid() + .toString() + .remove("{") + .remove("}") + .toUpper(); + char *buid = nullptr; + idevice_usbmuxd_get_buid(usbmuxd_conn, &buid); + + bool ok = false; + while (true) { + // if (const auto dev = + // AppContext::sharedInstance() + // ->getDevice( + // uniq.get().toStdString())) + // { + + if (ok) { + qDebug() << "Successfully paired with " + "device, "; + break; + }; + err = lockdownd_pair( + lockdown, hostId.toStdString().c_str(), + buid, &pairing_file); + if (err) { + qDebug() << "Failed to pair with device" + << err->message; + + std::this_thread::sleep_for( + std::chrono::seconds(5)); + // return; + // goto cleanup; + } else { + + qDebug() + << "There was no error, pairing " + "successful"; + uint8_t *data = nullptr; + size_t size = 0; + + // Serialize pairing file to bytes + IdeviceFfiError *err = + idevice_pairing_file_serialize( + pairing_file, &data, &size); + if (err) { + qDebug() << "Failed to serialize " + "pairing file:" + << err->message; + // idevice_error_free(err); + // goto cleanup; + } + + err = idevice_usbmuxd_save_pair_record( + usbmuxd_conn, + uniq.get().toUtf8().constData(), + data, size); + + QMetaObject::invokeMethod( + AppContext::sharedInstance(), + "addDevice", Qt::QueuedConnection, + Q_ARG(iDescriptor::Uniq, uniq), + Q_ARG(DeviceMonitorThread:: + IdeviceConnectionType, + DeviceMonitorThread:: + IdeviceConnectionType:: + CONNECTION_NETWORK), + Q_ARG(AddType, AddType::Regular)); + ok = true; + } + } + }); + } } - // if (!initResult.success) { - // qDebug() << "Failed to initialize device with UDID: " - // << udid; if (initResult.error == - // LOCKDOWN_E_PASSWORD_PROTECTED) - // { - // if (addType == AddType::Regular) { - // m_pendingDevices.append(udid); - // emit devicePasswordProtected(udid); - // emit deviceChange(); - // QTimer::singleShot( - // SettingsManager::sharedInstance()->connectionTimeout() - // * - // 1000, - // this, [this, udid]() { - // if (m_pendingDevices.contains(udid)) - // { - // qDebug() << "Pairing expired for - // device UDID: - // " - // << udid; - // m_pendingDevices.removeAll(udid); - // emit devicePairingExpired(udid); - // emit deviceChange(); - // } - // }); - // } - // } else if (initResult.error == - // LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING - // || - // initResult.error == - // LOCKDOWN_E_INVALID_HOST_ID) { - // m_pendingDevices.append(udid); - // emit devicePairPending(udid); - // emit deviceChange(); - // QTimer::singleShot( - // SettingsManager::sharedInstance()->connectionTimeout() - // * - // 1000, - // this, [this, udid]() { + + // else if (initResult.error == + // LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING + // || + // initResult.error == + // LOCKDOWN_E_INVALID_HOST_ID) { + // m_pendingDevices.append(udid); + // emit devicePairPending(udid); + // emit deviceChange(); + // QTimer::singleShot( + // SettingsManager::sharedInstance()->connectionTimeout() + // * + // 1000, + // this, [this, udid]() { + // qDebug() + // << "Pairing timer fired for device + // UDID: " << udid; + // if (m_pendingDevices.contains(udid)) { // qDebug() - // << "Pairing timer fired for device + // << "Pairing expired for device // UDID: " << udid; - // if (m_pendingDevices.contains(udid)) { - // qDebug() - // << "Pairing expired for device - // UDID: " << udid; - // m_pendingDevices.removeAll(udid); - // emit devicePairingExpired(udid); - // emit deviceChange(); - // } - // }); - // } else { - // qDebug() << "Unhandled error for device UDID: " - // << udid - // << " Error code: " << initResult.error; - // } - // return; + // m_pendingDevices.removeAll(udid); + // emit devicePairingExpired(udid); + // emit deviceChange(); + // } + // }); + // } else { + // qDebug() << "Unhandled error for device UDID: " + // << udid + // << " Error code: " << initResult.error; // } - qDebug() << "Device initialized: " << udid; + return; + } + qDebug() << "Device initialized: " << uniq; - iDescriptorDevice *device = new iDescriptorDevice{ - .udid = udid.toStdString(), - .conn_type = conn_type, - .provider = initResult->provider, - .deviceInfo = initResult->deviceInfo, - .afcClient = initResult->afcClient, - .afc2Client = initResult->afc2Client, - .lockdown = initResult->lockdown, - .imageMounter = initResult->imageMounter, - .diagRelay = initResult->diagRelay, - .locationSimulation = initResult->locationSimulation, - .heartbeatThread = initResult->heartbeatThread}; - m_devices[device->udid] = device; - if (addType == AddType::Regular) { - qDebug() << "Regular device added: " << udid; - // SettingsManager::sharedInstance()->doIfEnabled( - // SettingsManager::Setting::AutoRaiseWindow, []() { - // if (MainWindow *mainWindow = - // MainWindow::sharedInstance()) { - // mainWindow->raise(); - // mainWindow->activateWindow(); - // } - // }); + iDescriptorDevice *device = new iDescriptorDevice{ + .udid = uniq.get().toStdString(), + .conn_type = conn_type, + .provider = initResult->provider, + .deviceInfo = initResult->deviceInfo, + .afcClient = initResult->afcClient, + .afc2Client = initResult->afc2Client, + .lockdown = initResult->lockdown, + .diagRelay = initResult->diagRelay, + .heartbeatThread = initResult->heartbeatThread}; + m_devices[device->udid] = device; + if (addType == AddType::Regular) { + qDebug() << "Regular device added: " << uniq; + // SettingsManager::sharedInstance()->doIfEnabled( + // SettingsManager::Setting::AutoRaiseWindow, []() { + // if (MainWindow *mainWindow = + // MainWindow::sharedInstance()) { + // mainWindow->raise(); + // mainWindow->activateWindow(); + // } + // }); - emit deviceAdded(device); - emit deviceChange(); - return; - } - emit devicePaired(device); + emit deviceAdded(device); emit deviceChange(); - m_pendingDevices.removeAll(udid); - }); + return; + } + emit devicePaired(device); + emit deviceChange(); + m_pendingDevices.removeAll(uniq); + }); } catch (const std::exception &e) { qDebug() << "Exception in onDeviceAdded: " << e.what(); } @@ -552,31 +673,18 @@ AppContext::getDeviceByMacAddress(const QString &macAddress) const return nullptr; } -void AppContext::cachePairingFile(const QString &udid, +void AppContext::cachePairingFile(const QString &uniq, const QString &pairingFilePath) { - m_pairingFileCache.insert(udid, pairingFilePath); + m_pairingFileCache.insert(uniq, pairingFilePath); } -const QString AppContext::getCachedPairingFile(const QString &udid) const +const QString AppContext::getCachedPairingFile(const QString &uniq) const { QString pairingFile; - // Retrieve the pairing file from the cache - if (m_pairingFileCache.contains(udid)) { - pairingFile = m_pairingFileCache.value(udid); - } else { - // FIXME: mac support - // IdevicePairingFile* pairing_file = nullptr; - // const char* file_path = udid.toUtf8().constData(); - // IdeviceFfiError* err = idevice_pairing_file_read(file_path, - // &pairing_file); if (err == nullptr || pairing_file == nullptr) { - // pairingFile = QString::fromUtf8(file_path); - // } else { - // qDebug() << "Failed to read pairing file for UDID:" << udid << - // "Error:" << err->message; idevice_error_free(err); - // } + if (m_pairingFileCache.contains(uniq)) { + pairingFile = m_pairingFileCache.value(uniq); } - return pairingFile; } @@ -585,33 +693,19 @@ void AppContext::heartbeatFailed(const QString &macAddress, int tries) emit deviceHeartbeatFailed(macAddress, tries); } -void AppContext::tryToConnectToNetworkDevice(const QString &macAddress) +void AppContext::tryToConnectToNetworkDevice(const NetworkDevice &device) { // force refresh macAddress-udid mapping cachePairedDevices(); - QList networkDevices = - NetworkDeviceManager::sharedInstance() - ->m_networkProvider->getNetworkDevices(); - - auto it = - std::find_if(networkDevices.constBegin(), networkDevices.constEnd(), - [macAddress](const NetworkDevice &device) { - return device.macAddress.compare( - macAddress, Qt::CaseInsensitive) == 0; - }); - - if (it != networkDevices.constEnd()) { - QMetaObject::invokeMethod( - AppContext::sharedInstance(), "addDevice", Qt::QueuedConnection, - Q_ARG(QString, macAddress), - Q_ARG(DeviceMonitorThread::IdeviceConnectionType, - DeviceMonitorThread::CONNECTION_NETWORK), - Q_ARG(AddType, AddType::Wireless), Q_ARG(QString, macAddress)); - } else { - qDebug() << "No network device found with MAC address:" << macAddress; - } + QMetaObject::invokeMethod( + AppContext::sharedInstance(), "addDevice", Qt::QueuedConnection, + Q_ARG(iDescriptor::Uniq, iDescriptor::Uniq(device.macAddress, true)), + Q_ARG(DeviceMonitorThread::IdeviceConnectionType, + DeviceMonitorThread::CONNECTION_NETWORK), + Q_ARG(AddType, AddType::UpgradeToWireless), + Q_ARG(QString, device.macAddress), Q_ARG(QString, device.address)); } // this is required because cannot emit signals from qfuture diff --git a/src/appcontext.h b/src/appcontext.h index 52cd902..279b2e5 100644 --- a/src/appcontext.h +++ b/src/appcontext.h @@ -38,7 +38,7 @@ public: void cachePairingFile(const QString &udid, const QString &pairingFilePath); const QString getCachedPairingFile(const QString &udid) const; - void tryToConnectToNetworkDevice(const QString &macAddress); + void tryToConnectToNetworkDevice(const NetworkDevice &device); // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT // QList getAllRecoveryDevices(); // #endif @@ -91,7 +91,7 @@ signals: void deviceHeartbeatFailed(const QString &macAddress, int tries); public slots: void removeDevice(QString udid); - void addDevice(QString udid, + void addDevice(iDescriptor::Uniq udid, DeviceMonitorThread::IdeviceConnectionType connType, AddType addType, QString wifiMacAddress = QString(), QString ipAddress = QString()); diff --git a/src/core/services/get_mounted_image.cpp b/src/core/services/get_mounted_image.cpp index ff52f42..27b320e 100644 --- a/src/core/services/get_mounted_image.cpp +++ b/src/core/services/get_mounted_image.cpp @@ -21,24 +21,33 @@ MountedImageInfo _get_mounted_image(const iDescriptorDevice *device) { + qDebug() << "_get_mounted_image"; + uint8_t *signature = NULL; size_t signature_len = 0; IdeviceFfiError *err = nullptr; - qDebug() << "_get_mounted_image"; + ImageMounterHandle *image_mounter = nullptr; + err = image_mounter_connect(device->provider, &image_mounter); + if (err) { + qDebug() << "Failed to create Image Mounter client"; + goto leave; + } if (err) { qDebug() << "Failed to connect to image mounter:" << err->message; goto leave; } - err = image_mounter_lookup_image(device->imageMounter, - DISK_IMAGE_TYPE_DEVELOPER, &signature, - &signature_len); + err = image_mounter_lookup_image(image_mounter, DISK_IMAGE_TYPE_DEVELOPER, + &signature, &signature_len); if (err) { qDebug() << "Failed to lookup image:" << err->message << "Code:" << err->code; } leave: + if (image_mounter) + image_mounter_free(image_mounter); + return { .err = err, .signature = signature, diff --git a/src/core/services/init_device.cpp b/src/core/services/init_device.cpp index 6d63d13..f9c56b8 100644 --- a/src/core/services/init_device.cpp +++ b/src/core/services/init_device.cpp @@ -364,22 +364,29 @@ DeviceInfo fullDeviceInfo(const pugi::xml_document &doc, } } -iDescriptorInitDeviceResult -init_idescriptor_device(const QString &udid, - const WirelessInitArgs &wirelessArgs) +void init_idescriptor_device(const iDescriptor::Uniq &uniq, + iDescriptorInitDeviceResult &result, + const WirelessInitArgs &wirelessArgs) { const bool isWireless = !wirelessArgs.ip.isEmpty() && !wirelessArgs.pairing_file.isEmpty(); - qDebug() << "Initializing iDescriptor device with UDID: " << udid + + /* these should never happen but just to be safe and not to waste any + * resources return */ + if (isWireless && uniq.isUdid()) + return; + if (!isWireless && uniq.isMac()) + return; + + qDebug() << "Initializing iDescriptor device with" + << (uniq.isUdid() ? "UDID" : "MAC") << uniq << (isWireless ? "over wireless" : "over USB"); if (isWireless) { qDebug() << "Wireless args" << "IP:" << wirelessArgs.ip - << "for mac address" << udid; + << "for mac address" << uniq; } - iDescriptorInitDeviceResult result = {}; - UsbmuxdConnectionHandle *usbmuxd_conn = nullptr; UsbmuxdAddrHandle *addr_handle = nullptr; IdeviceProviderHandle *provider = nullptr; @@ -393,9 +400,7 @@ init_idescriptor_device(const QString &udid, IdeviceHandle *deviceHandle = nullptr; HeartbeatClientHandle *heartbeat = nullptr; HeartbeatThread *heartbeatThread = nullptr; - ImageMounterHandle *image_mounter = nullptr; DiagnosticsRelayClientHandle *diagnostics_relay = nullptr; - LocationSimulationHandle *location_simulation = nullptr; plist_t val = nullptr; IdeviceFfiError *err = @@ -422,7 +427,7 @@ init_idescriptor_device(const QString &udid, inet_pton(AF_INET, wirelessArgs.ip.toUtf8().constData(), &addr_in.sin_addr); qDebug() << "Reading pairing file from" << wirelessArgs.pairing_file - << "for udid" << udid; + << "for" << (uniq.isUdid() ? "UDID" : "MAC") << uniq; err = idevice_pairing_file_read( wirelessArgs.pairing_file.toUtf8().constData(), &pairing_file); if (err) { @@ -443,8 +448,8 @@ init_idescriptor_device(const QString &udid, qDebug() << "Failed to start Heartbeat service"; goto cleanup; } - // udid is mac address here for wireless - heartbeatThread = new HeartbeatThread(heartbeat, udid); + + heartbeatThread = new HeartbeatThread(heartbeat, uniq); heartbeatThread->start(); while (!heartbeatThread->initialCompleted()) { @@ -458,19 +463,18 @@ init_idescriptor_device(const QString &udid, err = idevice_usbmuxd_get_devices(usbmuxd_conn, &devices, &device_count); - // Find by UDID and get its device_id for (size_t i = 0; i < device_count; i++) { const char *device_udid = idevice_usbmuxd_device_get_udid(devices[i]); - if (strcmp(device_udid, udid.toUtf8().constData()) == 0) { + if (strcmp(device_udid, uniq.get().toUtf8().constData()) == 0) { actual_device_id = idevice_usbmuxd_device_get_device_id(devices[i]); break; } } - // 3. Create provider for the device (actual function name) - err = usbmuxd_provider_new(addr_handle, 0, udid.toUtf8().constData(), + err = usbmuxd_provider_new(addr_handle, 0, + uniq.get().toUtf8().constData(), actual_device_id, APP_LABEL, &provider); } @@ -487,7 +491,11 @@ init_idescriptor_device(const QString &udid, err = idevice_provider_get_pairing_file(provider, &pairing_file); if (err) { - qDebug() << "Failed to get pairing file"; + idevice_error_free(err); + err = new IdeviceFfiError{.code = PairingDialogResponsePending, + .message = "Pairing dialog response pending"}; + + qDebug() << "Waiting for user to respond to pairing dialog on device"; goto cleanup; } @@ -508,12 +516,6 @@ init_idescriptor_device(const QString &udid, goto cleanup; } - err = image_mounter_connect(provider, &image_mounter); - if (err) { - qDebug() << "Failed to create Image Mounter client"; - goto cleanup; - } - err = diagnostics_relay_client_connect(provider, &diagnostics_relay); if (err) { @@ -534,7 +536,7 @@ init_idescriptor_device(const QString &udid, // qDebug() << "Failed to create Location Simulation client"; // goto cleanup; // } - get_device_info_xml(udid.toUtf8().constData(), lockdown, infoXml); + get_device_info_xml(uniq.get().toUtf8().constData(), lockdown, infoXml); lockdownd_get_value(lockdown, "EnableWifiConnections", "com.apple.mobile.wireless_lockdown", &val); @@ -546,12 +548,8 @@ init_idescriptor_device(const QString &udid, result.afcClient = afc_client; result.afc2Client = afc2_client; result.lockdown = lockdown; - // TODO:remove, not really required to get some stuff going so it can be - // optional - result.imageMounter = image_mounter; result.diagRelay = std::make_shared( DiagnosticsRelay::adopt(diagnostics_relay)); - result.locationSimulation = location_simulation; result.heartbeatThread = heartbeatThread; // TODO cache pairing file path result.deviceInfo.isWireless = isWireless; @@ -561,14 +559,16 @@ init_idescriptor_device(const QString &udid, ::QObject::connect(heartbeatThread, &HeartbeatThread::heartbeatFailed, AppContext::sharedInstance(), &AppContext::heartbeatFailed); - ::QObject::connect( - heartbeatThread, &HeartbeatThread::heartbeatThreadExited, - AppContext::sharedInstance(), &AppContext::removeDevice); + ::QObject::connect(heartbeatThread, + &HeartbeatThread::heartbeatThreadExited, + AppContext::sharedInstance(), + &AppContext::removeDevice, Qt::SingleShotConnection); } cleanup: // Cleanup on error // FIXME: implement proper cleanup // one of them causes a crash here, needs investigation + result.error = err; if (!result.success) { qDebug() << "Initialization failed, cleaning up resources." << err->message; @@ -585,8 +585,6 @@ cleanup: // if (usbmuxd_conn) // idevice_usbmuxd_connection_free(usbmuxd_conn); } - - return result; } // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT @@ -649,4 +647,4 @@ cleanup: // return result; // } -// #endif // ENABLE_RECOVERY_DEVICE_SUPPORT \ No newline at end of file +// #endif // ENABLE_RECOVERY_DEVICE_SUPPORT diff --git a/src/core/services/mount_dev_image.cpp b/src/core/services/mount_dev_image.cpp index 542d994..2f900f4 100644 --- a/src/core/services/mount_dev_image.cpp +++ b/src/core/services/mount_dev_image.cpp @@ -29,7 +29,7 @@ IdeviceFfiError *mount_dev_image(const iDescriptorDevice *device, const char *signature_file) { - if (!device || !device->provider || !device->imageMounter) { + if (!device || !device->provider) { qDebug() << "Error: Invalid device or provider passed to mount_dev_image"; return new IdeviceFfiError{// FIXME: whats the code ? @@ -43,7 +43,10 @@ IdeviceFfiError *mount_dev_image(const iDescriptorDevice *device, uint8_t *signature_data = nullptr; IdeviceFfiError *err = nullptr; + ImageMounterHandle *image_mounter = nullptr; + err = image_mounter_connect(device->provider, &image_mounter); if (err) { + qDebug() << "Failed to create Image Mounter client"; goto cleanup; } @@ -56,9 +59,9 @@ IdeviceFfiError *mount_dev_image(const iDescriptorDevice *device, .message = "Failed to read signature file"}; goto cleanup; } else { - err = image_mounter_mount_developer(device->imageMounter, image_data, - image_len, signature_data, - signature_len); + err = + image_mounter_mount_developer(image_mounter, image_data, image_len, + signature_data, signature_len); if (err == NULL) { printf("Developer image mounted successfully\n"); } else { @@ -69,6 +72,8 @@ IdeviceFfiError *mount_dev_image(const iDescriptorDevice *device, } cleanup: + if (image_mounter) + image_mounter_free(image_mounter); if (image_data) free(image_data); diff --git a/src/devicemanagerwidget.cpp b/src/devicemanagerwidget.cpp index 8ae5cfa..d80ffac 100644 --- a/src/devicemanagerwidget.cpp +++ b/src/devicemanagerwidget.cpp @@ -197,28 +197,27 @@ void DeviceManagerWidget::addDevice(iDescriptorDevice *device) // } // #endif -void DeviceManagerWidget::addPendingDevice(const QString &udid, bool locked) +void DeviceManagerWidget::addPendingDevice(const QString &uniq, bool locked) { - // qDebug() << "Adding pending device:" << udid; - // if (m_pendingDeviceWidgets.contains(udid.toStdString()) && !locked) { - // qDebug() << "Pending device already exists, moving to next state:" - // << udid; - // m_pendingDeviceWidgets[udid.toStdString()].first->next(); - // return; - // } else if (m_pendingDeviceWidgets.contains(udid.toStdString()) && locked) - // { - // // Already exists and still locked, do nothing - // qDebug() - // << "Pending device already exists and is locked, doing nothing:" - // << udid; - // return; - // } + qDebug() << "Adding pending device:" << uniq; + if (m_pendingDeviceWidgets.contains(uniq.toStdString()) && !locked) { + qDebug() << "Pending device already exists, moving to next state:" + << uniq; + m_pendingDeviceWidgets[uniq.toStdString()].first->next(); + return; + } else if (m_pendingDeviceWidgets.contains(uniq.toStdString()) && locked) { + // Already exists and still locked, do nothing + qDebug() + << "Pending device already exists and is locked, doing nothing:" + << uniq; + return; + } - // qDebug() << "Created pending widget for:" << udid << "Locked:" << locked; - // DevicePendingWidget *pendingWidget = new DevicePendingWidget(locked, - // this); m_stackedWidget->addWidget(pendingWidget); - // m_pendingDeviceWidgets[udid.toStdString()] = - // std::pair{pendingWidget, m_sidebar->addPendingDevice(udid)}; + qDebug() << "Created pending widget for:" << uniq << "Locked:" << locked; + DevicePendingWidget *pendingWidget = new DevicePendingWidget(locked, this); + m_stackedWidget->addWidget(pendingWidget); + m_pendingDeviceWidgets[uniq.toStdString()] = + std::pair{pendingWidget, m_sidebar->addPendingDevice(uniq)}; } void DeviceManagerWidget::removePendingDevice(const QString &udid) diff --git a/src/iDescriptor-utils.h b/src/iDescriptor-utils.h index b949c62..93b8cee 100644 --- a/src/iDescriptor-utils.h +++ b/src/iDescriptor-utils.h @@ -39,6 +39,34 @@ struct ProductTypeVersion { namespace iDescriptor { +/* + Uniq is just a wrapper to get rid of mac and udid hell +*/ +class Uniq +{ +public: + Uniq(const QString &uniq, bool isMac = false) + { + m_uniq = uniq; + m_isMac = isMac; + }; + + Uniq(const std::string &uniq, bool isMac = false) + { + m_uniq = QString::fromStdString(uniq); + m_isMac = isMac; + }; + + bool isMac() const { return m_isMac; }; + bool isUdid() const { return !m_isMac; } + const QString &get() const { return m_uniq; } + operator QString() const { return m_uniq; } + +private: + QString m_uniq; + bool m_isMac; +}; + class Utils { private: diff --git a/src/iDescriptor.h b/src/iDescriptor.h index 1e13956..341df16 100644 --- a/src/iDescriptor.h +++ b/src/iDescriptor.h @@ -72,6 +72,8 @@ #define DeviceLockedMountErrorCode -21 #define NotFoundErrorCode -14 #define ServiceNotFoundErrorCode -15 +#define PairingDialogResponsePending -28 + #define DISK_IMAGE_TYPE_DEVELOPER "Developer" #define HEARTBEAT_RETRY_LIMIT 2 @@ -224,24 +226,20 @@ struct iDescriptorDevice { AfcClientHandle *afc2Client; LockdowndClientHandle *lockdown; mutable std::recursive_mutex mutex; - ImageMounterHandle *imageMounter; std::shared_ptr diagRelay; - LocationSimulationHandle *locationSimulation; // nullptr on USB devices QThread *heartbeatThread; }; struct iDescriptorInitDeviceResult { bool success = false; - IdeviceFfiError error; + IdeviceFfiError *error; IdeviceProviderHandle *provider; DeviceInfo deviceInfo; AfcClientHandle *afcClient; AfcClientHandle *afc2Client; LockdowndClientHandle *lockdown; - ImageMounterHandle *imageMounter; std::shared_ptr diagRelay; - LocationSimulationHandle *locationSimulation; QThread *heartbeatThread; }; // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT @@ -438,9 +436,9 @@ struct WirelessInitArgs { const QString ip; const QString pairing_file; }; -iDescriptorInitDeviceResult -init_idescriptor_device(const QString &udid, - const WirelessInitArgs &wirelessArgs = {"", ""}); +void init_idescriptor_device(const iDescriptor::Uniq &uniq, + iDescriptorInitDeviceResult &result, + const WirelessInitArgs &wirelessArgs = {"", ""}); // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT // iDescriptorInitDeviceResultRecovery diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4e770d9..7687516 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -364,11 +364,12 @@ MainWindow::MainWindow(QWidget *parent) if (conn_type == DeviceMonitorThread::CONNECTION_NETWORK) { return; } - qDebug() << "Device added: " << udid; + qDebug() << "Device event received: " << udid; QMetaObject::invokeMethod( AppContext::sharedInstance(), "addDevice", - Qt::QueuedConnection, Q_ARG(QString, udid), + Qt::QueuedConnection, + Q_ARG(iDescriptor::Uniq, iDescriptor::Uniq(udid)), Q_ARG( DeviceMonitorThread::IdeviceConnectionType, static_cast( @@ -414,24 +415,27 @@ MainWindow::MainWindow(QWidget *parent) // ═══════════════════════════════════════════════════════════════════════ // Upgrade to wireless when a "WIRED" device is removed // ═══════════════════════════════════════════════════════════════════════ - connect(AppContext::sharedInstance(), &AppContext::deviceRemoved, this, - [](const std::string &udid, const std::string &wifiMacAddress, - const std::string &ipAddress, bool wasWireless) { - if (wasWireless) - return; - qDebug() << "Upgrading device to wireless connection for UDID" - << QString::fromStdString(udid); - QMetaObject::invokeMethod( - AppContext::sharedInstance(), "addDevice", - Qt::QueuedConnection, - Q_ARG(QString, QString::fromStdString(udid)), - Q_ARG(DeviceMonitorThread::IdeviceConnectionType, - DeviceMonitorThread::CONNECTION_NETWORK), - Q_ARG(AddType, AddType::UpgradeToWireless), - Q_ARG(QString, QString::fromStdString(wifiMacAddress)), - Q_ARG(QString, QString::fromStdString(ipAddress))); - }); + connect( + AppContext::sharedInstance(), &AppContext::deviceRemoved, this, + [](const std::string &udid, const std::string &wifiMacAddress, + const std::string &ipAddress, bool wasWireless) { + if (wasWireless) + return; + qDebug() << "Upgrading device to wireless connection for UDID" + << QString::fromStdString(udid); + QMetaObject::invokeMethod( + AppContext::sharedInstance(), "addDevice", Qt::QueuedConnection, + Q_ARG(iDescriptor::Uniq, iDescriptor::Uniq(udid, wasWireless)), + Q_ARG(DeviceMonitorThread::IdeviceConnectionType, + DeviceMonitorThread::CONNECTION_NETWORK), + Q_ARG(AddType, AddType::UpgradeToWireless), + Q_ARG(QString, QString::fromStdString(wifiMacAddress)), + Q_ARG(QString, QString::fromStdString(ipAddress))); + }); + // ═══════════════════════════════════════════════════════════════════════ + // Add a wireless device + // ═══════════════════════════════════════════════════════════════════════ connect(NetworkDeviceManager::sharedInstance(), &NetworkDeviceManager::deviceAdded, this, [this](const NetworkDevice &device) { @@ -455,7 +459,8 @@ MainWindow::MainWindow(QWidget *parent) QMetaObject::invokeMethod( AppContext::sharedInstance(), "addDevice", - Qt::QueuedConnection, Q_ARG(QString, device.macAddress), + Q_ARG(iDescriptor::Uniq, + iDescriptor::Uniq(device.macAddress, true)), Q_ARG(DeviceMonitorThread::IdeviceConnectionType, DeviceMonitorThread::CONNECTION_NETWORK), Q_ARG(AddType, AddType::Wireless), @@ -496,7 +501,7 @@ void MainWindow::createMenus() void MainWindow::updateNoDevicesConnected() { - qDebug() << "Is there no devices connected? " + qDebug() << "No devices connected? " << AppContext::sharedInstance()->noDevicesConnected(); if (AppContext::sharedInstance()->noDevicesConnected()) { diff --git a/src/networkdevicestoconnectwidget.cpp b/src/networkdevicestoconnectwidget.cpp index 3c89b96..6c42e07 100644 --- a/src/networkdevicestoconnectwidget.cpp +++ b/src/networkdevicestoconnectwidget.cpp @@ -85,8 +85,7 @@ NetworkDeviceCard::NetworkDeviceCard(const NetworkDevice &device, connect(m_connectButton, &QPushButton::clicked, this, [this, device]() { m_connectButton->setText("Connecting..."); m_connectButton->setEnabled(false); - AppContext::sharedInstance()->tryToConnectToNetworkDevice( - device.macAddress); + AppContext::sharedInstance()->tryToConnectToNetworkDevice(device); }); infoLayout->addWidget(m_connectButton); infoLayout->addSpacing(5); @@ -207,7 +206,7 @@ void NetworkDevicesToConnectWidget::setupUI() // Scroll area m_scrollArea = new QScrollArea(); m_scrollArea->setWidgetResizable(true); - m_scrollArea->setMinimumHeight(200); + m_scrollArea->setMinimumHeight(400); m_scrollArea->setMaximumHeight(400); m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);