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 @@
TODO List
-
-This 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.
------------------------------------------------
-1) 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.
-
-2) 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).
-
-3) 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.
+1) libirecovery debug should be as static variable so the client doesn't need to be passed and can be set only once.
+2) Need to implement irecv_saveenv()
+3) Need to implement irecv_bootx()
+4) Neex to implement irecv_go()
+5) Need to implement irecv_bgcolor()
+6) Need to implememt irecv_setpicture()
+7) Need to impelemnt irecv_reboot()
+8) Should figure out a better place to store callbacks so the CONNECTED callback can actually be used
+9) would be nice to change to use asyncronous connections
+10) could add a function to identify whether we're connected to iBoot/iBEC/iBSS or DFU
+11) could add a function to identify which version we're connected to
+12) could add a function to return the device serial number
+13) 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 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
+#ifndef LIBIRECOVERY_H
+#define LIBIRECOVERY_H
+
#include <libusb-1.0/libusb.h>
#define APPLE_VENDOR_ID 0x05AC
@@ -72,19 +75,22 @@ struct irecv_client {
libusb_device_handle* handle;
irecv_event_cb_t progress_callback;
irecv_event_cb_t received_callback;
+ irecv_event_cb_t connected_callback;
irecv_event_cb_t precommand_callback;
irecv_event_cb_t postcommand_callback;
+ irecv_event_cb_t disconnected_callback;
};
irecv_error_t irecv_event_subscribe(irecv_client_t client, irecv_event_type type, irecv_event_cb_t callback, void *user_data);
irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type type);
+irecv_error_t irecv_setenv(irecv_client_t client, const char* variable, const char* value);
irecv_error_t irecv_open(irecv_client_t* client);
irecv_error_t irecv_reset(irecv_client_t client);
irecv_error_t irecv_close(irecv_client_t client);
irecv_error_t irecv_receive(irecv_client_t client);
irecv_error_t irecv_send_exploit(irecv_client_t client);
irecv_error_t irecv_set_debug(irecv_client_t client, int level);
-irecv_error_t irecv_getenv(irecv_client_t client, unsigned char** var);
+irecv_error_t irecv_getenv(irecv_client_t client, const char* variable, char** value);
irecv_error_t irecv_get_cpid(irecv_client_t client, unsigned int* cpid);
irecv_error_t irecv_get_bdid(irecv_client_t client, unsigned int* bdid);
irecv_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);
irecv_error_t irecv_set_interface(irecv_client_t client, int interface, int alt_interface);
irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, unsigned int length);
const char* irecv_strerror(irecv_error_t error);
+
+#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) {
}
int postcommand_cb(irecv_client_t client, const irecv_event_t* event) {
- unsigned char* value = NULL;
+ char* value = NULL;
+ char* action = NULL;
+ char* command = NULL;
+ char* argument = NULL;
+ irecv_error_t error = IRECV_E_SUCCESS;
+
if (event->type == IRECV_POSTCOMMAND) {
- irecv_error_t error = 0;
- if (strstr(event->data, "getenv") != NULL) {
- error = irecv_getenv(client, &value);
+ command = strdup(event->data);
+ action = strtok(command, " ");
+ if (!strcmp(action, "getenv")) {
+ argument = strtok(NULL, " ");
+ error = irecv_getenv(client, argument, &value);
if (error != IRECV_E_SUCCESS) {
debug("%s\n", irecv_strerror(error));
+ free(command);
return error;
}
printf("%s\n", value);
+ free(value);
}
- if (!strcmp(event->data, "reboot")) {
+ if (!strcmp(action, "reboot")) {
quit = 1;
}
}
- if (value != NULL) free(value);
+ if (command) free(command);
return 0;
}
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
client->received_callback = callback;
break;
+ case IRECV_PROGRESS:
+ client->progress_callback = callback;
+
+ case IRECV_CONNECTED:
+ client->connected_callback = callback;
+
case IRECV_PRECOMMAND:
client->precommand_callback = callback;
break;
@@ -160,8 +166,8 @@ irecv_error_t irecv_event_subscribe(irecv_client_t client, irecv_event_type type
client->postcommand_callback = callback;
break;
- case IRECV_PROGRESS:
- client->progress_callback = callback;
+ case IRECV_DISCONNECTED:
+ client->disconnected_callback = callback;
default:
return IRECV_E_UNKNOWN_ERROR;
@@ -176,6 +182,12 @@ irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type ty
client->received_callback = NULL;
break;
+ case IRECV_PROGRESS:
+ client->progress_callback = NULL;
+
+ case IRECV_CONNECTED:
+ client->connected_callback = NULL;
+
case IRECV_PRECOMMAND:
client->precommand_callback = NULL;
break;
@@ -184,8 +196,8 @@ irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type ty
client->postcommand_callback = NULL;
break;
- case IRECV_PROGRESS:
- client->progress_callback = NULL;
+ case IRECV_DISCONNECTED:
+ client->disconnected_callback = NULL;
default:
return IRECV_E_UNKNOWN_ERROR;
@@ -196,6 +208,15 @@ irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type ty
irecv_error_t irecv_close(irecv_client_t client) {
if (client != NULL) {
+ if(client->disconnected_callback != NULL) {
+ irecv_event_t event;
+ event.size = 0;
+ event.data = NULL;
+ event.progress = 0;
+ event.type = IRECV_DISCONNECTED;
+ client->disconnected_callback(client, &event);
+ }
+
if (client->handle != NULL) {
libusb_release_interface(client->handle, client->interface);
libusb_close(client->handle);
@@ -393,22 +414,37 @@ irecv_error_t irecv_receive(irecv_client_t client) {
return IRECV_E_SUCCESS;
}
-irecv_error_t irecv_getenv(irecv_client_t client, unsigned char** var) {
+irecv_error_t irecv_getenv(irecv_client_t client, const char* variable, char** value) {
+ char command[256];
if (client == NULL || client->handle == NULL) {
return IRECV_E_NO_DEVICE;
}
- unsigned char* value = (unsigned char*) malloc(256);
- if (value == NULL) {
+ *value = NULL;
+
+ if(variable == NULL) {
+ return IRECV_E_UNKNOWN_ERROR;
+ }
+
+ memset(command, '\0', sizeof(command));
+ snprintf(command, sizeof(command)-1, "getenv %s", variable);
+ irecv_error_t error = irecv_send_command(client, command);
+ if(error != IRECV_E_SUCCESS) {
+ return error;
+ }
+
+ unsigned char* response = (unsigned char*) malloc(256);
+ if (response == NULL) {
return IRECV_E_OUT_OF_MEMORY;
}
- int ret = libusb_control_transfer(client->handle, 0xC0, 0, 0, 0, value, 256, 500);
+ memset(response, '\0', 256);
+ int ret = libusb_control_transfer(client->handle, 0xC0, 0, 0, 0, response, 255, 500);
if (ret < 0) {
return IRECV_E_UNKNOWN_ERROR;
}
- *var = value;
+ *value = response;
return IRECV_E_SUCCESS;
}
@@ -484,6 +520,26 @@ irecv_error_t irecv_send_exploit(irecv_client_t client) {
return IRECV_E_SUCCESS;
}
+irecv_error_t irecv_setenv(irecv_client_t client, const char* variable, const char* value) {
+ char command[256];
+ if (client == NULL || client->handle == NULL) {
+ return IRECV_E_NO_DEVICE;
+ }
+
+ if(variable == NULL || value == NULL) {
+ return IRECV_E_UNKNOWN_ERROR;
+ }
+
+ memset(command, '\0', sizeof(command));
+ snprintf(command, sizeof(command)-1, "setenv %s %s", variable, value);
+ irecv_error_t error = irecv_send_command(client, command);
+ if(error != IRECV_E_SUCCESS) {
+ return error;
+ }
+
+ return IRECV_E_SUCCESS;
+}
+
const char* irecv_strerror(irecv_error_t error) {
switch (error) {
case IRECV_E_SUCCESS: