int asr_open_with_timeout(idevice_t device, idevice_connection_t* asr) { int i = 0; int attempts = 10; idevice_connection_t connection = NULL; idevice_error_t device_error = IDEVICE_E_SUCCESS; *asr = NULL; if (device == NULL) { return -1; } debug("Connecting to ASR\n"); for (i = 1; i <= attempts; i++) { device_error = idevice_connect(device, ASR_PORT, &connection); if (device_error == IDEVICE_E_SUCCESS) { break; } if (i >= attempts) { error("ERROR: Unable to connect to ASR client\n"); return -1; } sleep(2); debug("Retrying connection...\n"); } *asr = connection; return 0; }
service_error_t service_client_new(idevice_t device, lockdownd_service_descriptor_t service, service_client_t *client) { if (!device || !service || service->port == 0 || !client || *client) return SERVICE_E_INVALID_ARG; /* Attempt connection */ idevice_connection_t connection = NULL; if (idevice_connect(device, service->port, &connection) != IDEVICE_E_SUCCESS) { return SERVICE_E_MUX_ERROR; } /* create client object */ service_client_t client_loc = (service_client_t)malloc(sizeof(struct service_client_private)); client_loc->connection = connection; /* enable SSL if requested */ if (service->ssl_enabled == 1) { service_error_t result = service_enable_ssl(client_loc); if (SERVICE_E_SUCCESS != result) { service_client_free(client_loc); return result; } } /* all done, return success */ *client = client_loc; return SERVICE_E_SUCCESS; }
SWIGEXPORT jshort JNICALL Java_org_robovm_libimobiledevice_binding_libimobiledeviceJNI_idevice_1connect(JNIEnv *jenv, jclass jcls, jlong jarg1, jshort jarg2, jlong jarg3) { jshort jresult = 0 ; idevice_t arg1 = (idevice_t) 0 ; uint16_t arg2 ; idevice_connection_t *arg3 = (idevice_connection_t *) 0 ; idevice_error_t result; (void)jenv; (void)jcls; arg1 = *(idevice_t *)&jarg1; arg2 = (uint16_t)jarg2; arg3 = *(idevice_connection_t **)&jarg3; result = (idevice_error_t)idevice_connect(arg1,arg2,arg3); jresult = (jshort)result; return jresult; }
/** * Makes a connection to the AFC service on the device. * This function calls afc_client_new_from_connection() after creating * a connection to the specified device and port. * * @see afc_client_new_from_connection * * @param device The device to connect to. * @param port The destination port. * @param client Pointer that will be set to a newly allocated afc_client_t * upon successful return. * * @return AFC_E_SUCCESS on success, AFC_E_INVALID_ARG if device or port is * invalid, AFC_E_MUX_ERROR if the connection cannot be established, * or AFC_E_NO_MEM if there is a memory allocation problem. */ afc_error_t afc_client_new(idevice_t device, uint16_t port, afc_client_t * client) { if (!device || port==0) return AFC_E_INVALID_ARG; /* attempt connection */ idevice_connection_t connection = NULL; if (idevice_connect(device, port, &connection) != IDEVICE_E_SUCCESS) { return AFC_E_MUX_ERROR; } afc_error_t err = afc_client_new_from_connection(connection, client); if (err != AFC_E_SUCCESS) { idevice_disconnect(connection); } else { (*client)->own_connection = 1; } return err; }
/** * Creates a new property list service for the specified port. * * @param device The device to connect to. * @param port The port on the device to connect to, usually opened by a call to * lockdownd_start_service. * @param client Pointer that will be set to a newly allocated * property_list_service_client_t upon successful return. * * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, * PROPERTY_LIST_SERVICE_E_INVALID_ARG when one of the arguments is invalid, * or PROPERTY_LIST_SERVICE_E_MUX_ERROR when connecting to the device failed. */ property_list_service_error_t property_list_service_client_new(idevice_t device, uint16_t port, property_list_service_client_t *client) { if (!device || port == 0 || !client || *client) return PROPERTY_LIST_SERVICE_E_INVALID_ARG; /* Attempt connection */ idevice_connection_t connection = NULL; if (idevice_connect(device, port, &connection) != IDEVICE_E_SUCCESS) { return PROPERTY_LIST_SERVICE_E_MUX_ERROR; } /* create client object */ property_list_service_client_t client_loc = (property_list_service_client_t)malloc(sizeof(struct property_list_service_client_private)); client_loc->connection = connection; *client = client_loc; return PROPERTY_LIST_SERVICE_E_SUCCESS; }
static int rproxy_create_connection(idevice_t device, uint16_t port, const char * start_msg, idevice_connection_t * connection) { idevice_connection_t new_connection = NULL; /* Connect to the proxt port on the device */ if (IDEVICE_E_SUCCESS != idevice_connect(device, port, &new_connection)) { goto cleanup; } /* Send the start string, including the null terminator */ uint32_t msg_size = strlen(start_msg) + 1; if (IDEVICE_E_SUCCESS != idevice_connection_send_all(new_connection, start_msg, msg_size)) { goto cleanup; } *connection = new_connection; return 0; cleanup: if (new_connection) { idevice_disconnect(new_connection); } return -1; }
int main(int argc, char *argv[]) { lockdownd_client_t lockdown = NULL; idevice_t device = NULL; idevice_connection_t connection = NULL; idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; thread_t th; const char* udid = NULL; lockdownd_service_descriptor_t service = NULL; uint16_t local_port = 0; int result = EXIT_SUCCESS; int i; /* bind signals */ signal(SIGINT, clean_exit); signal(SIGTERM, clean_exit); #ifndef WIN32 signal(SIGQUIT, clean_exit); signal(SIGPIPE, SIG_IGN); #endif /* parse cmdline arguments */ for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { debug_mode = 1; idevice_set_debug_level(1); socket_set_verbose(3); continue; } else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { i++; if (!argv[i] || (strlen(argv[i]) != 40)) { print_usage(argc, argv); return 0; } udid = argv[i]; continue; } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { print_usage(argc, argv); return EXIT_SUCCESS; } else if (atoi(argv[i]) > 0) { local_port = atoi(argv[i]); continue; } else { print_usage(argc, argv); return EXIT_SUCCESS; } } /* a PORT is mandatory */ if (!local_port) { fprintf(stderr, "Please specify a PORT.\n"); print_usage(argc, argv); goto leave_cleanup; } /* start services and connect to device */ ret = idevice_new(&device, udid); if (ret != IDEVICE_E_SUCCESS) { if (udid) { fprintf(stderr, "No device found with udid %s, is it plugged in?\n", udid); } else { fprintf(stderr, "No device found, is it plugged in?\n"); } result = EXIT_FAILURE; goto leave_cleanup; } if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(device, &lockdown, "idevicedebugserverproxy")) { fprintf(stderr, "Could not connect to lockdownd. Exiting.\n"); result = EXIT_FAILURE; goto leave_cleanup; } if ((lockdownd_start_service(lockdown, "com.apple.debugserver", &service) != LOCKDOWN_E_SUCCESS) || !service || !service->port) { fprintf(stderr, "Could not start com.apple.debugserver!\nPlease make sure to mount the developer disk image first.\n"); result = EXIT_FAILURE; goto leave_cleanup; } if (idevice_connect(device, service->port, &connection) != IDEVICE_E_SUCCESS) { fprintf(stderr, "Connection to debugserver port %d failed!\n", (int)service->port); result = EXIT_FAILURE; goto leave_cleanup; } /* free lockdown connection if running as it is not needed anymore */ if (lockdown) { lockdownd_client_free(lockdown); lockdown = NULL; } /* setup and create socket endpoint */ socket_info_t socket_info; socket_info.device_connection = connection; socket_info.local_port = local_port; socket_info.remote_port = service->port; if (service) { lockdownd_service_descriptor_free(service); service = NULL; } /* create local socket */ socket_info.server_fd = socket_create(socket_info.local_port); if (socket_info.server_fd < 0) { fprintf(stderr, "Could not create socket\n"); result = EXIT_FAILURE; goto leave_cleanup; } while (!quit_flag) { debug("%s: Waiting for connection on local port %d\n", __func__, socket_info.local_port); /* wait for client */ socket_info.client_fd = socket_accept(socket_info.server_fd, socket_info.local_port); if (socket_info.client_fd < 0) { debug("%s: Continuing...\n", __func__); continue; } debug("%s: Handling new client connection...\n", __func__); if (thread_create(&th, connection_handler, (void*)&socket_info) != 0) { fprintf(stderr, "Could not start connection handler.\n"); socket_shutdown(socket_info.server_fd, SHUT_RDWR); socket_close(socket_info.server_fd); } } debug("%s: Shutting down debugserver proxy...\n", __func__); leave_cleanup: if (connection) { idevice_disconnect(connection); } if (lockdown) { lockdownd_client_free(lockdown); } if (device) { idevice_free(device); } return result; }
int main(int argc, char* argv[]) { idevice_t device = NULL; lockdownd_client_t lockdownd = NULL; afc_client_t afc = NULL; idevice_error_t device_error = IDEVICE_E_SUCCESS; lockdownd_error_t lockdownd_error = LOCKDOWN_E_SUCCESS; afc_error_t afc_error = AFC_E_SUCCESS; int i; const char* udid = NULL; /* parse cmdline args */ for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { idevice_set_debug_level(1); continue; } else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { i++; if (!argv[i] || (strlen(argv[i]) != 40)) { print_usage(argc, argv); return 0; } udid = argv[i]; continue; } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { print_usage(argc, argv); return 0; } else if (!strcmp(argv[i], "-e") || !strcmp(argv[i], "--extract")) { extract_raw_crash_reports = 1; continue; } else if (!strcmp(argv[i], "-k") || !strcmp(argv[i], "--keep")) { keep_crash_reports = 1; continue; } else if (target_directory == NULL) { target_directory = argv[i]; continue; } else { print_usage(argc, argv); return 0; } } /* ensure a target directory was supplied */ if (!target_directory) { print_usage(argc, argv); return 0; } /* check if target directory exists */ if (!file_exists(target_directory)) { fprintf(stderr, "ERROR: Directory '%s' does not exist.\n", target_directory); print_usage(argc, argv); return 0; } device_error = idevice_new(&device, udid); if (device_error != IDEVICE_E_SUCCESS) { if (udid) { printf("No device found with udid %s, is it plugged in?\n", udid); } else { printf("No device found, is it plugged in?\n"); } return -1; } lockdownd_error = lockdownd_client_new_with_handshake(device, &lockdownd, "idevicecrashreport"); if (lockdownd_error != LOCKDOWN_E_SUCCESS) { fprintf(stderr, "ERROR: Could not connect to lockdownd, error code %d\n", lockdownd_error); idevice_free(device); return -1; } /* start crash log mover service */ lockdownd_service_descriptor_t service = NULL; lockdownd_error = lockdownd_start_service(lockdownd, "com.apple.crashreportmover", &service); if (lockdownd_error != LOCKDOWN_E_SUCCESS) { lockdownd_client_free(lockdownd); idevice_free(device); return -1; } /* trigger move operation on device */ idevice_connection_t connection = NULL; device_error = idevice_connect(device, service->port, &connection); if(device_error != IDEVICE_E_SUCCESS) { lockdownd_client_free(lockdownd); idevice_free(device); return -1; } /* read "ping" message which indicates the crash logs have been moved to a safe harbor */ char *ping = malloc(4); int attempts = 0; while ((strncmp(ping, "ping", 4) != 0) && (attempts > 10)) { uint32_t bytes = 0; device_error = idevice_connection_receive_timeout(connection, ping, 4, &bytes, 2000); if ((bytes == 0) && (device_error == IDEVICE_E_SUCCESS)) { attempts++; continue; } else if (device_error < 0) { fprintf(stderr, "ERROR: Crash logs could not be moved. Connection interrupted.\n"); break; } } idevice_disconnect(connection); free(ping); if (service) { lockdownd_service_descriptor_free(service); service = NULL; } if (device_error != IDEVICE_E_SUCCESS || attempts > 10) { fprintf(stderr, "ERROR: Failed to receive ping message from crash report mover.\n"); lockdownd_client_free(lockdownd); idevice_free(device); return -1; } lockdownd_error = lockdownd_start_service(lockdownd, "com.apple.crashreportcopymobile", &service); if (lockdownd_error != LOCKDOWN_E_SUCCESS) { lockdownd_client_free(lockdownd); idevice_free(device); return -1; } lockdownd_client_free(lockdownd); afc = NULL; afc_error = afc_client_new(device, service, &afc); if(afc_error != AFC_E_SUCCESS) { lockdownd_client_free(lockdownd); idevice_free(device); return -1; } if (service) { lockdownd_service_descriptor_free(service); service = NULL; } /* recursively copy crash reports from the device to a local directory */ if (afc_client_copy_and_remove_crash_reports(afc, ".", target_directory) < 0) { fprintf(stderr, "ERROR: Failed to get crash reports from device.\n"); afc_client_free(afc); idevice_free(device); return -1; } printf("Done.\n"); afc_client_free(afc); idevice_free(device); return 0; }
int asr_open_with_timeout(idevice_t device, asr_client_t* asr) { int i = 0; int attempts = 10; idevice_connection_t connection = NULL; idevice_error_t device_error = IDEVICE_E_SUCCESS; *asr = NULL; if (device == NULL) { return -1; } debug("Connecting to ASR\n"); for (i = 1; i <= attempts; i++) { device_error = idevice_connect(device, ASR_PORT, &connection); if (device_error == IDEVICE_E_SUCCESS) { break; } if (i >= attempts) { error("ERROR: Unable to connect to ASR client\n"); return -1; } sleep(2); debug("Retrying connection...\n"); } asr_client_t asr_loc = (asr_client_t)malloc(sizeof(struct asr_client)); memset(asr_loc, '\0', sizeof(struct asr_client)); asr_loc->connection = connection; /* receive Initiate command message */ plist_t data = NULL; asr_loc->checksum_chunks = 0; if (asr_receive(asr_loc, &data) < 0) { error("ERROR: Unable to receive data from ASR\n"); asr_free(asr_loc); plist_free(data); return -1; } plist_t node; node = plist_dict_get_item(data, "Command"); if (node && (plist_get_node_type(node) == PLIST_STRING)) { char* strval = NULL; plist_get_string_val(node, &strval); if (strval && (strcmp(strval, "Initiate") != 0)) { error("ERROR: unexpected ASR plist received:\n"); debug_plist(data); plist_free(data); asr_free(asr_loc); return -1; } } node = plist_dict_get_item(data, "Checksum Chunks"); if (node && (plist_get_node_type(node) == PLIST_BOOLEAN)) { plist_get_bool_val(node, &(asr_loc->checksum_chunks)); } plist_free(data); *asr = asr_loc; return 0; }
int wi_connect(const char *device_id, char **to_device_id, char **to_device_name, int recv_timeout) { int ret = -1; idevice_t phone = NULL; plist_t node = NULL; lockdownd_service_descriptor_t service = NULL; lockdownd_client_t client = NULL; idevice_connection_t connection = NULL; int fd = -1; // get phone if (idevice_new(&phone, device_id)) { perror("No iPhone found, is it plugged in?"); goto leave_cleanup; } // connect to lockdownd if (lockdownd_client_new_with_handshake( phone, &client, "ios_webkit_debug_proxy")) { perror("Could not connect to lockdownd. Exiting."); goto leave_cleanup; } // get device info if (to_device_id && !lockdownd_get_value(client, NULL, "UniqueDeviceID", &node)) { plist_get_string_val(node, to_device_id); plist_free(node); node = NULL; } if (to_device_name && !lockdownd_get_value(client, NULL, "DeviceName", &node)) { plist_get_string_val(node, to_device_name); } // start webinspector, get port if (lockdownd_start_service(client, "com.apple.webinspector", &service) || !service->port) { perror("Could not start com.apple.webinspector!"); goto leave_cleanup; } // connect to webinspector if (idevice_connect(phone, service->port, &connection)) { perror("idevice_connect failed!"); goto leave_cleanup; } if (client) { // not needed anymore lockdownd_client_free(client); client = NULL; } // extract the connection fd if (idevice_connection_get_fd(connection, &fd)) { perror("Unable to get connection file descriptor."); goto leave_cleanup; } if (recv_timeout < 0) { int opts = fcntl(fd, F_GETFL); if (!opts || fcntl(fd, F_SETFL, (opts | O_NONBLOCK)) < 0) { perror("Could not set socket to non-blocking"); goto leave_cleanup; } } else { long millis = (recv_timeout > 0 ? recv_timeout : 5000); struct timeval tv; tv.tv_sec = (time_t) (millis / 1000); tv.tv_usec = (time_t) ((millis - (tv.tv_sec * 1000)) * 1000); if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv))) { perror("Could not set socket receive timeout"); goto leave_cleanup; } } // success ret = fd; leave_cleanup: if (ret < 0 && fd > 0) { close(fd); } // don't call usbmuxd_disconnect(fd)! //idevice_disconnect(connection); free(connection); lockdownd_client_free(client); plist_free(node); idevice_free(phone); return ret; }