summaryrefslogtreecommitdiffstats
path: root/tools/idevicedebugserverproxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/idevicedebugserverproxy.c')
-rw-r--r--tools/idevicedebugserverproxy.c117
1 files changed, 46 insertions, 71 deletions
diff --git a/tools/idevicedebugserverproxy.c b/tools/idevicedebugserverproxy.c
index 475749f..2209abc 100644
--- a/tools/idevicedebugserverproxy.c
+++ b/tools/idevicedebugserverproxy.c
@@ -26,7 +26,7 @@
26#include <signal.h> 26#include <signal.h>
27 27
28#include <libimobiledevice/libimobiledevice.h> 28#include <libimobiledevice/libimobiledevice.h>
29#include <libimobiledevice/lockdown.h> 29#include <libimobiledevice/debugserver.h>
30 30
31#include "common/socket.h" 31#include "common/socket.h"
32#include "common/thread.h" 32#include "common/thread.h"
@@ -41,16 +41,30 @@ typedef struct {
41 int server_fd; 41 int server_fd;
42 int client_fd; 42 int client_fd;
43 uint16_t local_port; 43 uint16_t local_port;
44 uint16_t remote_port; 44 idevice_t device;
45 idevice_connection_t device_connection; 45 debugserver_client_t debugserver_client;
46 volatile int stop_ctod; 46 volatile int stop_ctod;
47 volatile int stop_dtoc; 47 volatile int stop_dtoc;
48} socket_info_t; 48} socket_info_t;
49 49
50static socket_info_t global_socket_info;
51
50static void clean_exit(int sig) 52static void clean_exit(int sig)
51{ 53{
52 fprintf(stderr, "Exiting...\n"); 54 if (quit_flag == 0)
55 fprintf(stderr, "Setting quit status. Cancel again to quit server.\n");
56 else
57 fprintf(stderr, "Exiting...\n");
58
53 quit_flag++; 59 quit_flag++;
60
61 /* shutdown server socket if we have to terminate to unblock the server loop */
62 if (quit_flag > 1) {
63 if (global_socket_info.server_fd > 0) {
64 socket_shutdown(global_socket_info.server_fd, SHUT_RDWR);
65 socket_close(global_socket_info.server_fd);
66 }
67 }
54} 68}
55 69
56static void print_usage(int argc, char **argv) 70static void print_usage(int argc, char **argv)
@@ -83,7 +97,7 @@ static void *thread_device_to_client(void *data)
83 while (!quit_flag && !socket_info->stop_dtoc && socket_info->client_fd > 0 && socket_info->server_fd > 0) { 97 while (!quit_flag && !socket_info->stop_dtoc && socket_info->client_fd > 0 && socket_info->server_fd > 0) {
84 debug("%s: receiving data from device...\n", __func__); 98 debug("%s: receiving data from device...\n", __func__);
85 99
86 res = idevice_connection_receive_timeout(socket_info->device_connection, buffer, sizeof(buffer), (uint32_t*)&recv_len, 5000); 100 res = debugserver_client_receive_with_timeout(socket_info->debugserver_client, buffer, sizeof(buffer), (uint32_t*)&recv_len, 5000);
87 101
88 if (recv_len <= 0) { 102 if (recv_len <= 0) {
89 if (recv_len == 0 && res == IDEVICE_E_SUCCESS) { 103 if (recv_len == 0 && res == IDEVICE_E_SUCCESS) {
@@ -161,7 +175,7 @@ static void *thread_client_to_device(void *data)
161 } else { 175 } else {
162 /* forward data to device */ 176 /* forward data to device */
163 debug("%s: sending data to device...\n", __func__); 177 debug("%s: sending data to device...\n", __func__);
164 res = idevice_connection_send(socket_info->device_connection, buffer, recv_len, (uint32_t*)&sent); 178 res = debugserver_client_send(socket_info->debugserver_client, buffer, recv_len, (uint32_t*)&sent);
165 179
166 if (sent < recv_len || res != IDEVICE_E_SUCCESS) { 180 if (sent < recv_len || res != IDEVICE_E_SUCCESS) {
167 if (sent <= 0) { 181 if (sent <= 0) {
@@ -194,11 +208,18 @@ static void *thread_client_to_device(void *data)
194 208
195static void* connection_handler(void* data) 209static void* connection_handler(void* data)
196{ 210{
211 debugserver_error_t derr = DEBUGSERVER_E_SUCCESS;
197 socket_info_t* socket_info = (socket_info_t*)data; 212 socket_info_t* socket_info = (socket_info_t*)data;
198 thread_t ctod; 213 thread_t ctod;
199 214
200 debug("%s: client_fd = %d\n", __func__, socket_info->client_fd); 215 debug("%s: client_fd = %d\n", __func__, socket_info->client_fd);
201 216
217 derr = debugserver_client_start_service(socket_info->device, &socket_info->debugserver_client, "idevicedebugserverproxy");
218 if (derr != DEBUGSERVER_E_SUCCESS) {
219 fprintf(stderr, "Could not start debugserver on device!\nPlease make sure to mount a developer disk image first.\n");
220 return NULL;
221 }
222
202 /* spawn client to device thread */ 223 /* spawn client to device thread */
203 socket_info->stop_ctod = 0; 224 socket_info->stop_ctod = 0;
204 if (thread_new(&ctod, thread_client_to_device, data) != 0) { 225 if (thread_new(&ctod, thread_client_to_device, data) != 0) {
@@ -209,29 +230,23 @@ static void* connection_handler(void* data)
209 thread_join(ctod); 230 thread_join(ctod);
210 thread_free(ctod); 231 thread_free(ctod);
211 232
233 debug("%s: shutting down...\n", __func__);
234
235 debugserver_client_free(socket_info->debugserver_client);
236 socket_info->debugserver_client = NULL;
237
212 /* shutdown client socket */ 238 /* shutdown client socket */
213 socket_shutdown(socket_info->client_fd, SHUT_RDWR); 239 socket_shutdown(socket_info->client_fd, SHUT_RDWR);
214 socket_close(socket_info->client_fd); 240 socket_close(socket_info->client_fd);
215 241
216 /* shutdown server socket if we have to terminate to unblock the server loop */
217 if (quit_flag) {
218 socket_shutdown(socket_info->server_fd, SHUT_RDWR);
219 socket_close(socket_info->server_fd);
220 }
221
222 return NULL; 242 return NULL;
223} 243}
224 244
225int main(int argc, char *argv[]) 245int main(int argc, char *argv[])
226{ 246{
227 lockdownd_client_t lockdown = NULL;
228 lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR;
229 idevice_t device = NULL;
230 idevice_connection_t connection = NULL;
231 idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; 247 idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
232 thread_t th; 248 thread_t th;
233 const char* udid = NULL; 249 const char* udid = NULL;
234 lockdownd_service_descriptor_t service = NULL;
235 uint16_t local_port = 0; 250 uint16_t local_port = 0;
236 int result = EXIT_SUCCESS; 251 int result = EXIT_SUCCESS;
237 int i; 252 int i;
@@ -282,8 +297,11 @@ int main(int argc, char *argv[])
282 goto leave_cleanup; 297 goto leave_cleanup;
283 } 298 }
284 299
300 /* setup and create socket endpoint */
301 global_socket_info.local_port = local_port;
302
285 /* start services and connect to device */ 303 /* start services and connect to device */
286 ret = idevice_new(&device, udid); 304 ret = idevice_new(&global_socket_info.device, udid);
287 if (ret != IDEVICE_E_SUCCESS) { 305 if (ret != IDEVICE_E_SUCCESS) {
288 if (udid) { 306 if (udid) {
289 fprintf(stderr, "No device found with udid %s, is it plugged in?\n", udid); 307 fprintf(stderr, "No device found with udid %s, is it plugged in?\n", udid);
@@ -294,66 +312,29 @@ int main(int argc, char *argv[])
294 goto leave_cleanup; 312 goto leave_cleanup;
295 } 313 }
296 314
297 if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(device, &lockdown, "idevicedebugserverproxy"))) {
298 fprintf(stderr, "ERROR: Could not connect to lockdownd, error code %d\n", ldret);
299 result = EXIT_FAILURE;
300 goto leave_cleanup;
301 }
302
303 if ((lockdownd_start_service(lockdown, "com.apple.debugserver", &service) != LOCKDOWN_E_SUCCESS) || !service || !service->port) {
304 fprintf(stderr, "Could not start com.apple.debugserver!\nPlease make sure to mount the developer disk image first.\n");
305 result = EXIT_FAILURE;
306 goto leave_cleanup;
307 }
308
309 if (idevice_connect(device, service->port, &connection) != IDEVICE_E_SUCCESS) {
310 fprintf(stderr, "Connection to debugserver port %d failed!\n", (int)service->port);
311 result = EXIT_FAILURE;
312 goto leave_cleanup;
313 }
314
315 /* free lockdown connection if running as it is not needed anymore */
316 if (lockdown) {
317 lockdownd_client_free(lockdown);
318 lockdown = NULL;
319 }
320
321 /* setup and create socket endpoint */
322 socket_info_t socket_info;
323
324 socket_info.device_connection = connection;
325 socket_info.local_port = local_port;
326 socket_info.remote_port = service->port;
327
328 if (service) {
329 lockdownd_service_descriptor_free(service);
330 service = NULL;
331 }
332
333 /* create local socket */ 315 /* create local socket */
334 socket_info.server_fd = socket_create(socket_info.local_port); 316 global_socket_info.server_fd = socket_create(global_socket_info.local_port);
335 if (socket_info.server_fd < 0) { 317 if (global_socket_info.server_fd < 0) {
336 fprintf(stderr, "Could not create socket\n"); 318 fprintf(stderr, "Could not create socket\n");
337 result = EXIT_FAILURE; 319 result = EXIT_FAILURE;
338 goto leave_cleanup; 320 goto leave_cleanup;
339 } 321 }
340 322
341 while (!quit_flag) { 323 while (!quit_flag) {
342 debug("%s: Waiting for connection on local port %d\n", __func__, socket_info.local_port); 324 debug("%s: Waiting for connection on local port %d\n", __func__, global_socket_info.local_port);
343 325
344 /* wait for client */ 326 /* wait for client */
345 socket_info.client_fd = socket_accept(socket_info.server_fd, socket_info.local_port); 327 global_socket_info.client_fd = socket_accept(global_socket_info.server_fd, global_socket_info.local_port);
346 if (socket_info.client_fd < 0) { 328 if (global_socket_info.client_fd < 0) {
347 debug("%s: Continuing...\n", __func__);
348 continue; 329 continue;
349 } 330 }
350 331
351 debug("%s: Handling new client connection...\n", __func__); 332 debug("%s: Handling new client connection...\n", __func__);
352 333
353 if (thread_new(&th, connection_handler, (void*)&socket_info) != 0) { 334 if (thread_new(&th, connection_handler, (void*)&global_socket_info) != 0) {
354 fprintf(stderr, "Could not start connection handler.\n"); 335 fprintf(stderr, "Could not start connection handler.\n");
355 socket_shutdown(socket_info.server_fd, SHUT_RDWR); 336 socket_shutdown(global_socket_info.server_fd, SHUT_RDWR);
356 socket_close(socket_info.server_fd); 337 socket_close(global_socket_info.server_fd);
357 continue; 338 continue;
358 } 339 }
359 340
@@ -364,14 +345,8 @@ int main(int argc, char *argv[])
364 debug("%s: Shutting down debugserver proxy...\n", __func__); 345 debug("%s: Shutting down debugserver proxy...\n", __func__);
365 346
366leave_cleanup: 347leave_cleanup:
367 if (connection) { 348 if (global_socket_info.device) {
368 idevice_disconnect(connection); 349 idevice_free(global_socket_info.device);
369 }
370 if (lockdown) {
371 lockdownd_client_free(lockdown);
372 }
373 if (device) {
374 idevice_free(device);
375 } 350 }
376 351
377 return result; 352 return result;