summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2018-09-17 18:11:47 +0200
committerGravatar Nikias Bassen2018-09-17 18:11:47 +0200
commit4daf6d84f7271cc19256c45b52c63b99ba7b4391 (patch)
tree9329f344b20d753ee5b43bda609b6db51a2d6530
parent85d352a6bd4c4d3fef26bc1bec289254939950f9 (diff)
downloadlibirecovery-4daf6d84f7271cc19256c45b52c63b99ba7b4391.tar.gz
libirecovery-4daf6d84f7271cc19256c45b52c63b99ba7b4391.tar.bz2
Add configuration option to allow compiling without USB driver
Using --with-dummy, libirecovery can be compiled in a way that it will not require any USB driver at all. This is only useful if you just want to query libirecovery's device database by product type or hardware model, namely using: irecv_devices_get_device_by_product_type(); irecv_devices_get_device_by_hardware_model(); All other function are either no-op or return IRECV_E_UNSUPPORTED if the library is compiled this way.
-rw-r--r--configure.ac32
-rw-r--r--include/libirecovery.h1
-rw-r--r--src/libirecovery.c143
-rw-r--r--tools/irecovery.c8
4 files changed, 172 insertions, 12 deletions
diff --git a/configure.ac b/configure.ac
index e13c571..1f10bb7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -59,6 +59,11 @@ case "$host_os" in
59esac 59esac
60AC_SUBST(LIBIRECOVERYLDFLAGS) 60AC_SUBST(LIBIRECOVERYLDFLAGS)
61 61
62AC_ARG_WITH([dummy],
63 [AS_HELP_STRING([--with-dummy], [Use no USB driver at all [default=no]. This is only useful if you just want to query the device list by product type or hardware model. All other operations are no-ops or will return IRECV_E_UNSUPPORTED.])],
64 [],
65 [with_dummy=no])
66
62AS_IF([test "x$have_iokit" = "xyes"], [ 67AS_IF([test "x$have_iokit" = "xyes"], [
63 AC_ARG_WITH([iokit], 68 AC_ARG_WITH([iokit],
64 [AS_HELP_STRING([--with-iokit], [Use IOKit instead of libusb on OS X [default=yes]])], 69 [AS_HELP_STRING([--with-iokit], [Use IOKit instead of libusb on OS X [default=yes]])],
@@ -67,17 +72,22 @@ AS_IF([test "x$have_iokit" = "xyes"], [
67 ], [] 72 ], []
68) 73)
69 74
70AS_IF([test "x$with_iokit" = "xyes" && test "x$have_iokit" = "xyes"] , [ 75AS_IF([test "x$with_dummy" = "xyes"], [
71 AC_DEFINE(HAVE_IOKIT, 1, [Define if we have IOKit]) 76 AC_DEFINE(USE_DUMMY, 1, [Define if we are using dummy USB driver])
72 USB_BACKEND="IOKit" 77 USB_BACKEND="dummy"
73 ], 78], [
74 [ 79 AS_IF([test "x$with_iokit" = "xyes" && test "x$have_iokit" = "xyes"] , [
75 PKG_CHECK_MODULES(libusb, libusb-1.0 >= $LIBUSB_VERSION) 80 AC_DEFINE(HAVE_IOKIT, 1, [Define if we have IOKit])
76 USB_BACKEND="libusb `$PKG_CONFIG --modversion libusb-1.0`" 81 USB_BACKEND="IOKit"
77 LIBUSB_REQUIRED="libusb-1.0 >= $LIBUSB_VERSION" 82 ],
78 AC_SUBST(LIBUSB_REQUIRED) 83 [
79 ] 84 PKG_CHECK_MODULES(libusb, libusb-1.0 >= $LIBUSB_VERSION)
80) 85 USB_BACKEND="libusb `$PKG_CONFIG --modversion libusb-1.0`"
86 LIBUSB_REQUIRED="libusb-1.0 >= $LIBUSB_VERSION"
87 AC_SUBST(LIBUSB_REQUIRED)
88 ]
89 )
90])
81 91
82# Checks for header files. 92# Checks for header files.
83AC_HEADER_STDC 93AC_HEADER_STDC
diff --git a/include/libirecovery.h b/include/libirecovery.h
index 7f9c2b4..73fe6f0 100644
--- a/include/libirecovery.h
+++ b/include/libirecovery.h
@@ -49,6 +49,7 @@ typedef enum {
49 IRECV_E_USB_CONFIGURATION = -9, 49 IRECV_E_USB_CONFIGURATION = -9,
50 IRECV_E_PIPE = -10, 50 IRECV_E_PIPE = -10,
51 IRECV_E_TIMEOUT = -11, 51 IRECV_E_TIMEOUT = -11,
52 IRECV_E_UNSUPPORTED = -254,
52 IRECV_E_UNKNOWN_ERROR = -255 53 IRECV_E_UNKNOWN_ERROR = -255
53} irecv_error_t; 54} irecv_error_t;
54 55
diff --git a/src/libirecovery.c b/src/libirecovery.c
index bf96408..945e591 100644
--- a/src/libirecovery.c
+++ b/src/libirecovery.c
@@ -31,6 +31,7 @@
31#include <unistd.h> 31#include <unistd.h>
32#include <sys/stat.h> 32#include <sys/stat.h>
33 33
34#ifndef USE_DUMMY
34#ifndef WIN32 35#ifndef WIN32
35#ifndef HAVE_IOKIT 36#ifndef HAVE_IOKIT
36#include <libusb.h> 37#include <libusb.h>
@@ -52,6 +53,7 @@
52#define sleep(n) Sleep(1000 * n) 53#define sleep(n) Sleep(1000 * n)
53#endif 54#endif
54#endif 55#endif
56#endif
55 57
56#ifdef WIN32 58#ifdef WIN32
57#define IRECV_API __declspec( dllexport ) 59#define IRECV_API __declspec( dllexport )
@@ -72,6 +74,7 @@ struct irecv_client_private {
72 int usb_alt_interface; 74 int usb_alt_interface;
73 unsigned int mode; 75 unsigned int mode;
74 struct irecv_device_info device_info; 76 struct irecv_device_info device_info;
77#ifndef USE_DUMMY
75#ifndef WIN32 78#ifndef WIN32
76#ifndef HAVE_IOKIT 79#ifndef HAVE_IOKIT
77 libusb_device_handle* handle; 80 libusb_device_handle* handle;
@@ -92,6 +95,7 @@ struct irecv_client_private {
92 irecv_event_cb_t precommand_callback; 95 irecv_event_cb_t precommand_callback;
93 irecv_event_cb_t postcommand_callback; 96 irecv_event_cb_t postcommand_callback;
94 irecv_event_cb_t disconnected_callback; 97 irecv_event_cb_t disconnected_callback;
98#endif
95}; 99};
96 100
97#define USB_TIMEOUT 10000 101#define USB_TIMEOUT 10000
@@ -101,11 +105,13 @@ struct irecv_client_private {
101#define debug(...) if(libirecovery_debug) fprintf(stderr, __VA_ARGS__) 105#define debug(...) if(libirecovery_debug) fprintf(stderr, __VA_ARGS__)
102 106
103static int libirecovery_debug = 0; 107static int libirecovery_debug = 0;
108#ifndef USE_DUMMY
104#ifndef WIN32 109#ifndef WIN32
105#ifndef HAVE_IOKIT 110#ifndef HAVE_IOKIT
106static libusb_context* libirecovery_context = NULL; 111static libusb_context* libirecovery_context = NULL;
107#endif 112#endif
108#endif 113#endif
114#endif
109 115
110static struct irecv_device irecv_devices[] = { 116static struct irecv_device irecv_devices[] = {
111 {"iPhone1,1", "m68ap", 0x00, 0x8900 }, 117 {"iPhone1,1", "m68ap", 0x00, 0x8900 },
@@ -197,6 +203,7 @@ static struct irecv_device irecv_devices[] = {
197 { NULL, NULL, -1, -1 } 203 { NULL, NULL, -1, -1 }
198}; 204};
199 205
206#ifndef USE_DUMMY
200static unsigned int dfu_hash_t1[256] = { 207static unsigned int dfu_hash_t1[256] = {
201 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 208 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
202 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 209 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
@@ -772,16 +779,20 @@ static int check_context(irecv_client_t client) {
772 779
773 return IRECV_E_SUCCESS; 780 return IRECV_E_SUCCESS;
774} 781}
782#endif
775 783
776IRECV_API void irecv_init(void) { 784IRECV_API void irecv_init(void) {
785#ifndef USE_DUMMY
777#ifndef WIN32 786#ifndef WIN32
778#ifndef HAVE_IOKIT 787#ifndef HAVE_IOKIT
779 libusb_init(&libirecovery_context); 788 libusb_init(&libirecovery_context);
780#endif 789#endif
781#endif 790#endif
791#endif
782} 792}
783 793
784IRECV_API void irecv_exit(void) { 794IRECV_API void irecv_exit(void) {
795#ifndef USE_DUMMY
785#ifndef WIN32 796#ifndef WIN32
786#ifndef HAVE_IOKIT 797#ifndef HAVE_IOKIT
787 if (libirecovery_context != NULL) { 798 if (libirecovery_context != NULL) {
@@ -790,8 +801,10 @@ IRECV_API void irecv_exit(void) {
790 } 801 }
791#endif 802#endif
792#endif 803#endif
804#endif
793} 805}
794 806
807#ifndef USE_DUMMY
795#ifdef HAVE_IOKIT 808#ifdef HAVE_IOKIT
796static int iokit_usb_control_transfer(irecv_client_t client, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, unsigned char *data, uint16_t w_length, unsigned int timeout) 809static int iokit_usb_control_transfer(irecv_client_t client, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, unsigned char *data, uint16_t w_length, unsigned int timeout)
797{ 810{
@@ -824,8 +837,12 @@ static int iokit_usb_control_transfer(irecv_client_t client, uint8_t bm_request_
824 void dummy_callback(void) { } 837 void dummy_callback(void) { }
825#endif 838#endif
826#endif 839#endif
840#endif
827 841
828IRECV_API int irecv_usb_control_transfer(irecv_client_t client, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, unsigned char *data, uint16_t w_length, unsigned int timeout) { 842IRECV_API int irecv_usb_control_transfer(irecv_client_t client, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, unsigned char *data, uint16_t w_length, unsigned int timeout) {
843#ifdef USE_DUMMY
844 return IRECV_E_UNSUPPORTED;
845#else
829#ifndef WIN32 846#ifndef WIN32
830#ifdef HAVE_IOKIT 847#ifdef HAVE_IOKIT
831 return iokit_usb_control_transfer(client, bm_request_type, b_request, w_value, w_index, data, w_length, timeout); 848 return iokit_usb_control_transfer(client, bm_request_type, b_request, w_value, w_index, data, w_length, timeout);
@@ -873,8 +890,10 @@ IRECV_API int irecv_usb_control_transfer(irecv_client_t client, uint8_t bm_reque
873 890
874 return count; 891 return count;
875#endif 892#endif
893#endif
876} 894}
877 895
896#ifndef USE_DUMMY
878#ifdef HAVE_IOKIT 897#ifdef HAVE_IOKIT
879static int iokit_usb_bulk_transfer(irecv_client_t client, 898static int iokit_usb_bulk_transfer(irecv_client_t client,
880 unsigned char endpoint, 899 unsigned char endpoint,
@@ -928,6 +947,7 @@ static int iokit_usb_bulk_transfer(irecv_client_t client,
928 return IRECV_E_USB_INTERFACE; 947 return IRECV_E_USB_INTERFACE;
929} 948}
930#endif 949#endif
950#endif
931 951
932IRECV_API int irecv_usb_bulk_transfer(irecv_client_t client, 952IRECV_API int irecv_usb_bulk_transfer(irecv_client_t client,
933 unsigned char endpoint, 953 unsigned char endpoint,
@@ -935,6 +955,9 @@ IRECV_API int irecv_usb_bulk_transfer(irecv_client_t client,
935 int length, 955 int length,
936 int *transferred, 956 int *transferred,
937 unsigned int timeout) { 957 unsigned int timeout) {
958#ifdef USE_DUMMY
959 return IRECV_E_UNSUPPORTED;
960#else
938 int ret; 961 int ret;
939 962
940#ifndef WIN32 963#ifndef WIN32
@@ -956,8 +979,10 @@ IRECV_API int irecv_usb_bulk_transfer(irecv_client_t client,
956#endif 979#endif
957 980
958 return ret; 981 return ret;
982#endif
959} 983}
960 984
985#ifndef USE_DUMMY
961#ifdef HAVE_IOKIT 986#ifdef HAVE_IOKIT
962static irecv_error_t iokit_usb_open_service(irecv_client_t *pclient, io_service_t service) { 987static irecv_error_t iokit_usb_open_service(irecv_client_t *pclient, io_service_t service) {
963 988
@@ -1143,8 +1168,12 @@ UInt16 *pids = all_pids;
1143 return iokit_usb_open_service(pclient, ret_service); 1168 return iokit_usb_open_service(pclient, ret_service);
1144} 1169}
1145#endif 1170#endif
1171#endif
1146 1172
1147IRECV_API irecv_error_t irecv_open_with_ecid(irecv_client_t* pclient, unsigned long long ecid) { 1173IRECV_API irecv_error_t irecv_open_with_ecid(irecv_client_t* pclient, unsigned long long ecid) {
1174#ifdef USE_DUMMY
1175 return IRECV_E_UNSUPPORTED;
1176#else
1148 if(libirecovery_debug) { 1177 if(libirecovery_debug) {
1149 irecv_set_debug_level(libirecovery_debug); 1178 irecv_set_debug_level(libirecovery_debug);
1150 } 1179 }
@@ -1282,9 +1311,13 @@ IRECV_API irecv_error_t irecv_open_with_ecid(irecv_client_t* pclient, unsigned l
1282 1311
1283 return ret; 1312 return ret;
1284#endif 1313#endif
1314#endif
1285} 1315}
1286 1316
1287IRECV_API irecv_error_t irecv_usb_set_configuration(irecv_client_t client, int configuration) { 1317IRECV_API irecv_error_t irecv_usb_set_configuration(irecv_client_t client, int configuration) {
1318#ifdef USE_DUMMY
1319 return IRECV_E_UNSUPPORTED;
1320#else
1288 if (check_context(client) != IRECV_E_SUCCESS) 1321 if (check_context(client) != IRECV_E_SUCCESS)
1289 return IRECV_E_NO_DEVICE; 1322 return IRECV_E_NO_DEVICE;
1290 1323
@@ -1312,8 +1345,10 @@ IRECV_API irecv_error_t irecv_usb_set_configuration(irecv_client_t client, int c
1312#endif 1345#endif
1313 1346
1314 return IRECV_E_SUCCESS; 1347 return IRECV_E_SUCCESS;
1348#endif
1315} 1349}
1316 1350
1351#ifndef USE_DUMMY
1317#ifdef HAVE_IOKIT 1352#ifdef HAVE_IOKIT
1318static IOReturn iokit_usb_get_interface(IOUSBDeviceInterface320 **device, uint8_t ifc, io_service_t *usbInterfacep) { 1353static IOReturn iokit_usb_get_interface(IOUSBDeviceInterface320 **device, uint8_t ifc, io_service_t *usbInterfacep) {
1319 1354
@@ -1393,8 +1428,12 @@ static irecv_error_t iokit_usb_set_interface(irecv_client_t client, int usb_inte
1393 return IRECV_E_SUCCESS; 1428 return IRECV_E_SUCCESS;
1394} 1429}
1395#endif 1430#endif
1431#endif
1396 1432
1397IRECV_API irecv_error_t irecv_usb_set_interface(irecv_client_t client, int usb_interface, int usb_alt_interface) { 1433IRECV_API irecv_error_t irecv_usb_set_interface(irecv_client_t client, int usb_interface, int usb_alt_interface) {
1434#ifdef USE_DUMMY
1435 return IRECV_E_UNSUPPORTED;
1436#else
1398 if (check_context(client) != IRECV_E_SUCCESS) 1437 if (check_context(client) != IRECV_E_SUCCESS)
1399 return IRECV_E_NO_DEVICE; 1438 return IRECV_E_NO_DEVICE;
1400 1439
@@ -1424,9 +1463,13 @@ IRECV_API irecv_error_t irecv_usb_set_interface(irecv_client_t client, int usb_i
1424 client->usb_alt_interface = usb_alt_interface; 1463 client->usb_alt_interface = usb_alt_interface;
1425 1464
1426 return IRECV_E_SUCCESS; 1465 return IRECV_E_SUCCESS;
1466#endif
1427} 1467}
1428 1468
1429IRECV_API irecv_error_t irecv_reset(irecv_client_t client) { 1469IRECV_API irecv_error_t irecv_reset(irecv_client_t client) {
1470#ifdef USE_DUMMY
1471 return IRECV_E_UNSUPPORTED;
1472#else
1430 if (check_context(client) != IRECV_E_SUCCESS) 1473 if (check_context(client) != IRECV_E_SUCCESS)
1431 return IRECV_E_NO_DEVICE; 1474 return IRECV_E_NO_DEVICE;
1432 1475
@@ -1453,9 +1496,13 @@ IRECV_API irecv_error_t irecv_reset(irecv_client_t client) {
1453#endif 1496#endif
1454 1497
1455 return IRECV_E_SUCCESS; 1498 return IRECV_E_SUCCESS;
1499#endif
1456} 1500}
1457 1501
1458IRECV_API irecv_error_t irecv_open_with_ecid_and_attempts(irecv_client_t* pclient, unsigned long long ecid, int attempts) { 1502IRECV_API irecv_error_t irecv_open_with_ecid_and_attempts(irecv_client_t* pclient, unsigned long long ecid, int attempts) {
1503#ifdef USE_DUMMY
1504 return IRECV_E_UNSUPPORTED;
1505#else
1459 int i; 1506 int i;
1460 1507
1461 for (i = 0; i < attempts; i++) { 1508 for (i = 0; i < attempts; i++) {
@@ -1472,9 +1519,13 @@ IRECV_API irecv_error_t irecv_open_with_ecid_and_attempts(irecv_client_t* pclien
1472 } 1519 }
1473 1520
1474 return IRECV_E_UNABLE_TO_CONNECT; 1521 return IRECV_E_UNABLE_TO_CONNECT;
1522#endif
1475} 1523}
1476 1524
1477IRECV_API irecv_error_t irecv_event_subscribe(irecv_client_t client, irecv_event_type type, irecv_event_cb_t callback, void* user_data) { 1525IRECV_API irecv_error_t irecv_event_subscribe(irecv_client_t client, irecv_event_type type, irecv_event_cb_t callback, void* user_data) {
1526#ifdef USE_DUMMY
1527 return IRECV_E_UNSUPPORTED;
1528#else
1478 switch(type) { 1529 switch(type) {
1479 case IRECV_RECEIVED: 1530 case IRECV_RECEIVED:
1480 client->received_callback = callback; 1531 client->received_callback = callback;
@@ -1502,9 +1553,13 @@ IRECV_API irecv_error_t irecv_event_subscribe(irecv_client_t client, irecv_event
1502 } 1553 }
1503 1554
1504 return IRECV_E_SUCCESS; 1555 return IRECV_E_SUCCESS;
1556#endif
1505} 1557}
1506 1558
1507IRECV_API irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type type) { 1559IRECV_API irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type type) {
1560#ifdef USE_DUMMY
1561 return IRECV_E_UNSUPPORTED;
1562#else
1508 switch(type) { 1563 switch(type) {
1509 case IRECV_RECEIVED: 1564 case IRECV_RECEIVED:
1510 client->received_callback = NULL; 1565 client->received_callback = NULL;
@@ -1532,9 +1587,13 @@ IRECV_API irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_eve
1532 } 1587 }
1533 1588
1534 return IRECV_E_SUCCESS; 1589 return IRECV_E_SUCCESS;
1590#endif
1535} 1591}
1536 1592
1537IRECV_API irecv_error_t irecv_close(irecv_client_t client) { 1593IRECV_API irecv_error_t irecv_close(irecv_client_t client) {
1594#ifdef USE_DUMMY
1595 return IRECV_E_UNSUPPORTED;
1596#else
1538 if (client != NULL) { 1597 if (client != NULL) {
1539 if(client->disconnected_callback != NULL) { 1598 if(client->disconnected_callback != NULL) {
1540 irecv_event_t event; 1599 irecv_event_t event;
@@ -1582,10 +1641,12 @@ IRECV_API irecv_error_t irecv_close(irecv_client_t client) {
1582 } 1641 }
1583 1642
1584 return IRECV_E_SUCCESS; 1643 return IRECV_E_SUCCESS;
1644#endif
1585} 1645}
1586 1646
1587IRECV_API void irecv_set_debug_level(int level) { 1647IRECV_API void irecv_set_debug_level(int level) {
1588 libirecovery_debug = level; 1648 libirecovery_debug = level;
1649#ifndef USE_DUMMY
1589#ifndef WIN32 1650#ifndef WIN32
1590#ifndef HAVE_IOKIT 1651#ifndef HAVE_IOKIT
1591 if(libirecovery_context) { 1652 if(libirecovery_context) {
@@ -1593,8 +1654,10 @@ IRECV_API void irecv_set_debug_level(int level) {
1593 } 1654 }
1594#endif 1655#endif
1595#endif 1656#endif
1657#endif
1596} 1658}
1597 1659
1660#ifndef USE_DUMMY
1598static irecv_error_t irecv_send_command_raw(irecv_client_t client, const char* command) { 1661static irecv_error_t irecv_send_command_raw(irecv_client_t client, const char* command) {
1599 unsigned int length = strlen(command); 1662 unsigned int length = strlen(command);
1600 if (length >= 0x100) { 1663 if (length >= 0x100) {
@@ -1607,8 +1670,12 @@ static irecv_error_t irecv_send_command_raw(irecv_client_t client, const char* c
1607 1670
1608 return IRECV_E_SUCCESS; 1671 return IRECV_E_SUCCESS;
1609} 1672}
1673#endif
1610 1674
1611IRECV_API irecv_error_t irecv_send_command(irecv_client_t client, const char* command) { 1675IRECV_API irecv_error_t irecv_send_command(irecv_client_t client, const char* command) {
1676#ifdef USE_DUMMY
1677 return IRECV_E_UNSUPPORTED;
1678#else
1612 irecv_error_t error = 0; 1679 irecv_error_t error = 0;
1613 1680
1614 if (check_context(client) != IRECV_E_SUCCESS) 1681 if (check_context(client) != IRECV_E_SUCCESS)
@@ -1646,9 +1713,13 @@ IRECV_API irecv_error_t irecv_send_command(irecv_client_t client, const char* co
1646 } 1713 }
1647 1714
1648 return IRECV_E_SUCCESS; 1715 return IRECV_E_SUCCESS;
1716#endif
1649} 1717}
1650 1718
1651IRECV_API irecv_error_t irecv_send_file(irecv_client_t client, const char* filename, int dfu_notify_finished) { 1719IRECV_API irecv_error_t irecv_send_file(irecv_client_t client, const char* filename, int dfu_notify_finished) {
1720#ifdef USE_DUMMY
1721 return IRECV_E_UNSUPPORTED;
1722#else
1652 if (check_context(client) != IRECV_E_SUCCESS) 1723 if (check_context(client) != IRECV_E_SUCCESS)
1653 return IRECV_E_NO_DEVICE; 1724 return IRECV_E_NO_DEVICE;
1654 1725
@@ -1681,8 +1752,10 @@ IRECV_API irecv_error_t irecv_send_file(irecv_client_t client, const char* filen
1681 free(buffer); 1752 free(buffer);
1682 1753
1683 return error; 1754 return error;
1755#endif
1684} 1756}
1685 1757
1758#ifndef USE_DUMMY
1686static irecv_error_t irecv_get_status(irecv_client_t client, unsigned int* status) { 1759static irecv_error_t irecv_get_status(irecv_client_t client, unsigned int* status) {
1687 if (check_context(client) != IRECV_E_SUCCESS) { 1760 if (check_context(client) != IRECV_E_SUCCESS) {
1688 *status = 0; 1761 *status = 0;
@@ -1700,8 +1773,12 @@ static irecv_error_t irecv_get_status(irecv_client_t client, unsigned int* statu
1700 1773
1701 return IRECV_E_SUCCESS; 1774 return IRECV_E_SUCCESS;
1702} 1775}
1776#endif
1703 1777
1704IRECV_API irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, unsigned long length, int dfu_notify_finished) { 1778IRECV_API irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, unsigned long length, int dfu_notify_finished) {
1779#ifdef USE_DUMMY
1780 return IRECV_E_UNSUPPORTED;
1781#else
1705 irecv_error_t error = 0; 1782 irecv_error_t error = 0;
1706 int recovery_mode = ((client->mode != IRECV_K_DFU_MODE) && (client->mode != IRECV_K_WTF_MODE)); 1783 int recovery_mode = ((client->mode != IRECV_K_DFU_MODE) && (client->mode != IRECV_K_WTF_MODE));
1707 1784
@@ -1862,9 +1939,13 @@ IRECV_API irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char*
1862 } 1939 }
1863 1940
1864 return IRECV_E_SUCCESS; 1941 return IRECV_E_SUCCESS;
1942#endif
1865} 1943}
1866 1944
1867IRECV_API irecv_error_t irecv_receive(irecv_client_t client) { 1945IRECV_API irecv_error_t irecv_receive(irecv_client_t client) {
1946#ifdef USE_DUMMY
1947 return IRECV_E_UNSUPPORTED;
1948#else
1868 char buffer[BUFFER_SIZE]; 1949 char buffer[BUFFER_SIZE];
1869 memset(buffer, '\0', BUFFER_SIZE); 1950 memset(buffer, '\0', BUFFER_SIZE);
1870 1951
@@ -1887,9 +1968,13 @@ IRECV_API irecv_error_t irecv_receive(irecv_client_t client) {
1887 } 1968 }
1888 1969
1889 return IRECV_E_SUCCESS; 1970 return IRECV_E_SUCCESS;
1971#endif
1890} 1972}
1891 1973
1892IRECV_API irecv_error_t irecv_getenv(irecv_client_t client, const char* variable, char** value) { 1974IRECV_API irecv_error_t irecv_getenv(irecv_client_t client, const char* variable, char** value) {
1975#ifdef USE_DUMMY
1976 return IRECV_E_UNSUPPORTED;
1977#else
1893 char command[256]; 1978 char command[256];
1894 1979
1895 if (check_context(client) != IRECV_E_SUCCESS) 1980 if (check_context(client) != IRECV_E_SUCCESS)
@@ -1923,9 +2008,13 @@ IRECV_API irecv_error_t irecv_getenv(irecv_client_t client, const char* variable
1923 *value = response; 2008 *value = response;
1924 2009
1925 return IRECV_E_SUCCESS; 2010 return IRECV_E_SUCCESS;
2011#endif
1926} 2012}
1927 2013
1928IRECV_API irecv_error_t irecv_getret(irecv_client_t client, unsigned int* value) { 2014IRECV_API irecv_error_t irecv_getret(irecv_client_t client, unsigned int* value) {
2015#ifdef USE_DUMMY
2016 return IRECV_E_UNSUPPORTED;
2017#else
1929 if (check_context(client) != IRECV_E_SUCCESS) 2018 if (check_context(client) != IRECV_E_SUCCESS)
1930 return IRECV_E_NO_DEVICE; 2019 return IRECV_E_NO_DEVICE;
1931 2020
@@ -1942,25 +2031,35 @@ IRECV_API irecv_error_t irecv_getret(irecv_client_t client, unsigned int* value)
1942 *value = (unsigned int) *response; 2031 *value = (unsigned int) *response;
1943 2032
1944 return IRECV_E_SUCCESS; 2033 return IRECV_E_SUCCESS;
2034#endif
1945} 2035}
1946 2036
1947IRECV_API irecv_error_t irecv_get_mode(irecv_client_t client, int* mode) { 2037IRECV_API irecv_error_t irecv_get_mode(irecv_client_t client, int* mode) {
2038#ifdef USE_DUMMY
2039 return IRECV_E_UNSUPPORTED;
2040#else
1948 if (check_context(client) != IRECV_E_SUCCESS) 2041 if (check_context(client) != IRECV_E_SUCCESS)
1949 return IRECV_E_NO_DEVICE; 2042 return IRECV_E_NO_DEVICE;
1950 2043
1951 *mode = client->mode; 2044 *mode = client->mode;
1952 2045
1953 return IRECV_E_SUCCESS; 2046 return IRECV_E_SUCCESS;
2047#endif
1954} 2048}
1955 2049
1956IRECV_API const struct irecv_device_info* irecv_get_device_info(irecv_client_t client) 2050IRECV_API const struct irecv_device_info* irecv_get_device_info(irecv_client_t client)
1957{ 2051{
2052#ifdef USE_DUMMY
2053 return NULL;
2054#else
1958 if (check_context(client) != IRECV_E_SUCCESS) 2055 if (check_context(client) != IRECV_E_SUCCESS)
1959 return NULL; 2056 return NULL;
1960 2057
1961 return &client->device_info; 2058 return &client->device_info;
2059#endif
1962} 2060}
1963 2061
2062#ifndef USE_DUMMY
1964#ifdef HAVE_IOKIT 2063#ifdef HAVE_IOKIT
1965static void *iokit_limera1n_usb_submit_request(void *argv) { 2064static void *iokit_limera1n_usb_submit_request(void *argv) {
1966 void **args = argv; 2065 void **args = argv;
@@ -1974,8 +2073,12 @@ static void *iokit_limera1n_usb_submit_request(void *argv) {
1974 return NULL; 2073 return NULL;
1975} 2074}
1976#endif 2075#endif
2076#endif
1977 2077
1978IRECV_API irecv_error_t irecv_trigger_limera1n_exploit(irecv_client_t client) { 2078IRECV_API irecv_error_t irecv_trigger_limera1n_exploit(irecv_client_t client) {
2079#ifdef USE_DUMMY
2080 return IRECV_E_UNSUPPORTED;
2081#else
1979 if (check_context(client) != IRECV_E_SUCCESS) 2082 if (check_context(client) != IRECV_E_SUCCESS)
1980 return IRECV_E_NO_DEVICE; 2083 return IRECV_E_NO_DEVICE;
1981 2084
@@ -2020,9 +2123,13 @@ IRECV_API irecv_error_t irecv_trigger_limera1n_exploit(irecv_client_t client) {
2020#endif 2123#endif
2021 2124
2022 return IRECV_E_SUCCESS; 2125 return IRECV_E_SUCCESS;
2126#endif
2023} 2127}
2024 2128
2025IRECV_API irecv_error_t irecv_execute_script(irecv_client_t client, const char* script) { 2129IRECV_API irecv_error_t irecv_execute_script(irecv_client_t client, const char* script) {
2130#ifdef USE_DUMMY
2131 return IRECV_E_UNSUPPORTED;
2132#else
2026 irecv_error_t error = IRECV_E_SUCCESS; 2133 irecv_error_t error = IRECV_E_SUCCESS;
2027 if (check_context(client) != IRECV_E_SUCCESS) 2134 if (check_context(client) != IRECV_E_SUCCESS)
2028 return IRECV_E_NO_DEVICE; 2135 return IRECV_E_NO_DEVICE;
@@ -2048,18 +2155,26 @@ IRECV_API irecv_error_t irecv_execute_script(irecv_client_t client, const char*
2048 free(body); 2155 free(body);
2049 2156
2050 return error; 2157 return error;
2158#endif
2051} 2159}
2052 2160
2053IRECV_API irecv_error_t irecv_saveenv(irecv_client_t client) { 2161IRECV_API irecv_error_t irecv_saveenv(irecv_client_t client) {
2162#ifdef USE_DUMMY
2163 return IRECV_E_UNSUPPORTED;
2164#else
2054 irecv_error_t error = irecv_send_command_raw(client, "saveenv"); 2165 irecv_error_t error = irecv_send_command_raw(client, "saveenv");
2055 if(error != IRECV_E_SUCCESS) { 2166 if(error != IRECV_E_SUCCESS) {
2056 return error; 2167 return error;
2057 } 2168 }
2058 2169
2059 return IRECV_E_SUCCESS; 2170 return IRECV_E_SUCCESS;
2171#endif
2060} 2172}
2061 2173
2062IRECV_API irecv_error_t irecv_setenv(irecv_client_t client, const char* variable, const char* value) { 2174IRECV_API irecv_error_t irecv_setenv(irecv_client_t client, const char* variable, const char* value) {
2175#ifdef USE_DUMMY
2176 return IRECV_E_UNSUPPORTED;
2177#else
2063 char command[256]; 2178 char command[256];
2064 2179
2065 if (check_context(client) != IRECV_E_SUCCESS) 2180 if (check_context(client) != IRECV_E_SUCCESS)
@@ -2077,15 +2192,20 @@ IRECV_API irecv_error_t irecv_setenv(irecv_client_t client, const char* variable
2077 } 2192 }
2078 2193
2079 return IRECV_E_SUCCESS; 2194 return IRECV_E_SUCCESS;
2195#endif
2080} 2196}
2081 2197
2082IRECV_API irecv_error_t irecv_reboot(irecv_client_t client) { 2198IRECV_API irecv_error_t irecv_reboot(irecv_client_t client) {
2199#ifdef USE_DUMMY
2200 return IRECV_E_UNSUPPORTED;
2201#else
2083 irecv_error_t error = irecv_send_command_raw(client, "reboot"); 2202 irecv_error_t error = irecv_send_command_raw(client, "reboot");
2084 if(error != IRECV_E_SUCCESS) { 2203 if(error != IRECV_E_SUCCESS) {
2085 return error; 2204 return error;
2086 } 2205 }
2087 2206
2088 return IRECV_E_SUCCESS; 2207 return IRECV_E_SUCCESS;
2208#endif
2089} 2209}
2090 2210
2091IRECV_API const char* irecv_strerror(irecv_error_t error) { 2211IRECV_API const char* irecv_strerror(irecv_error_t error) {
@@ -2126,6 +2246,9 @@ IRECV_API const char* irecv_strerror(irecv_error_t error) {
2126 case IRECV_E_TIMEOUT: 2246 case IRECV_E_TIMEOUT:
2127 return "Timeout talking to device"; 2247 return "Timeout talking to device";
2128 2248
2249 case IRECV_E_UNSUPPORTED:
2250 return "Operation unsupported by driver";
2251
2129 default: 2252 default:
2130 return "Unknown error"; 2253 return "Unknown error";
2131 } 2254 }
@@ -2134,6 +2257,9 @@ IRECV_API const char* irecv_strerror(irecv_error_t error) {
2134} 2257}
2135 2258
2136IRECV_API irecv_error_t irecv_reset_counters(irecv_client_t client) { 2259IRECV_API irecv_error_t irecv_reset_counters(irecv_client_t client) {
2260#ifdef USE_DUMMY
2261 return IRECV_E_UNSUPPORTED;
2262#else
2137 if (check_context(client) != IRECV_E_SUCCESS) 2263 if (check_context(client) != IRECV_E_SUCCESS)
2138 return IRECV_E_NO_DEVICE; 2264 return IRECV_E_NO_DEVICE;
2139 2265
@@ -2142,9 +2268,13 @@ IRECV_API irecv_error_t irecv_reset_counters(irecv_client_t client) {
2142 } 2268 }
2143 2269
2144 return IRECV_E_SUCCESS; 2270 return IRECV_E_SUCCESS;
2271#endif
2145} 2272}
2146 2273
2147IRECV_API irecv_error_t irecv_recv_buffer(irecv_client_t client, char* buffer, unsigned long length) { 2274IRECV_API irecv_error_t irecv_recv_buffer(irecv_client_t client, char* buffer, unsigned long length) {
2275#ifdef USE_DUMMY
2276 return IRECV_E_UNSUPPORTED;
2277#else
2148 int recovery_mode = ((client->mode != IRECV_K_DFU_MODE) && (client->mode != IRECV_K_WTF_MODE)); 2278 int recovery_mode = ((client->mode != IRECV_K_DFU_MODE) && (client->mode != IRECV_K_WTF_MODE));
2149 2279
2150 if (check_context(client) != IRECV_E_SUCCESS) 2280 if (check_context(client) != IRECV_E_SUCCESS)
@@ -2184,9 +2314,13 @@ IRECV_API irecv_error_t irecv_recv_buffer(irecv_client_t client, char* buffer, u
2184 } 2314 }
2185 2315
2186 return IRECV_E_SUCCESS; 2316 return IRECV_E_SUCCESS;
2317#endif
2187} 2318}
2188 2319
2189IRECV_API irecv_error_t irecv_finish_transfer(irecv_client_t client) { 2320IRECV_API irecv_error_t irecv_finish_transfer(irecv_client_t client) {
2321#ifdef USE_DUMMY
2322 return IRECV_E_UNSUPPORTED;
2323#else
2190 int i = 0; 2324 int i = 0;
2191 unsigned int status = 0; 2325 unsigned int status = 0;
2192 2326
@@ -2202,6 +2336,7 @@ IRECV_API irecv_error_t irecv_finish_transfer(irecv_client_t client) {
2202 irecv_reset(client); 2336 irecv_reset(client);
2203 2337
2204 return IRECV_E_SUCCESS; 2338 return IRECV_E_SUCCESS;
2339#endif
2205} 2340}
2206 2341
2207IRECV_API irecv_device_t irecv_devices_get_all(void) { 2342IRECV_API irecv_device_t irecv_devices_get_all(void) {
@@ -2209,6 +2344,9 @@ IRECV_API irecv_device_t irecv_devices_get_all(void) {
2209} 2344}
2210 2345
2211IRECV_API irecv_error_t irecv_devices_get_device_by_client(irecv_client_t client, irecv_device_t* device) { 2346IRECV_API irecv_error_t irecv_devices_get_device_by_client(irecv_client_t client, irecv_device_t* device) {
2347#ifdef USE_DUMMY
2348 return IRECV_E_UNSUPPORTED;
2349#else
2212 int i = 0; 2350 int i = 0;
2213 2351
2214 *device = NULL; 2352 *device = NULL;
@@ -2225,6 +2363,7 @@ IRECV_API irecv_error_t irecv_devices_get_device_by_client(irecv_client_t client
2225 } 2363 }
2226 2364
2227 return IRECV_E_NO_DEVICE; 2365 return IRECV_E_NO_DEVICE;
2366#endif
2228} 2367}
2229 2368
2230IRECV_API irecv_error_t irecv_devices_get_device_by_product_type(const char* product_type, irecv_device_t* device) { 2369IRECV_API irecv_error_t irecv_devices_get_device_by_product_type(const char* product_type, irecv_device_t* device) {
@@ -2264,6 +2403,9 @@ IRECV_API irecv_error_t irecv_devices_get_device_by_hardware_model(const char* h
2264} 2403}
2265 2404
2266IRECV_API irecv_client_t irecv_reconnect(irecv_client_t client, int initial_pause) { 2405IRECV_API irecv_client_t irecv_reconnect(irecv_client_t client, int initial_pause) {
2406#ifdef USE_DUMMY
2407 return NULL;
2408#else
2267 irecv_error_t error = 0; 2409 irecv_error_t error = 0;
2268 irecv_client_t new_client = NULL; 2410 irecv_client_t new_client = NULL;
2269 irecv_event_cb_t progress_callback = client->progress_callback; 2411 irecv_event_cb_t progress_callback = client->progress_callback;
@@ -2287,4 +2429,5 @@ IRECV_API irecv_client_t irecv_reconnect(irecv_client_t client, int initial_paus
2287 new_client->progress_callback = progress_callback; 2429 new_client->progress_callback = progress_callback;
2288 2430
2289 return new_client; 2431 return new_client;
2432#endif
2290} 2433}
diff --git a/tools/irecovery.c b/tools/irecovery.c
index f250dc5..2db6f4f 100644
--- a/tools/irecovery.c
+++ b/tools/irecovery.c
@@ -459,12 +459,18 @@ int main(int argc, char* argv[]) {
459 for (i = 0; i <= 5; i++) { 459 for (i = 0; i <= 5; i++) {
460 debug("Attempting to connect... \n"); 460 debug("Attempting to connect... \n");
461 461
462 if (irecv_open_with_ecid(&client, ecid) != IRECV_E_SUCCESS) 462 irecv_error_t err = irecv_open_with_ecid(&client, ecid);
463 if (err == IRECV_E_UNSUPPORTED) {
464 fprintf(stderr, "ERROR: %s\n", irecv_strerror(err));
465 return -1;
466 }
467 else if (err != IRECV_E_SUCCESS)
463 sleep(1); 468 sleep(1);
464 else 469 else
465 break; 470 break;
466 471
467 if (i == 5) { 472 if (i == 5) {
473 fprintf(stderr, "ERROR: %s\n", irecv_strerror(err));
468 return -1; 474 return -1;
469 } 475 }
470 } 476 }