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;  		} | 
