diff options
author | Benjamin BOURGEAIS | 2021-05-06 17:35:16 +0200 |
---|---|---|
committer | Benjamin BOURGEAIS | 2021-05-08 14:16:50 +0200 |
commit | 7d24f8eb9e5fd32cee92746652a995ccd83e8401 (patch) | |
tree | feb4557e6b0061ea384090408afbce6ba8126bd0 /src | |
parent | fffe2e3972840f3a9be865f950383ebd41f5061d (diff) | |
download | idevicerestore-7d24f8eb9e5fd32cee92746652a995ccd83e8401.tar.gz idevicerestore-7d24f8eb9e5fd32cee92746652a995ccd83e8401.tar.bz2 |
dfu: Add helpers to send components and commands
Diffstat (limited to 'src')
-rw-r--r-- | src/dfu.c | 75 |
1 files changed, 75 insertions, 0 deletions
@@ -331,6 +331,81 @@ int dfu_get_sep_nonce(struct idevicerestore_client_t* client, unsigned char** no return 0; } +int dfu_send_component_and_command(struct idevicerestore_client_t* client, plist_t build_identity, const char* component, const char* command) +{ + irecv_error_t dfu_error = IRECV_E_SUCCESS; + + if (dfu_send_component(client, build_identity, component) < 0) { + error("ERROR: Unable to send %s to device.\n", component); + return -1; + } + + info("INFO: executing command: %s\n", command); + dfu_error = irecv_send_command(client->dfu->client, command); + if (dfu_error != IRECV_E_SUCCESS) { + error("ERROR: Unable to execute %s\n", command); + return -1; + } + + return 0; +} + +int dfu_send_command(struct idevicerestore_client_t* client, const char* command) +{ + irecv_error_t dfu_error = IRECV_E_SUCCESS; + + info("INFO: executing command: %s\n", command); + dfu_error = irecv_send_command(client->dfu->client, command); + if (dfu_error != IRECV_E_SUCCESS) { + error("ERROR: Unable to execute %s\n", command); + return -1; + } + + return 0; +} + +int dfu_send_iboot_stage1_components(struct idevicerestore_client_t* client, plist_t build_identity) +{ + plist_t manifest_node = plist_dict_get_item(build_identity, "Manifest"); + if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { + error("ERROR: Unable to find manifest node\n"); + return -1; + } + + plist_dict_iter iter = NULL; + plist_dict_new_iter(manifest_node, &iter); + int err = 0; + while (iter) { + char *key = NULL; + plist_t node = NULL; + plist_dict_next_item(manifest_node, iter, &key, &node); + if (key == NULL) + break; + + plist_t iboot_node = plist_access_path(node, 2, "Info", "IsLoadedByiBoot"); + plist_t iboot_stg1_node = plist_access_path(node, 2, "Info", "IsLoadedByiBootStage1"); + uint8_t is_stg1 = 0; + if (iboot_stg1_node && plist_get_node_type(iboot_stg1_node) == PLIST_BOOLEAN) { + plist_get_bool_val(iboot_stg1_node, &is_stg1); + } + if (iboot_node && plist_get_node_type(iboot_node) == PLIST_BOOLEAN && is_stg1) { + uint8_t b = 0; + plist_get_bool_val(iboot_node, &b); + if (b) { + debug("DEBUG: %s is loaded by iBoot Stage 1.\n", key); + if (dfu_send_component_and_command(client, build_identity, key, "firmware") < 0) { + error("ERROR: Unable to send component '%s' to device.\n", key); + err++; + } + } + } + free(key); + } + free(iter); + + return (err) ? -1 : 0; +} + int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_identity) { int mode = 0; |