diff options
| author | 2012-07-04 13:28:27 +0200 | |
|---|---|---|
| committer | 2012-07-04 13:28:27 +0200 | |
| commit | 51489dbb69a4e4a0131a74b34235152f131588d1 (patch) | |
| tree | 5f5e35bca7d8d8a201faba99c4006d821d6b2ac1 | |
| parent | 1f2f0141bd5fc0cdc4eb311261766eb0b8716c88 (diff) | |
| download | libirecovery-51489dbb69a4e4a0131a74b34235152f131588d1.tar.gz libirecovery-51489dbb69a4e4a0131a74b34235152f131588d1.tar.bz2 | |
add support for targeting a device by ECID
| -rw-r--r-- | include/libirecovery.h | 4 | ||||
| -rw-r--r-- | libirecovery.c | 52 |
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 | ||
| 187 | void irecv_set_debug_level(int level); | 187 | void irecv_set_debug_level(int level); |
| 188 | const char* irecv_strerror(irecv_error_t error); | 188 | const char* irecv_strerror(irecv_error_t error); |
| 189 | irecv_error_t irecv_open_attempts(irecv_client_t* pclient, int attempts); | 189 | irecv_error_t irecv_open_attempts(irecv_client_t* pclient, unsigned long long ecid, int attempts); |
| 190 | irecv_error_t irecv_open(irecv_client_t* client); | 190 | irecv_error_t irecv_open(irecv_client_t* client, unsigned long long ecid); |
| 191 | irecv_error_t irecv_reset(irecv_client_t client); | 191 | irecv_error_t irecv_reset(irecv_client_t client); |
| 192 | irecv_error_t irecv_close(irecv_client_t client); | 192 | irecv_error_t irecv_close(irecv_client_t client); |
| 193 | irecv_error_t irecv_receive(irecv_client_t client); | 193 | 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, | |||
| 384 | #endif | 384 | #endif |
| 385 | } | 385 | } |
| 386 | 386 | ||
| 387 | irecv_error_t irecv_open(irecv_client_t* pclient) { | 387 | irecv_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 | ||
| 532 | irecv_error_t irecv_open_attempts(irecv_client_t* pclient, int attempts) { | 557 | irecv_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 | } |
