Skip to content

Commit 7b4b4bf

Browse files
committed
- rework usage of lockdownd_client_t and service objects
- we create it every we need it and kill it when it done - changes some ui logics
1 parent 5b6c263 commit 7b4b4bf

12 files changed

Lines changed: 918 additions & 764 deletions

Src/devicebridge.cpp

Lines changed: 97 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,24 @@ void DeviceBridge::Destroy()
2121

2222
DeviceBridge::DeviceBridge()
2323
: m_device(nullptr)
24-
, m_client(nullptr)
24+
, m_miscClient(nullptr)
2525
, m_diagnostics(nullptr)
2626
, m_screenshot(nullptr)
27-
, m_afc(nullptr)
2827
, m_imageMounter(nullptr)
28+
, m_imageSender(nullptr)
29+
, m_mounterClient(nullptr)
30+
, m_crashlogClient(nullptr)
2931
, m_crashlog(nullptr)
32+
, m_fileClient(nullptr)
3033
, m_fileManager(nullptr)
3134
, m_houseArrest(nullptr)
3235
, m_installer(nullptr)
36+
, m_buildSender(nullptr)
37+
, m_installerClient(nullptr)
38+
, m_syslogClient(nullptr)
3339
, m_syslog(nullptr)
3440
, m_logHandler(new LogFilterThread())
41+
, m_debugClient(nullptr)
3542
, m_debugger(nullptr)
3643
, m_debugHandler(new DebuggerFilterThread())
3744
{
@@ -76,13 +83,6 @@ void DeviceBridge::ResetConnection()
7683
m_currentUdid.clear();
7784
StopDebugging();
7885

79-
if(m_client)
80-
{
81-
//Quick fix: stuck while reseting connection at exit, switch, reconnect
82-
//is_exist ? (void)lockdownd_client_free(m_client) : free(m_client);
83-
m_client = nullptr;
84-
}
85-
8686
if (m_screenshot)
8787
{
8888
screenshotr_client_free(m_screenshot);
@@ -97,10 +97,16 @@ void DeviceBridge::ResetConnection()
9797
m_imageMounter = nullptr;
9898
}
9999

100-
if (m_afc)
100+
if (m_imageSender)
101101
{
102-
afc_client_free(m_afc);
103-
m_afc = nullptr;
102+
afc_client_free(m_imageSender);
103+
m_imageSender = nullptr;
104+
}
105+
106+
if (m_buildSender)
107+
{
108+
afc_client_free(m_buildSender);
109+
m_buildSender = nullptr;
104110
}
105111

106112
if (m_crashlog)
@@ -132,11 +138,54 @@ void DeviceBridge::ResetConnection()
132138
syslog_relay_client_free(m_syslog);
133139
m_syslog = nullptr;
134140
}
141+
142+
//Quick fix: stuck while reseting connection at exit, switch, reconnect just comment free
143+
if(m_miscClient)
144+
{
145+
lockdownd_client_free(m_miscClient);
146+
m_miscClient = nullptr;
147+
}
148+
149+
if(m_mounterClient)
150+
{
151+
lockdownd_client_free(m_mounterClient);
152+
m_mounterClient = nullptr;
153+
}
154+
155+
if(m_crashlogClient)
156+
{
157+
lockdownd_client_free(m_crashlogClient);
158+
m_crashlogClient = nullptr;
159+
}
160+
161+
if(m_fileClient)
162+
{
163+
lockdownd_client_free(m_fileClient);
164+
m_fileClient = nullptr;
165+
}
166+
167+
if(m_installerClient)
168+
{
169+
lockdownd_client_free(m_installerClient);
170+
m_installerClient = nullptr;
171+
}
172+
173+
if(m_syslogClient)
174+
{
175+
lockdownd_client_free(m_syslogClient);
176+
m_syslogClient = nullptr;
177+
}
178+
179+
if(m_debugClient)
180+
{
181+
lockdownd_client_free(m_debugClient);
182+
m_debugClient = nullptr;
183+
}
135184

136185
if(m_device)
137186
{
138187
//Quick fix: crash when try to connect unpaired device
139-
//idevice_free(m_device);
188+
idevice_free(m_device);
140189
m_device = nullptr;
141190
}
142191
emit DeviceStatus(ConnectionStatus::DISCONNECTED, m_currentUdid, m_isRemote);
@@ -156,18 +205,12 @@ void DeviceBridge::ConnectToDevice(QString udid)
156205
return;
157206
}
158207

159-
emit ProcessStatusChanged(15, "Handshaking client...");
160-
if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(m_device, &m_client, TOOL_NAME)) {
161-
idevice_free(m_device);
162-
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Connecting to " + udid + " failed!");
163-
return;
164-
}
165-
166208
emit ProcessStatusChanged(20, "Getting device info...");
167209
m_currentUdid = udid;
168210
m_isRemote = false;
169211
UpdateDeviceInfo();
170212
emit ProcessStatusChanged(100, "Connected to " + GetDeviceInfo()["DeviceName"].toString() + "!");
213+
emit DeviceStatus(ConnectionStatus::CONNECTED, m_currentUdid, m_isRemote);
171214
});
172215
}
173216

@@ -186,18 +229,11 @@ void DeviceBridge::ConnectToDevice(QString ipAddress, int port)
186229
return;
187230
}
188231

189-
emit ProcessStatusChanged(15, "Handshaking client...");
190-
lockdownd_error_t ret = lockdownd_client_new_with_handshake_remote(m_device, &m_client, TOOL_NAME);
191-
if (LOCKDOWN_E_SUCCESS != ret) {
192-
idevice_free(m_device);
193-
emit MessagesReceived(MessagesType::MSG_ERROR, QString::asprintf("ERROR: Connecting to %s:%d failed!", ipAddress.toUtf8().data(), port));
194-
return;
195-
}
196-
197232
emit ProcessStatusChanged(20, "Getting device info...");
198233
m_isRemote = true;
199234
UpdateDeviceInfo();
200235
emit ProcessStatusChanged(100, "Connected to " + GetDeviceInfo()["DeviceName"].toString() + "!");
236+
emit DeviceStatus(ConnectionStatus::CONNECTED, m_currentUdid, m_isRemote);
201237
});
202238
}
203239

@@ -213,145 +249,72 @@ bool DeviceBridge::IsConnected()
213249

214250
void DeviceBridge::UpdateDeviceInfo()
215251
{
216-
plist_t node = nullptr;
217-
if(lockdownd_get_value(m_client, nullptr, nullptr, &node) == LOCKDOWN_E_SUCCESS) {
218-
if (node) {
219-
QJsonDocument deviceInfo = PlistToJson(node);
220-
m_currentUdid = deviceInfo["UniqueDeviceID"].toString();
221-
m_deviceInfo[m_currentUdid] = deviceInfo;
222-
plist_free(node);
223-
node = nullptr;
224-
emit DeviceStatus(ConnectionStatus::CONNECTED, m_currentUdid, m_isRemote);
225-
226-
//start services
227-
StartServices();
252+
StartLockdown(true, m_miscClient, QStringList(), [this](QString& service_id, lockdownd_service_descriptor_t& service){
253+
plist_t node = nullptr;
254+
if(lockdownd_get_value(m_miscClient, nullptr, nullptr, &node) == LOCKDOWN_E_SUCCESS) {
255+
if (node) {
256+
QJsonDocument deviceInfo = PlistToJson(node);
257+
m_currentUdid = deviceInfo["UniqueDeviceID"].toString();
258+
m_deviceInfo[m_currentUdid] = deviceInfo;
259+
plist_free(node);
260+
node = nullptr;
261+
}
228262
}
229-
}
263+
});
264+
230265
}
231266

232267
QJsonDocument DeviceBridge::GetDeviceInfo(QString udid)
233268
{
234269
return m_deviceInfo[udid.isEmpty() ? m_currentUdid : udid];
235270
}
236271

237-
void DeviceBridge::StartServices()
272+
void DeviceBridge::StartLockdown(bool condition, lockdownd_client_t& client, QStringList service_ids, const std::function<void (QString&, lockdownd_service_descriptor_t&)> &function, bool clear_lockdownd)
238273
{
239-
emit ProcessStatusChanged(30, "Starting installation proxy service...");
240-
QStringList serviceIds = QStringList() << "com.apple.mobile.installation_proxy";
241-
StartLockdown(!m_installer, serviceIds, [this](QString& service_id, lockdownd_service_descriptor_t& service){
242-
instproxy_error_t err = instproxy_client_new(m_device, service, &m_installer);
243-
if (err != INSTPROXY_E_SUCCESS)
244-
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not connect to " + service_id + " client! " + QString::number(err));
245-
});
274+
if (!condition)
275+
return;
246276

247-
emit ProcessStatusChanged(40, "Starting crash report mover service...");
248-
serviceIds = QStringList() << "com.apple.crashreportmover";
249-
StartLockdown(!m_crashlog, serviceIds, [this](QString& service_id, lockdownd_service_descriptor_t& service){
250-
service_client_t svcmove = NULL;
251-
service_error_t err = service_client_new(m_device, service, &svcmove);
252-
if (err != SERVICE_E_SUCCESS)
277+
lockdownd_error_t err = lockdownd_error_t::LOCKDOWN_E_UNKNOWN_ERROR;
278+
if (client == nullptr)
279+
{
280+
err = m_isRemote ? lockdownd_client_new_with_handshake_remote(m_device, &client, TOOL_NAME) : lockdownd_client_new_with_handshake(m_device, &client, TOOL_NAME);
281+
if (LOCKDOWN_E_SUCCESS != err)
253282
{
254-
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not connect to " + service_id + " client! " + QString::number(err));
283+
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Create lockdownd handshake failed!");
284+
client = nullptr;
255285
return;
256286
}
287+
}
257288

258-
/* read "ping" message which indicates the crash logs have been moved to a safe harbor */
259-
char* ping = (char*)malloc(4);
260-
memset(ping, '\0', 4);
261-
int attempts = 0;
262-
while ((strncmp(ping, "ping", 4) != 0) && (attempts < 10)) {
263-
uint32_t bytes = 0;
264-
err = service_receive_with_timeout(svcmove, ping, 4, &bytes, 2000);
265-
if (err == SERVICE_E_SUCCESS || err == SERVICE_E_TIMEOUT) {
266-
attempts++;
267-
continue;
268-
}
269-
270-
fprintf(stderr, "ERROR: Crash logs could not be moved. Connection interrupted (%d).\n", err);
271-
break;
272-
}
273-
service_client_free(svcmove);
274-
free(ping);
275-
276-
if (attempts >= 10) {
277-
fprintf(stderr, "ERROR: Failed to receive ping message from crash report mover.\n");
278-
}
279-
});
280-
281-
emit ProcessStatusChanged(50, "Starting crash report copy service...");
282-
serviceIds = QStringList() << "com.apple.crashreportcopymobile";
283-
StartLockdown(!m_crashlog, serviceIds, [this](QString& service_id, lockdownd_service_descriptor_t& service){
284-
afc_error_t err = afc_client_new(m_device, service, &m_crashlog);
285-
if (err != AFC_E_SUCCESS)
286-
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not connect to " + service_id + " client! " + QString::number(err));
287-
});
288-
289-
emit ProcessStatusChanged(60, "Starting afc service...");
290-
serviceIds = QStringList() << "com.apple.afc";
291-
StartLockdown(!m_afc, serviceIds, [this](QString& service_id, lockdownd_service_descriptor_t& service){
292-
afc_error_t err = afc_client_new(m_device, service, &m_afc);
293-
if (err != AFC_E_SUCCESS)
294-
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not connect to " + service_id + " client! " + QString::number(err));
295-
});
296-
297-
emit ProcessStatusChanged(70, "Starting image mounter service...");
298-
serviceIds = QStringList() << MOBILE_IMAGE_MOUNTER_SERVICE_NAME;
299-
StartLockdown(!m_imageMounter, serviceIds, [this](QString& service_id, lockdownd_service_descriptor_t& service){
300-
mobile_image_mounter_error_t err = mobile_image_mounter_new(m_device, service, &m_imageMounter);
301-
if (err != MOBILE_IMAGE_MOUNTER_E_SUCCESS)
302-
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not connect to " + service_id + " client! " + QString::number(err));
303-
});
304-
305-
emit ProcessStatusChanged(80, "Starting syslog relay service...");
306-
serviceIds = QStringList() << SYSLOG_RELAY_SERVICE_NAME;
307-
StartLockdown(!m_syslog, serviceIds, [this](QString& service_id, lockdownd_service_descriptor_t& service){
308-
/* connect to syslog_relay service */
309-
syslog_relay_error_t err = SYSLOG_RELAY_E_UNKNOWN_ERROR;
310-
err = syslog_relay_client_new(m_device, service, &m_syslog);
311-
if (err != SYSLOG_RELAY_E_SUCCESS) {
312-
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not connect to " + service_id + " client! " + QString::number(err));
313-
return;
314-
}
315-
316-
/* start capturing syslog */
317-
err = syslog_relay_start_capture_raw(m_syslog, SystemLogsCallback, nullptr);
318-
if (err != SYSLOG_RELAY_E_SUCCESS) {
319-
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Unable to start capturing syslog.");
320-
syslog_relay_client_free(m_syslog);
321-
m_syslog = nullptr;
322-
return;
323-
}
324-
});
325-
}
326-
327-
void DeviceBridge::StartLockdown(bool condition, QStringList service_ids, const std::function<void (QString&, lockdownd_service_descriptor_t&)> &function)
328-
{
329-
if (!condition)
330-
return;
289+
if (service_ids.size() > 0)
290+
err = lockdownd_error_t::LOCKDOWN_E_UNKNOWN_ERROR;
331291

332-
lockdownd_error_t lerr = lockdownd_error_t::LOCKDOWN_E_UNKNOWN_ERROR;
333292
lockdownd_service_descriptor_t service = nullptr;
334293
QString service_id;
335294
for ( const auto& svc_id : service_ids)
336295
{
337296
service_id = svc_id;
338-
lerr = lockdownd_start_service(m_client, svc_id.toUtf8().data(), &service);
339-
if(lerr == LOCKDOWN_E_SUCCESS) { break; }
297+
err = lockdownd_start_service(client, svc_id.toUtf8().data(), &service);
298+
if(err == LOCKDOWN_E_SUCCESS) { break; }
340299
}
341300

342-
switch (lerr)
301+
switch (err)
343302
{
344303
case LOCKDOWN_E_SUCCESS:
345304
function(service_id, service);
346305
lockdownd_service_descriptor_free(service);
306+
if (clear_lockdownd && !client) {
307+
lockdownd_client_free(client);
308+
client = nullptr;
309+
}
347310
break;
348311

349312
case LOCKDOWN_E_PASSWORD_PROTECTED:
350313
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Device is passcode protected, enter passcode on the device to continue.");
351314
break;
352315

353316
default:
354-
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not connect to " + service_id + " lockdownd: " + QString::number(lerr));
317+
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not connect to " + service_id + " lockdownd: " + QString::number(err));
355318
break;
356319
}
357320
}

0 commit comments

Comments
 (0)