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[] = {
186 186
187void irecv_set_debug_level(int level); 187void irecv_set_debug_level(int level);
188const char* irecv_strerror(irecv_error_t error); 188const char* irecv_strerror(irecv_error_t error);
189irecv_error_t irecv_open_attempts(irecv_client_t* pclient, int attempts); 189irecv_error_t irecv_open_attempts(irecv_client_t* pclient, unsigned long long ecid, int attempts);
190irecv_error_t irecv_open(irecv_client_t* client); 190irecv_error_t irecv_open(irecv_client_t* client, unsigned long long ecid);
191irecv_error_t irecv_reset(irecv_client_t client); 191irecv_error_t irecv_reset(irecv_client_t client);
192irecv_error_t irecv_close(irecv_client_t client); 192irecv_error_t irecv_close(irecv_client_t client);
193irecv_error_t irecv_receive(irecv_client_t client); 193irecv_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,
384#endif 384#endif
385} 385}
386 386
387irecv_error_t irecv_open(irecv_client_t* pclient) { 387irecv_error_t irecv_open(irecv_client_t* pclient, unsigned long long ecid) {
388#ifndef WIN32 388#ifndef WIN32
389 int i = 0; 389 int i = 0;
390 struct libusb_device* usb_device = NULL; 390 struct libusb_device* usb_device = NULL;
@@ -411,19 +411,28 @@ irecv_error_t irecv_open(irecv_client_t* pclient) {
411 usb_descriptor.idProduct == kWTFMode || 411 usb_descriptor.idProduct == kWTFMode ||
412 usb_descriptor.idProduct == kDfuMode) { 412 usb_descriptor.idProduct == kDfuMode) {
413 413
414 if ((ecid != 0) && (usb_descriptor.idProduct == kWTFMode)) {
415 // we can't get ecid in WTF mode
416 continue;
417 }
418
414 debug("opening device %04x:%04x...\n", usb_descriptor.idVendor, usb_descriptor.idProduct); 419 debug("opening device %04x:%04x...\n", usb_descriptor.idVendor, usb_descriptor.idProduct);
415 420
416 libusb_open(usb_device, &usb_handle); 421 libusb_open(usb_device, &usb_handle);
417 if (usb_handle == NULL) { 422 if (usb_handle == NULL) {
418 libusb_free_device_list(usb_device_list, 1); 423 debug("%s: can't connect to device...\n", __func__);
419 libusb_close(usb_handle); 424 libusb_close(usb_handle);
425 if (ecid != 0) {
426 continue;
427 }
428 libusb_free_device_list(usb_device_list, 1);
420 libusb_exit(libirecovery_context); 429 libusb_exit(libirecovery_context);
421 return IRECV_E_UNABLE_TO_CONNECT; 430 return IRECV_E_UNABLE_TO_CONNECT;
422 } 431 }
423 libusb_free_device_list(usb_device_list, 1);
424 432
425 irecv_client_t client = (irecv_client_t) malloc(sizeof(struct irecv_client)); 433 irecv_client_t client = (irecv_client_t) malloc(sizeof(struct irecv_client));
426 if (client == NULL) { 434 if (client == NULL) {
435 libusb_free_device_list(usb_device_list, 1);
427 libusb_close(usb_handle); 436 libusb_close(usb_handle);
428 libusb_exit(libirecovery_context); 437 libusb_exit(libirecovery_context);
429 return IRECV_E_OUT_OF_MEMORY; 438 return IRECV_E_OUT_OF_MEMORY;
@@ -433,7 +442,26 @@ irecv_error_t irecv_open(irecv_client_t* pclient) {
433 client->interface = 0; 442 client->interface = 0;
434 client->handle = usb_handle; 443 client->handle = usb_handle;
435 client->mode = usb_descriptor.idProduct; 444 client->mode = usb_descriptor.idProduct;
436 445
446 /* cache usb serial */
447 irecv_get_string_descriptor_ascii(client, usb_descriptor.iSerialNumber, (unsigned char*) client->serial, 255);
448
449 if (ecid != 0) {
450 char* ecid_string = strstr(client->serial, "ECID:");
451 if (ecid_string == NULL) {
452 debug("%s: could not get ECID for device\n", __func__);
453 irecv_close(client);
454 continue;
455 }
456
457 unsigned long long this_ecid = 0;
458 sscanf(ecid_string, "ECID:%qX", (unsigned long long*)&this_ecid);
459 if (this_ecid != ecid) {
460 irecv_close(client);
461 continue;
462 }
463 debug("found device with ECID %016llx\n", (unsigned long long)ecid);
464 }
437 465
438 error = irecv_set_configuration(client, 1); 466 error = irecv_set_configuration(client, 1);
439 if (error != IRECV_E_SUCCESS) { 467 if (error != IRECV_E_SUCCESS) {
@@ -453,9 +481,6 @@ irecv_error_t irecv_open(irecv_client_t* pclient) {
453 return error; 481 return error;
454 } 482 }
455 483
456 /* cache usb serial */
457 irecv_get_string_descriptor_ascii(client, usb_descriptor.iSerialNumber, (unsigned char*) client->serial, 255);
458
459 *pclient = client; 484 *pclient = client;
460 return IRECV_E_SUCCESS; 485 return IRECV_E_SUCCESS;
461 } 486 }
@@ -529,11 +554,15 @@ irecv_error_t irecv_reset(irecv_client_t client) {
529 return IRECV_E_SUCCESS; 554 return IRECV_E_SUCCESS;
530} 555}
531 556
532irecv_error_t irecv_open_attempts(irecv_client_t* pclient, int attempts) { 557irecv_error_t irecv_open_attempts(irecv_client_t* pclient, unsigned long long ecid, int attempts) {
533 int i; 558 int i;
534 559
535 for (i = 0; i < attempts; i++) { 560 for (i = 0; i < attempts; i++) {
536 if (irecv_open(pclient) != IRECV_E_SUCCESS) { 561 if(*pclient) {
562 irecv_close(*pclient);
563 *pclient = NULL;
564 }
565 if (irecv_open(pclient, ecid) != IRECV_E_SUCCESS) {
537 debug("Connection failed. Waiting 1 sec before retry.\n"); 566 debug("Connection failed. Waiting 1 sec before retry.\n");
538 sleep(1); 567 sleep(1);
539 } else { 568 } else {
@@ -1390,6 +1419,9 @@ irecv_client_t irecv_reconnect(irecv_client_t client, int initial_pause) {
1390 irecv_client_t new_client = NULL; 1419 irecv_client_t new_client = NULL;
1391 irecv_event_cb_t progress_callback = client->progress_callback; 1420 irecv_event_cb_t progress_callback = client->progress_callback;
1392 1421
1422 unsigned long long ecid = 0;
1423 irecv_get_ecid(client, &ecid);
1424
1393 if (check_context(client) == IRECV_E_SUCCESS) { 1425 if (check_context(client) == IRECV_E_SUCCESS) {
1394 irecv_close(client); 1426 irecv_close(client);
1395 } 1427 }
@@ -1399,7 +1431,7 @@ irecv_client_t irecv_reconnect(irecv_client_t client, int initial_pause) {
1399 sleep(initial_pause); 1431 sleep(initial_pause);
1400 } 1432 }
1401 1433
1402 error = irecv_open_attempts(&new_client, 10); 1434 error = irecv_open_attempts(&new_client, ecid, 10);
1403 if(error != IRECV_E_SUCCESS) { 1435 if(error != IRECV_E_SUCCESS) {
1404 return NULL; 1436 return NULL;
1405 } 1437 }