summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Joshua Hill2010-05-16 15:48:19 -0400
committerGravatar Joshua Hill2010-05-16 15:48:19 -0400
commit34fc43b128e475fda4e9834689e3649eba82c4c9 (patch)
tree60ceb87bd3098ab96cb96cf359275f162ea0d90c
parent3491ef9c41f1cd867028881a8beebf1ad55373c7 (diff)
downloadlibirecovery-34fc43b128e475fda4e9834689e3649eba82c4c9.tar.gz
libirecovery-34fc43b128e475fda4e9834689e3649eba82c4c9.tar.bz2
added irecv_errorstr() and fixed a few bugs
-rw-r--r--include/libirecovery.h1
-rw-r--r--src/irecovery.c24
-rw-r--r--src/libirecovery.c100
3 files changed, 103 insertions, 22 deletions
diff --git a/include/libirecovery.h b/include/libirecovery.h
index 822d0e1..65abf04 100644
--- a/include/libirecovery.h
+++ b/include/libirecovery.h
@@ -58,6 +58,7 @@ struct irecv_device {
58}; 58};
59 59
60irecv_device_t* irecv_init(); 60irecv_device_t* irecv_init();
61const char* irecv_strerror(irecv_error_t error);
61irecv_error_t irecv_open(irecv_device_t* device); 62irecv_error_t irecv_open(irecv_device_t* device);
62irecv_error_t irecv_exit(irecv_device_t* device); 63irecv_error_t irecv_exit(irecv_device_t* device);
63irecv_error_t irecv_reset(irecv_device_t* device); 64irecv_error_t irecv_reset(irecv_device_t* device);
diff --git a/src/irecovery.c b/src/irecovery.c
index 8ffe86b..7133606 100644
--- a/src/irecovery.c
+++ b/src/irecovery.c
@@ -30,7 +30,7 @@ enum {
30}; 30};
31 31
32static unsigned int quit = 0; 32static unsigned int quit = 0;
33static unsigned int debug = 0; 33static unsigned int verbose = 0;
34 34
35void print_shell_usage() { 35void print_shell_usage() {
36 printf("Usage:\n"); 36 printf("Usage:\n");
@@ -50,7 +50,7 @@ void parse_command(irecv_device_t* device, unsigned char* command, unsigned int
50 } else 50 } else
51 51
52 if(!strcmp(command, "/upload")) { 52 if(!strcmp(command, "/upload")) {
53 char* filename = strtok(0, " "); 53 char* filename = strtok(NULL, " ");
54 if(filename != NULL) { 54 if(filename != NULL) {
55 irecv_send_file(device, filename); 55 irecv_send_file(device, filename);
56 } 56 }
@@ -87,10 +87,16 @@ void init_shell(irecv_device_t* device) {
87 irecv_set_sender(device, &send_callback); 87 irecv_set_sender(device, &send_callback);
88 irecv_set_receiver(device, &recv_callback); 88 irecv_set_receiver(device, &recv_callback);
89 while(!quit) { 89 while(!quit) {
90 irecv_update(device); 90 if(irecv_update(device) != IRECV_SUCCESS) {
91 break;
92 }
93
91 char* cmd = readline("> "); 94 char* cmd = readline("> ");
92 if(cmd && *cmd) { 95 if(cmd && *cmd) {
93 irecv_send_command(device, cmd); 96 if(irecv_send_command(device, cmd) != IRECV_SUCCESS) {
97 quit = 1;
98 }
99
94 append_command_to_history(cmd); 100 append_command_to_history(cmd);
95 free(cmd); 101 free(cmd);
96 } 102 }
@@ -100,8 +106,8 @@ void init_shell(irecv_device_t* device) {
100void print_usage() { 106void print_usage() {
101 printf("iRecovery - iDevice Recovery Utility\n"); 107 printf("iRecovery - iDevice Recovery Utility\n");
102 printf("Usage: ./irecovery [args]\n"); 108 printf("Usage: ./irecovery [args]\n");
109 printf("\t-v\t\tStart irecovery in verbose mode.\n");
103 printf("\t-c <cmd>\tSend command to device.\n"); 110 printf("\t-c <cmd>\tSend command to device.\n");
104 printf("\t-d\t\tStart irecovery in debug mode.\n");
105 printf("\t-f <file>\tSend file to device.\n"); 111 printf("\t-f <file>\tSend file to device.\n");
106 printf("\t-h\t\tShow this help.\n"); 112 printf("\t-h\t\tShow this help.\n");
107 printf("\t-r\t\tReset device.\n"); 113 printf("\t-r\t\tReset device.\n");
@@ -114,10 +120,10 @@ int main(int argc, char** argv) {
114 int action = 0; 120 int action = 0;
115 char* argument = NULL; 121 char* argument = NULL;
116 if(argc == 1) print_usage(); 122 if(argc == 1) print_usage();
117 while ((opt = getopt(argc, argv, "dhrsc:f:")) > 0) { 123 while ((opt = getopt(argc, argv, "vhrsc:f:")) > 0) {
118 switch (opt) { 124 switch (opt) {
119 case 'd': 125 case 'v':
120 debug = 1; 126 verbose += 1;
121 break; 127 break;
122 128
123 case 'h': 129 case 'h':
@@ -153,7 +159,7 @@ int main(int argc, char** argv) {
153 fprintf(stderr, "Unable to initialize libirecovery\n"); 159 fprintf(stderr, "Unable to initialize libirecovery\n");
154 return -1; 160 return -1;
155 } 161 }
156 if(debug) irecv_set_debug(device, 1); 162 if(verbose) irecv_set_debug(device, verbose);
157 163
158 if(irecv_open(device) < 0) { 164 if(irecv_open(device) < 0) {
159 fprintf(stderr, "Unable to open device\n"); 165 fprintf(stderr, "Unable to open device\n");
diff --git a/src/libirecovery.c b/src/libirecovery.c
index 21cdfcf..bcea61c 100644
--- a/src/libirecovery.c
+++ b/src/libirecovery.c
@@ -27,6 +27,21 @@
27#define BUFFER_SIZE 0x1000 27#define BUFFER_SIZE 0x1000
28#define debug(...) if(device->debug) fprintf(stderr, __VA_ARGS__) 28#define debug(...) if(device->debug) fprintf(stderr, __VA_ARGS__)
29 29
30const char* irecv_error_invalid_input = "Invalid input";
31const char* irecv_error_unknown = "Unknown error";
32const char* irecv_error_file_not_found = "Unable to find file";
33const char* irecv_error_usb_status = "Invalid device status";
34const char* irecv_error_no_device = "Unable to find device";
35const char* irecv_error_out_of_memory = "Unable to allocate memory";
36const char* irecv_error_unable_to_connect = "Unable to connect to device";
37const char* irecv_error_usb_interface = "Unable to set device interface";
38const char* irecv_error_success = "Command completed successfully";
39const char* irecv_error_usb_upload = "Unable to upload data to device";
40const char* irecv_error_usb_configuration = "Unable to set device configuration";
41
42int irecv_default_sender(irecv_device_t* device, unsigned char* data, int size);
43int irecv_default_receiver(irecv_device_t* device, unsigned char* data, int size);
44
30irecv_device_t* irecv_init() { 45irecv_device_t* irecv_init() {
31 struct libusb_context* usb_context = NULL; 46 struct libusb_context* usb_context = NULL;
32 47
@@ -36,8 +51,10 @@ irecv_device_t* irecv_init() {
36 return NULL; 51 return NULL;
37 } 52 }
38 memset(device, '\0', sizeof(irecv_device_t)); 53 memset(device, '\0', sizeof(irecv_device_t));
39 device->context = usb_context;
40 54
55 irecv_set_receiver(device, &irecv_default_receiver);
56 irecv_set_sender(device, &irecv_default_sender);
57 device->context = usb_context;
41 return device; 58 return device;
42} 59}
43 60
@@ -112,8 +129,10 @@ irecv_error_t irecv_set_interface(irecv_device_t* device, int interface, int alt
112 return IRECV_ERROR_USB_INTERFACE; 129 return IRECV_ERROR_USB_INTERFACE;
113 } 130 }
114 131
115 if(libusb_set_interface_alt_setting(device->handle, interface, alt_interface) < 0) { 132 if(alt_interface > 0) {
116 return IRECV_ERROR_USB_INTERFACE; 133 if(libusb_set_interface_alt_setting(device->handle, interface, alt_interface) < 0) {
134 return IRECV_ERROR_USB_INTERFACE;
135 }
117 } 136 }
118 137
119 device->interface = interface; 138 device->interface = interface;
@@ -170,6 +189,7 @@ irecv_error_t irecv_set_debug(irecv_device_t* device, int level) {
170 189
171 libusb_set_debug(device->context, level); 190 libusb_set_debug(device->context, level);
172 device->debug = level; 191 device->debug = level;
192 return IRECV_SUCCESS;
173} 193}
174 194
175irecv_error_t irecv_send_command(irecv_device_t* device, unsigned char* command) { 195irecv_error_t irecv_send_command(irecv_device_t* device, unsigned char* command) {
@@ -177,23 +197,21 @@ irecv_error_t irecv_send_command(irecv_device_t* device, unsigned char* command)
177 return IRECV_ERROR_NO_DEVICE; 197 return IRECV_ERROR_NO_DEVICE;
178 } 198 }
179 199
180 ssize_t length = strlen(command); 200 unsigned int length = strlen(command);
181 if(length >= 0x100) { 201 if(length >= 0x100) {
182 return IRECV_ERROR_INVALID_INPUT; 202 length = 0xFF;
183 } 203 }
184 204
185 if(device->send_callback != NULL) { 205 if(device->send_callback != NULL) {
186 // Call our user defined callback first, this must return a number of bytes to send 206 // Call our user defined callback first, this must return a number of bytes to send
187 // or zero to abort send. 207 // or zero to abort send.
188 length = device->send_callback(device, command, length); 208 length = device->send_callback(device, command, length);
189 if(length > 0) {
190 int ret = libusb_control_transfer(device->handle, 0x40, 0, 0, 0, (unsigned char*) command, length+1, 100);
191 if(ret < 0) {
192 return IRECV_ERROR_UNKNOWN;
193 }
194 }
195 } 209 }
196 210
211 if(length > 0) {
212 libusb_control_transfer(device->handle, 0x40, 0, 0, 0, command, length+1, 100);
213 }
214
197 return IRECV_SUCCESS; 215 return IRECV_SUCCESS;
198} 216}
199 217
@@ -299,8 +317,10 @@ irecv_error_t irecv_update(irecv_device_t* device) {
299 int bytes = 0; 317 int bytes = 0;
300 while(libusb_bulk_transfer(device->handle, 0x81, buffer, BUFFER_SIZE, &bytes, 100) == 0) { 318 while(libusb_bulk_transfer(device->handle, 0x81, buffer, BUFFER_SIZE, &bytes, 100) == 0) {
301 if(bytes > 0) { 319 if(bytes > 0) {
302 if(device->receive_callback(device, buffer, bytes) != bytes) { 320 if(device->receive_callback != NULL) {
303 return IRECV_ERROR_UNKNOWN; 321 if(device->receive_callback(device, buffer, bytes) != bytes) {
322 return IRECV_ERROR_UNKNOWN;
323 }
304 } 324 }
305 } else break; 325 } else break;
306 } 326 }
@@ -308,6 +328,18 @@ irecv_error_t irecv_update(irecv_device_t* device) {
308 return IRECV_SUCCESS; 328 return IRECV_SUCCESS;
309} 329}
310 330
331int irecv_default_sender(irecv_device_t* device, unsigned char* data, int size) {
332 return size;
333}
334
335int irecv_default_receiver(irecv_device_t* device, unsigned char* data, int size) {
336 int i = 0;
337 for(i = 0; i < size; i++) {
338 printf("%c", data[i]);
339 }
340 return size;
341}
342
311irecv_error_t irecv_set_receiver(irecv_device_t* device, irecv_receive_callback callback) { 343irecv_error_t irecv_set_receiver(irecv_device_t* device, irecv_receive_callback callback) {
312 if(device == NULL) { 344 if(device == NULL) {
313 return IRECV_ERROR_NO_DEVICE; 345 return IRECV_ERROR_NO_DEVICE;
@@ -325,3 +357,45 @@ irecv_error_t irecv_set_sender(irecv_device_t* device, irecv_send_callback callb
325 device->send_callback = callback; 357 device->send_callback = callback;
326 return IRECV_SUCCESS; 358 return IRECV_SUCCESS;
327} 359}
360
361const char* irecv_strerror(irecv_error_t error) {
362 switch(error) {
363 case IRECV_SUCCESS:
364 return irecv_error_success;
365
366 case IRECV_ERROR_NO_DEVICE:
367 return irecv_error_no_device;
368
369 case IRECV_ERROR_OUT_OF_MEMORY:
370 return irecv_error_out_of_memory;
371
372 case IRECV_ERROR_UNABLE_TO_CONNECT:
373 return irecv_error_unable_to_connect;
374
375 case IRECV_ERROR_INVALID_INPUT:
376 return irecv_error_invalid_input;
377
378 case IRECV_ERROR_UNKNOWN:
379 return irecv_error_unknown;
380
381 case IRECV_ERROR_FILE_NOT_FOUND:
382 return irecv_error_file_not_found;
383
384 case IRECV_ERROR_USB_UPLOAD:
385 return irecv_error_usb_upload;
386
387 case IRECV_ERROR_USB_STATUS:
388 return irecv_error_usb_status;
389
390 case IRECV_ERROR_USB_INTERFACE:
391 return irecv_error_usb_interface;
392
393 case IRECV_ERROR_USB_CONFIGURATION:
394 return irecv_error_usb_configuration;
395
396 default:
397 return irecv_error_unknown;
398 }
399
400 return NULL;
401}