diff options
Diffstat (limited to 'src/asr.c')
-rw-r--r-- | src/asr.c | 108 |
1 files changed, 67 insertions, 41 deletions
@@ -63,7 +63,7 @@ int asr_open_with_timeout(idevice_t device, asr_client_t* asr, uint16_t port) if (port == 0) { port = ASR_DEFAULT_PORT; } - debug("Connecting to ASR on port %u\n", port); + logger(LL_VERBOSE, "Connecting to ASR on port %u\n", port); for (i = 1; i <= attempts; i++) { device_error = idevice_connect(device, port, &connection); @@ -72,12 +72,12 @@ int asr_open_with_timeout(idevice_t device, asr_client_t* asr, uint16_t port) } if (i >= attempts) { - error("ERROR: Unable to connect to ASR client\n"); + logger(LL_ERROR, "Unable to connect to ASR client\n"); return -1; } sleep(2); - debug("Retrying connection...\n"); + logger(LL_VERBOSE, "Retrying connection...\n"); } asr_client_t asr_loc = (asr_client_t)malloc(sizeof(struct asr_client)); @@ -88,7 +88,7 @@ int asr_open_with_timeout(idevice_t device, asr_client_t* asr, uint16_t port) 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"); + logger(LL_ERROR, "Unable to receive data from ASR\n"); asr_free(asr_loc); plist_free(data); return -1; @@ -99,8 +99,8 @@ int asr_open_with_timeout(idevice_t device, asr_client_t* asr, uint16_t port) 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); + logger(LL_ERROR, "Unexpected ASR plist received\n"); + logger_dump_plist(LL_VERBOSE, data, 1); plist_free(data); asr_free(asr_loc); return -1; @@ -138,13 +138,13 @@ int asr_receive(asr_client_t asr, plist_t* data) buffer = (char*)malloc(ASR_BUFFER_SIZE); if (buffer == NULL) { - error("ERROR: Unable to allocate memory for ASR receive buffer\n"); + logger(LL_ERROR, "Unable to allocate memory for ASR receive buffer\n"); return -1; } device_error = idevice_connection_receive(asr->connection, buffer, ASR_BUFFER_SIZE, &size); if (device_error != IDEVICE_E_SUCCESS) { - error("ERROR: Unable to receive data from ASR\n"); + logger(LL_ERROR, "Unable to receive data from ASR\n"); free(buffer); return -1; } @@ -152,9 +152,8 @@ int asr_receive(asr_client_t asr, plist_t* data) *data = request; - debug("Received %d bytes:\n", size); - if (idevicerestore_debug) - debug_plist(request); + logger(LL_DEBUG, "Received %d bytes:\n", size); + logger_dump_plist(LL_DEBUG, request, 1); free(buffer); return 0; } @@ -166,7 +165,7 @@ int asr_send(asr_client_t asr, plist_t data) plist_to_xml(data, &buffer, &size); if (asr_send_buffer(asr, buffer, size) < 0) { - error("ERROR: Unable to send plist to ASR\n"); + logger(LL_ERROR, "Unable to send plist to ASR\n"); free(buffer); return -1; } @@ -176,14 +175,14 @@ int asr_send(asr_client_t asr, plist_t data) return 0; } -int asr_send_buffer(asr_client_t asr, const char* data, uint32_t size) +int asr_send_buffer(asr_client_t asr, const void* data, size_t size) { uint32_t bytes = 0; idevice_error_t device_error = IDEVICE_E_SUCCESS; device_error = idevice_connection_send(asr->connection, data, size, &bytes); if (device_error != IDEVICE_E_SUCCESS || bytes != size) { - error("ERROR: Unable to send data to ASR. Sent %u of %u bytes.\n", bytes, size); + logger(LL_ERROR, "Unable to send data to ASR. Sent %u of %zu bytes.\n", bytes, size); return -1; } @@ -202,23 +201,13 @@ void asr_free(asr_client_t asr) } } -int asr_perform_validation(asr_client_t asr, ipsw_file_handle_t file) +int asr_send_validation_packet_info(asr_client_t asr, uint64_t ipsw_size) { - uint64_t length = 0; - char* command = NULL; - plist_t node = NULL; - plist_t packet = NULL; - plist_t packet_info = NULL; - plist_t payload_info = NULL; - int attempts = 0; - - length = ipsw_file_size(file); - - payload_info = plist_new_dict(); + plist_t payload_info = plist_new_dict(); plist_dict_set_item(payload_info, "Port", plist_new_uint(1)); - plist_dict_set_item(payload_info, "Size", plist_new_uint(length)); + plist_dict_set_item(payload_info, "Size", plist_new_uint(ipsw_size)); - packet_info = plist_new_dict(); + plist_t packet_info = plist_new_dict(); if (asr->checksum_chunks) { plist_dict_set_item(packet_info, "Checksum Chunk Size", plist_new_uint(ASR_CHECKSUM_CHUNK_SIZE)); } @@ -230,21 +219,39 @@ int asr_perform_validation(asr_client_t asr, ipsw_file_handle_t file) plist_dict_set_item(packet_info, "Version", plist_new_uint(ASR_VERSION)); if (asr_send(asr, packet_info)) { - error("ERROR: Unable to sent packet information to ASR\n"); plist_free(packet_info); return -1; } plist_free(packet_info); + return 0; +} + +int asr_perform_validation(asr_client_t asr, ipsw_file_handle_t file) +{ + uint64_t length = 0; + char* command = NULL; + plist_t node = NULL; + plist_t packet = NULL; + int attempts = 0; + + length = ipsw_file_size(file); + + // Expected by device after every initiate + if (asr_send_validation_packet_info(asr, length) < 0) { + logger(LL_ERROR, "Unable to send validation packet info to ASR\n"); + return -1; + } + while (1) { if (asr_receive(asr, &packet) < 0) { - error("ERROR: Unable to receive validation packet\n"); + logger(LL_ERROR, "Unable to receive validation packet\n"); return -1; } if (packet == NULL) { if (attempts < 5) { - info("Retrying to receive validation packet... %d\n", attempts); + logger(LL_INFO, "Retrying to receive validation packet... %d\n", attempts); attempts++; sleep(1); continue; @@ -255,11 +262,30 @@ int asr_perform_validation(asr_client_t asr, ipsw_file_handle_t file) node = plist_dict_get_item(packet, "Command"); if (!node || plist_get_node_type(node) != PLIST_STRING) { - error("ERROR: Unable to find command node in validation request\n"); + logger(LL_ERROR, "Unable to find command node in validation request\n"); return -1; } plist_get_string_val(node, &command); + // Added for iBridgeOS 9.0 - second initiate request to change to checksum chunks + if (!strcmp(command, "Initiate")) { + // This might switch on the second Initiate + node = plist_dict_get_item(packet, "Checksum Chunks"); + if (node && (plist_get_node_type(node) == PLIST_BOOLEAN)) { + plist_get_bool_val(node, &(asr->checksum_chunks)); + } + plist_free(packet); + + // Expected by device after every Initiate + if (asr_send_validation_packet_info(asr, length) < 0) { + logger(LL_ERROR, "Unable to send validation packet info to ASR\n"); + return -1; + } + + // A OOBData request should follow + continue; + } + if (!strcmp(command, "OOBData")) { int ret = asr_handle_oob_data_request(asr, packet, file); plist_free(packet); @@ -270,7 +296,7 @@ int asr_perform_validation(asr_client_t asr, ipsw_file_handle_t file) break; } else { - error("ERROR: Unknown command received from ASR\n"); + logger(LL_ERROR, "Unknown command received from ASR\n"); plist_free(packet); return -1; } @@ -289,38 +315,38 @@ int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, ipsw_file_hand oob_length_node = plist_dict_get_item(packet, "OOB Length"); if (!oob_length_node || PLIST_UINT != plist_get_node_type(oob_length_node)) { - error("ERROR: Unable to find OOB data length\n"); + logger(LL_ERROR, "Unable to find OOB data length\n"); return -1; } plist_get_uint_val(oob_length_node, &oob_length); oob_offset_node = plist_dict_get_item(packet, "OOB Offset"); if (!oob_offset_node || PLIST_UINT != plist_get_node_type(oob_offset_node)) { - error("ERROR: Unable to find OOB data offset\n"); + logger(LL_ERROR, "Unable to find OOB data offset\n"); return -1; } plist_get_uint_val(oob_offset_node, &oob_offset); oob_data = (char*) malloc(oob_length); if (oob_data == NULL) { - error("ERROR: Out of memory\n"); + logger(LL_ERROR, "Out of memory\n"); return -1; } if (ipsw_file_seek(file, oob_offset, SEEK_SET) < 0) { - error("ERROR: Unable to seek to OOB offset 0x%" PRIx64 "\n", oob_offset); + logger(LL_ERROR, "Unable to seek to OOB offset 0x%" PRIx64 "\n", oob_offset); free(oob_data); return -1; } int64_t ir = ipsw_file_read(file, oob_data, oob_length); if (ir != oob_length) { - error("ERROR: Unable to read OOB data from filesystem offset 0x%" PRIx64 ", oob_length %" PRIu64 ", read returned %" PRIi64"\n", oob_offset, oob_length, ir); + logger(LL_ERROR, "Unable to read OOB data from filesystem offset 0x%" PRIx64 ", oob_length %" PRIu64 ", read returned %" PRIi64"\n", oob_offset, oob_length, ir); free(oob_data); return -1; } if (asr_send_buffer(asr, oob_data, oob_length) < 0) { - error("ERROR: Unable to send OOB data to ASR\n"); + logger(LL_ERROR, "Unable to send OOB data to ASR\n"); free(oob_data); return -1; } @@ -350,7 +376,7 @@ int asr_send_payload(asr_client_t asr, ipsw_file_handle_t file) } if (ipsw_file_read(file, data, size) != (int64_t)size) { - error("Error reading filesystem\n"); + logger(LL_ERROR, "Error reading filesystem\n"); retry--; continue; } @@ -361,7 +387,7 @@ int asr_send_payload(asr_client_t asr, ipsw_file_handle_t file) sendsize += 20; } if (asr_send_buffer(asr, data, sendsize) < 0) { - error("Unable to send filesystem payload chunk, retrying...\n"); + logger(LL_ERROR, "Unable to send filesystem payload chunk, retrying...\n"); retry--; continue; } |