summaryrefslogtreecommitdiffstats
path: root/src/asr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/asr.c')
-rw-r--r--src/asr.c108
1 files changed, 67 insertions, 41 deletions
diff --git a/src/asr.c b/src/asr.c
index b150e85..e140980 100644
--- a/src/asr.c
+++ b/src/asr.c
@@ -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;
}