summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Florian Brandstetter2024-09-21 00:13:37 +0200
committerGravatar Nikias Bassen2024-09-21 00:13:37 +0200
commit4145e9584980f2c2d994a1b543478b38156be5e7 (patch)
tree0e4ed5e0ee06e039162d78856c11379d08e9d52f /src
parenta31eb2bf5fb2b5df1468e2ec4d31bcdc584af7d1 (diff)
downloadidevicerestore-4145e9584980f2c2d994a1b543478b38156be5e7.tar.gz
idevicerestore-4145e9584980f2c2d994a1b543478b38156be5e7.tar.bz2
asr: Add support for second Initiate request
First observed in iBridgeOS 9.0. The first Initiate ASR packet (checksum_chunks = false) requests 64 bytes of the IPSW at offset 0, after which another Initiate follows requesting a switch to (checksum_chunks = true) and additional OOBData.
Diffstat (limited to 'src')
-rw-r--r--src/asr.c59
1 files changed, 43 insertions, 16 deletions
diff --git a/src/asr.c b/src/asr.c
index b150e85..8463f0d 100644
--- a/src/asr.c
+++ b/src/asr.c
@@ -202,23 +202,12 @@ void asr_free(asr_client_t asr)
}
}
-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;
- plist_t packet_info = NULL;
- plist_t payload_info = NULL;
- int attempts = 0;
-
- length = ipsw_file_size(file);
-
- payload_info = plist_new_dict();
+int asr_send_validation_packet_info(asr_client_t asr, uint64_t ipsw_size) {
+ 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,11 +219,30 @@ 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);
+ plist_free(payload_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) {
+ error("ERROR: Unable to send validation packet info to ASR\n");
+ return -1;
+ }
while (1) {
if (asr_receive(asr, &packet) < 0) {
@@ -260,6 +268,25 @@ int asr_perform_validation(asr_client_t asr, ipsw_file_handle_t file)
}
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) {
+ error("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);