summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2012-07-04 13:28:27 +0200
committerGravatar Nikias Bassen2012-07-04 13:28:27 +0200
commit51489dbb69a4e4a0131a74b34235152f131588d1 (patch)
tree5f5e35bca7d8d8a201faba99c4006d821d6b2ac1
parent1f2f0141bd5fc0cdc4eb311261766eb0b8716c88 (diff)
downloadlibirecovery-51489dbb69a4e4a0131a74b34235152f131588d1.tar.gz
libirecovery-51489dbb69a4e4a0131a74b34235152f131588d1.tar.bz2
add support for targeting a device by ECID
-rw-r--r--include/libirecovery.h4
-rw-r--r--libirecovery.c52
2 files changed, 44 insertions, 12 deletions
diff --git a/include/libirecovery.h b/include/libirecovery.h
index 3422f9d..b524cd3 100644
--- a/include/libirecovery.h
+++ b/include/libirecovery.h
@@ -186,8 +186,8 @@ static struct irecv_device irecv_devices[] = {
void irecv_set_debug_level(int level);
const char* irecv_strerror(irecv_error_t error);
-irecv_error_t irecv_open_attempts(irecv_client_t* pclient, int attempts);
-irecv_error_t irecv_open(irecv_client_t* client);
+irecv_error_t irecv_open_attempts(irecv_client_t* pclient, unsigned long long ecid, int attempts);
+irecv_error_t irecv_open(irecv_client_t* client, unsigned long long ecid);
irecv_error_t irecv_reset(irecv_client_t client);
irecv_error_t irecv_close(irecv_client_t client);
irecv_error_t irecv_receive(irecv_client_t client);
diff --git a/libirecovery.c b/libirecovery.c
index 2385174..18763ed 100644
--- a/libirecovery.c
+++ b/libirecovery.c
@@ -384,7 +384,7 @@ int irecv_get_string_descriptor_ascii(irecv_client_t client, uint8_t desc_index,
#endif
}
-irecv_error_t irecv_open(irecv_client_t* pclient) {
+irecv_error_t irecv_open(irecv_client_t* pclient, unsigned long long ecid) {
#ifndef WIN32
int i = 0;
struct libusb_device* usb_device = NULL;
@@ -411,19 +411,28 @@ irecv_error_t irecv_open(irecv_client_t* pclient) {
usb_descriptor.idProduct == kWTFMode ||
usb_descriptor.idProduct == kDfuMode) {
+ if ((ecid != 0) && (usb_descriptor.idProduct == kWTFMode)) {
+ // we can't get ecid in WTF mode
+ continue;
+ }
+
debug("opening device %04x:%04x...\n", usb_descriptor.idVendor, usb_descriptor.idProduct);
libusb_open(usb_device, &usb_handle);
if (usb_handle == NULL) {
- libusb_free_device_list(usb_device_list, 1);
+ debug("%s: can't connect to device...\n", __func__);
libusb_close(usb_handle);
+ if (ecid != 0) {
+ continue;
+ }
+ libusb_free_device_list(usb_device_list, 1);
libusb_exit(libirecovery_context);
return IRECV_E_UNABLE_TO_CONNECT;
}
- libusb_free_device_list(usb_device_list, 1);
irecv_client_t client = (irecv_client_t) malloc(sizeof(struct irecv_client));
if (client == NULL) {
+ libusb_free_device_list(usb_device_list, 1);
libusb_close(usb_handle);
libusb_exit(libirecovery_context);
return IRECV_E_OUT_OF_MEMORY;
@@ -433,7 +442,26 @@ irecv_error_t irecv_open(irecv_client_t* pclient) {
client->interface = 0;
client->handle = usb_handle;
client->mode = usb_descriptor.idProduct;
-
+
+ /* cache usb serial */
+ irecv_get_string_descriptor_ascii(client, usb_descriptor.iSerialNumber, (unsigned char*) client->serial, 255);
+
+ if (ecid != 0) {
+ char* ecid_string = strstr(client->serial, "ECID:");
+ if (ecid_string == NULL) {
+ debug("%s: could not get ECID for device\n", __func__);
+ irecv_close(client);
+ continue;
+ }
+
+ unsigned long long this_ecid = 0;
+ sscanf(ecid_string, "ECID:%qX", (unsigned long long*)&this_ecid);
+ if (this_ecid != ecid) {
+ irecv_close(client);
+ continue;
+ }
+ debug("found device with ECID %016llx\n", (unsigned long long)ecid);
+ }
error = irecv_set_configuration(client, 1);
if (error != IRECV_E_SUCCESS) {
@@ -453,9 +481,6 @@ irecv_error_t irecv_open(irecv_client_t* pclient) {
return error;
}
- /* cache usb serial */
- irecv_get_string_descriptor_ascii(client, usb_descriptor.iSerialNumber, (unsigned char*) client->serial, 255);
-
*pclient = client;
return IRECV_E_SUCCESS;
}
@@ -529,11 +554,15 @@ irecv_error_t irecv_reset(irecv_client_t client) {
return IRECV_E_SUCCESS;
}
-irecv_error_t irecv_open_attempts(irecv_client_t* pclient, int attempts) {
+irecv_error_t irecv_open_attempts(irecv_client_t* pclient, unsigned long long ecid, int attempts) {
int i;
for (i = 0; i < attempts; i++) {
- if (irecv_open(pclient) != IRECV_E_SUCCESS) {
+ if(*pclient) {
+ irecv_close(*pclient);
+ *pclient = NULL;
+ }
+ if (irecv_open(pclient, ecid) != IRECV_E_SUCCESS) {
debug("Connection failed. Waiting 1 sec before retry.\n");
sleep(1);
} else {
@@ -1390,6 +1419,9 @@ irecv_client_t irecv_reconnect(irecv_client_t client, int initial_pause) {
irecv_client_t new_client = NULL;
irecv_event_cb_t progress_callback = client->progress_callback;
+ unsigned long long ecid = 0;
+ irecv_get_ecid(client, &ecid);
+
if (check_context(client) == IRECV_E_SUCCESS) {
irecv_close(client);
}
@@ -1399,7 +1431,7 @@ irecv_client_t irecv_reconnect(irecv_client_t client, int initial_pause) {
sleep(initial_pause);
}
- error = irecv_open_attempts(&new_client, 10);
+ error = irecv_open_attempts(&new_client, ecid, 10);
if(error != IRECV_E_SUCCESS) {
return NULL;
}