summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO20
-rw-r--r--include/libirecovery.h10
-rw-r--r--src/irecovery.c21
-rw-r--r--src/libirecovery.c74
4 files changed, 102 insertions, 23 deletions
diff --git a/TODO b/TODO
index 61d4872..306a1ae 100644
--- a/TODO
+++ b/TODO
@@ -1,10 +1,16 @@
1TODO List 1TODO List
2
3This is just a list of a couple things i've been meaning to get around to, but haven't had the chance. If you finish any of them you can go ahead and remove it from the list.
4------------------------------------------------ 2------------------------------------------------
5 3
61) Port irecovery to libusb1.0. I've already done this in some of my other projects, and I think westbaer's brach has already been ported but our branches forked off a long time ago. 41) libirecovery debug should be as static variable so the client doesn't need to be passed and can be set only once.
7 52) Need to implement irecv_saveenv()
82) Add support for getenv command. getenv sends the request variable back in a control message that can be fetched with usb_control_message(handle, 0xC0, 0, 0, 0, buffer, size, 500). 63) Need to implement irecv_bootx()
9 74) Neex to implement irecv_go()
103) Fix command line parsing so you can send arguments to commands. Currently if you try "irecovery -c bgcolor 0 0 0" only "bgcolor" will be sent and none of it's arguments. 85) Need to implement irecv_bgcolor()
96) Need to implememt irecv_setpicture()
107) Need to impelemnt irecv_reboot()
118) Should figure out a better place to store callbacks so the CONNECTED callback can actually be used
129) would be nice to change to use asyncronous connections
1310) could add a function to identify whether we're connected to iBoot/iBEC/iBSS or DFU
1411) could add a function to identify which version we're connected to
1512) could add a function to return the device serial number
1613) fix command parsing to strip quotes \ No newline at end of file
diff --git a/include/libirecovery.h b/include/libirecovery.h
index d01e022..50ec5be 100644
--- a/include/libirecovery.h
+++ b/include/libirecovery.h
@@ -16,6 +16,9 @@
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 **/ 17 **/
18 18
19#ifndef LIBIRECOVERY_H
20#define LIBIRECOVERY_H
21
19#include <libusb-1.0/libusb.h> 22#include <libusb-1.0/libusb.h>
20 23
21#define APPLE_VENDOR_ID 0x05AC 24#define APPLE_VENDOR_ID 0x05AC
@@ -72,19 +75,22 @@ struct irecv_client {
72 libusb_device_handle* handle; 75 libusb_device_handle* handle;
73 irecv_event_cb_t progress_callback; 76 irecv_event_cb_t progress_callback;
74 irecv_event_cb_t received_callback; 77 irecv_event_cb_t received_callback;
78 irecv_event_cb_t connected_callback;
75 irecv_event_cb_t precommand_callback; 79 irecv_event_cb_t precommand_callback;
76 irecv_event_cb_t postcommand_callback; 80 irecv_event_cb_t postcommand_callback;
81 irecv_event_cb_t disconnected_callback;
77}; 82};
78 83
79irecv_error_t irecv_event_subscribe(irecv_client_t client, irecv_event_type type, irecv_event_cb_t callback, void *user_data); 84irecv_error_t irecv_event_subscribe(irecv_client_t client, irecv_event_type type, irecv_event_cb_t callback, void *user_data);
80irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type type); 85irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type type);
86irecv_error_t irecv_setenv(irecv_client_t client, const char* variable, const char* value);
81irecv_error_t irecv_open(irecv_client_t* client); 87irecv_error_t irecv_open(irecv_client_t* client);
82irecv_error_t irecv_reset(irecv_client_t client); 88irecv_error_t irecv_reset(irecv_client_t client);
83irecv_error_t irecv_close(irecv_client_t client); 89irecv_error_t irecv_close(irecv_client_t client);
84irecv_error_t irecv_receive(irecv_client_t client); 90irecv_error_t irecv_receive(irecv_client_t client);
85irecv_error_t irecv_send_exploit(irecv_client_t client); 91irecv_error_t irecv_send_exploit(irecv_client_t client);
86irecv_error_t irecv_set_debug(irecv_client_t client, int level); 92irecv_error_t irecv_set_debug(irecv_client_t client, int level);
87irecv_error_t irecv_getenv(irecv_client_t client, unsigned char** var); 93irecv_error_t irecv_getenv(irecv_client_t client, const char* variable, char** value);
88irecv_error_t irecv_get_cpid(irecv_client_t client, unsigned int* cpid); 94irecv_error_t irecv_get_cpid(irecv_client_t client, unsigned int* cpid);
89irecv_error_t irecv_get_bdid(irecv_client_t client, unsigned int* bdid); 95irecv_error_t irecv_get_bdid(irecv_client_t client, unsigned int* bdid);
90irecv_error_t irecv_get_ecid(irecv_client_t client, unsigned long long* ecid); 96irecv_error_t irecv_get_ecid(irecv_client_t client, unsigned long long* ecid);
@@ -95,3 +101,5 @@ irecv_error_t irecv_set_configuration(irecv_client_t client, int configuration);
95irecv_error_t irecv_set_interface(irecv_client_t client, int interface, int alt_interface); 101irecv_error_t irecv_set_interface(irecv_client_t client, int interface, int alt_interface);
96irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, unsigned int length); 102irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, unsigned int length);
97const char* irecv_strerror(irecv_error_t error); 103const char* irecv_strerror(irecv_error_t error);
104
105#endif
diff --git a/src/irecovery.c b/src/irecovery.c
index fcc745c..baae17e 100644
--- a/src/irecovery.c
+++ b/src/irecovery.c
@@ -139,24 +139,33 @@ int precommand_cb(irecv_client_t client, const irecv_event_t* event) {
139} 139}
140 140
141int postcommand_cb(irecv_client_t client, const irecv_event_t* event) { 141int postcommand_cb(irecv_client_t client, const irecv_event_t* event) {
142 unsigned char* value = NULL; 142 char* value = NULL;
143 char* action = NULL;
144 char* command = NULL;
145 char* argument = NULL;
146 irecv_error_t error = IRECV_E_SUCCESS;
147
143 if (event->type == IRECV_POSTCOMMAND) { 148 if (event->type == IRECV_POSTCOMMAND) {
144 irecv_error_t error = 0; 149 command = strdup(event->data);
145 if (strstr(event->data, "getenv") != NULL) { 150 action = strtok(command, " ");
146 error = irecv_getenv(client, &value); 151 if (!strcmp(action, "getenv")) {
152 argument = strtok(NULL, " ");
153 error = irecv_getenv(client, argument, &value);
147 if (error != IRECV_E_SUCCESS) { 154 if (error != IRECV_E_SUCCESS) {
148 debug("%s\n", irecv_strerror(error)); 155 debug("%s\n", irecv_strerror(error));
156 free(command);
149 return error; 157 return error;
150 } 158 }
151 printf("%s\n", value); 159 printf("%s\n", value);
160 free(value);
152 } 161 }
153 162
154 if (!strcmp(event->data, "reboot")) { 163 if (!strcmp(action, "reboot")) {
155 quit = 1; 164 quit = 1;
156 } 165 }
157 } 166 }
158 167
159 if (value != NULL) free(value); 168 if (command) free(command);
160 return 0; 169 return 0;
161} 170}
162 171
diff --git a/src/libirecovery.c b/src/libirecovery.c
index 4900fbf..05a162f 100644
--- a/src/libirecovery.c
+++ b/src/libirecovery.c
@@ -152,6 +152,12 @@ irecv_error_t irecv_event_subscribe(irecv_client_t client, irecv_event_type type
152 client->received_callback = callback; 152 client->received_callback = callback;
153 break; 153 break;
154 154
155 case IRECV_PROGRESS:
156 client->progress_callback = callback;
157
158 case IRECV_CONNECTED:
159 client->connected_callback = callback;
160
155 case IRECV_PRECOMMAND: 161 case IRECV_PRECOMMAND:
156 client->precommand_callback = callback; 162 client->precommand_callback = callback;
157 break; 163 break;
@@ -160,8 +166,8 @@ irecv_error_t irecv_event_subscribe(irecv_client_t client, irecv_event_type type
160 client->postcommand_callback = callback; 166 client->postcommand_callback = callback;
161 break; 167 break;
162 168
163 case IRECV_PROGRESS: 169 case IRECV_DISCONNECTED:
164 client->progress_callback = callback; 170 client->disconnected_callback = callback;
165 171
166 default: 172 default:
167 return IRECV_E_UNKNOWN_ERROR; 173 return IRECV_E_UNKNOWN_ERROR;
@@ -176,6 +182,12 @@ irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type ty
176 client->received_callback = NULL; 182 client->received_callback = NULL;
177 break; 183 break;
178 184
185 case IRECV_PROGRESS:
186 client->progress_callback = NULL;
187
188 case IRECV_CONNECTED:
189 client->connected_callback = NULL;
190
179 case IRECV_PRECOMMAND: 191 case IRECV_PRECOMMAND:
180 client->precommand_callback = NULL; 192 client->precommand_callback = NULL;
181 break; 193 break;
@@ -184,8 +196,8 @@ irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type ty
184 client->postcommand_callback = NULL; 196 client->postcommand_callback = NULL;
185 break; 197 break;
186 198
187 case IRECV_PROGRESS: 199 case IRECV_DISCONNECTED:
188 client->progress_callback = NULL; 200 client->disconnected_callback = NULL;
189 201
190 default: 202 default:
191 return IRECV_E_UNKNOWN_ERROR; 203 return IRECV_E_UNKNOWN_ERROR;
@@ -196,6 +208,15 @@ irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type ty
196 208
197irecv_error_t irecv_close(irecv_client_t client) { 209irecv_error_t irecv_close(irecv_client_t client) {
198 if (client != NULL) { 210 if (client != NULL) {
211 if(client->disconnected_callback != NULL) {
212 irecv_event_t event;
213 event.size = 0;
214 event.data = NULL;
215 event.progress = 0;
216 event.type = IRECV_DISCONNECTED;
217 client->disconnected_callback(client, &event);
218 }
219
199 if (client->handle != NULL) { 220 if (client->handle != NULL) {
200 libusb_release_interface(client->handle, client->interface); 221 libusb_release_interface(client->handle, client->interface);
201 libusb_close(client->handle); 222 libusb_close(client->handle);
@@ -393,22 +414,37 @@ irecv_error_t irecv_receive(irecv_client_t client) {
393 return IRECV_E_SUCCESS; 414 return IRECV_E_SUCCESS;
394} 415}
395 416
396irecv_error_t irecv_getenv(irecv_client_t client, unsigned char** var) { 417irecv_error_t irecv_getenv(irecv_client_t client, const char* variable, char** value) {
418 char command[256];
397 if (client == NULL || client->handle == NULL) { 419 if (client == NULL || client->handle == NULL) {
398 return IRECV_E_NO_DEVICE; 420 return IRECV_E_NO_DEVICE;
399 } 421 }
400 422
401 unsigned char* value = (unsigned char*) malloc(256); 423 *value = NULL;
402 if (value == NULL) { 424
425 if(variable == NULL) {
426 return IRECV_E_UNKNOWN_ERROR;
427 }
428
429 memset(command, '\0', sizeof(command));
430 snprintf(command, sizeof(command)-1, "getenv %s", variable);
431 irecv_error_t error = irecv_send_command(client, command);
432 if(error != IRECV_E_SUCCESS) {
433 return error;
434 }
435
436 unsigned char* response = (unsigned char*) malloc(256);
437 if (response == NULL) {
403 return IRECV_E_OUT_OF_MEMORY; 438 return IRECV_E_OUT_OF_MEMORY;
404 } 439 }
405 440
406 int ret = libusb_control_transfer(client->handle, 0xC0, 0, 0, 0, value, 256, 500); 441 memset(response, '\0', 256);
442 int ret = libusb_control_transfer(client->handle, 0xC0, 0, 0, 0, response, 255, 500);
407 if (ret < 0) { 443 if (ret < 0) {
408 return IRECV_E_UNKNOWN_ERROR; 444 return IRECV_E_UNKNOWN_ERROR;
409 } 445 }
410 446
411 *var = value; 447 *value = response;
412 return IRECV_E_SUCCESS; 448 return IRECV_E_SUCCESS;
413} 449}
414 450
@@ -484,6 +520,26 @@ irecv_error_t irecv_send_exploit(irecv_client_t client) {
484 return IRECV_E_SUCCESS; 520 return IRECV_E_SUCCESS;
485} 521}
486 522
523irecv_error_t irecv_setenv(irecv_client_t client, const char* variable, const char* value) {
524 char command[256];
525 if (client == NULL || client->handle == NULL) {
526 return IRECV_E_NO_DEVICE;
527 }
528
529 if(variable == NULL || value == NULL) {
530 return IRECV_E_UNKNOWN_ERROR;
531 }
532
533 memset(command, '\0', sizeof(command));
534 snprintf(command, sizeof(command)-1, "setenv %s %s", variable, value);
535 irecv_error_t error = irecv_send_command(client, command);
536 if(error != IRECV_E_SUCCESS) {
537 return error;
538 }
539
540 return IRECV_E_SUCCESS;
541}
542
487const char* irecv_strerror(irecv_error_t error) { 543const char* irecv_strerror(irecv_error_t error) {
488 switch (error) { 544 switch (error) {
489 case IRECV_E_SUCCESS: 545 case IRECV_E_SUCCESS: