diff options
| author | 2010-05-30 03:33:03 -0400 | |
|---|---|---|
| committer | 2010-05-30 03:33:03 -0400 | |
| commit | 30fd56859f50dea5712492807a1b9784da9fec11 (patch) | |
| tree | 66b3c2569616315cbfa843f23a5c192b38255be5 /src/libirecovery.c | |
| parent | 1e4d65033781cd44876b7b2634976259e4bef7c5 (diff) | |
| download | libirecovery-30fd56859f50dea5712492807a1b9784da9fec11.tar.gz libirecovery-30fd56859f50dea5712492807a1b9784da9fec11.tar.bz2 | |
Implemented a few more events, got rid of the old ones and cleaned up a little
Diffstat (limited to 'src/libirecovery.c')
| -rw-r--r-- | src/libirecovery.c | 136 |
1 files changed, 31 insertions, 105 deletions
diff --git a/src/libirecovery.c b/src/libirecovery.c index 8f029ed..a641562 100644 --- a/src/libirecovery.c +++ b/src/libirecovery.c | |||
| @@ -27,9 +27,6 @@ | |||
| 27 | #define BUFFER_SIZE 0x1000 | 27 | #define BUFFER_SIZE 0x1000 |
| 28 | #define debug(...) if(client->debug) fprintf(stderr, __VA_ARGS__) | 28 | #define debug(...) if(client->debug) fprintf(stderr, __VA_ARGS__) |
| 29 | 29 | ||
| 30 | int irecv_default_sender(irecv_client_t client, unsigned char* data, int size); | ||
| 31 | int irecv_default_receiver(irecv_client_t client, unsigned char* data, int size); | ||
| 32 | |||
| 33 | irecv_error_t irecv_open(irecv_client_t* pclient) { | 30 | irecv_error_t irecv_open(irecv_client_t* pclient) { |
| 34 | int i = 0; | 31 | int i = 0; |
| 35 | char serial[256]; | 32 | char serial[256]; |
| @@ -41,7 +38,6 @@ irecv_error_t irecv_open(irecv_client_t* pclient) { | |||
| 41 | 38 | ||
| 42 | *pclient = NULL; | 39 | *pclient = NULL; |
| 43 | libusb_init(&usb_context); | 40 | libusb_init(&usb_context); |
| 44 | //libusb_init(NULL); | ||
| 45 | irecv_error_t error = IRECV_E_SUCCESS; | 41 | irecv_error_t error = IRECV_E_SUCCESS; |
| 46 | int usb_device_count = libusb_get_device_list(usb_context, &usb_device_list); | 42 | int usb_device_count = libusb_get_device_list(usb_context, &usb_device_list); |
| 47 | for (i = 0; i < usb_device_count; i++) { | 43 | for (i = 0; i < usb_device_count; i++) { |
| @@ -49,10 +45,11 @@ irecv_error_t irecv_open(irecv_client_t* pclient) { | |||
| 49 | libusb_get_device_descriptor(usb_device, &usb_descriptor); | 45 | libusb_get_device_descriptor(usb_device, &usb_descriptor); |
| 50 | if (usb_descriptor.idVendor == APPLE_VENDOR_ID) { | 46 | if (usb_descriptor.idVendor == APPLE_VENDOR_ID) { |
| 51 | /* verify this device is in a mode we understand */ | 47 | /* verify this device is in a mode we understand */ |
| 52 | if (usb_descriptor.idProduct == kRecoveryMode1 || usb_descriptor.idProduct | 48 | if (usb_descriptor.idProduct == kRecoveryMode1 || |
| 53 | == kRecoveryMode2 || usb_descriptor.idProduct == kRecoveryMode3 | 49 | usb_descriptor.idProduct == kRecoveryMode2 || |
| 54 | || usb_descriptor.idProduct == kRecoveryMode4 || usb_descriptor.idProduct | 50 | usb_descriptor.idProduct == kRecoveryMode3 || |
| 55 | == kDfuMode) { | 51 | usb_descriptor.idProduct == kRecoveryMode4 || |
| 52 | usb_descriptor.idProduct == kDfuMode) { | ||
| 56 | 53 | ||
| 57 | libusb_open(usb_device, &usb_handle); | 54 | libusb_open(usb_device, &usb_handle); |
| 58 | if (usb_handle == NULL) { | 55 | if (usb_handle == NULL) { |
| @@ -61,8 +58,6 @@ irecv_error_t irecv_open(irecv_client_t* pclient) { | |||
| 61 | libusb_exit(usb_context); | 58 | libusb_exit(usb_context); |
| 62 | return IRECV_E_UNABLE_TO_CONNECT; | 59 | return IRECV_E_UNABLE_TO_CONNECT; |
| 63 | } | 60 | } |
| 64 | libusb_set_debug(usb_context, 3); | ||
| 65 | |||
| 66 | libusb_free_device_list(usb_device_list, 1); | 61 | libusb_free_device_list(usb_device_list, 1); |
| 67 | 62 | ||
| 68 | irecv_client_t client = (irecv_client_t) malloc(sizeof(struct irecv_client)); | 63 | irecv_client_t client = (irecv_client_t) malloc(sizeof(struct irecv_client)); |
| @@ -71,6 +66,7 @@ irecv_error_t irecv_open(irecv_client_t* pclient) { | |||
| 71 | libusb_exit(usb_context); | 66 | libusb_exit(usb_context); |
| 72 | return IRECV_E_OUT_OF_MEMORY; | 67 | return IRECV_E_OUT_OF_MEMORY; |
| 73 | } | 68 | } |
| 69 | |||
| 74 | memset(client, '\0', sizeof(struct irecv_client)); | 70 | memset(client, '\0', sizeof(struct irecv_client)); |
| 75 | client->interface = 0; | 71 | client->interface = 0; |
| 76 | client->handle = usb_handle; | 72 | client->handle = usb_handle; |
| @@ -150,6 +146,10 @@ irecv_error_t irecv_reset(irecv_client_t client) { | |||
| 150 | 146 | ||
| 151 | irecv_error_t irecv_event_subscribe(irecv_client_t client, irecv_event_type type, irecv_event_cb_t callback, void* user_data) { | 147 | irecv_error_t irecv_event_subscribe(irecv_client_t client, irecv_event_type type, irecv_event_cb_t callback, void* user_data) { |
| 152 | switch(type) { | 148 | switch(type) { |
| 149 | case IRECV_RECEIVED: | ||
| 150 | client->received_callback = callback; | ||
| 151 | break; | ||
| 152 | |||
| 153 | case IRECV_PRECOMMAND: | 153 | case IRECV_PRECOMMAND: |
| 154 | client->precommand_callback = callback; | 154 | client->precommand_callback = callback; |
| 155 | break; | 155 | break; |
| @@ -167,6 +167,10 @@ irecv_error_t irecv_event_subscribe(irecv_client_t client, irecv_event_type type | |||
| 167 | 167 | ||
| 168 | irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type type) { | 168 | irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type type) { |
| 169 | switch(type) { | 169 | switch(type) { |
| 170 | case IRECV_RECEIVED: | ||
| 171 | client->received_callback = NULL; | ||
| 172 | break; | ||
| 173 | |||
| 170 | case IRECV_PRECOMMAND: | 174 | case IRECV_PRECOMMAND: |
| 171 | client->precommand_callback = NULL; | 175 | client->precommand_callback = NULL; |
| 172 | break; | 176 | break; |
| @@ -185,7 +189,7 @@ irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type ty | |||
| 185 | irecv_error_t irecv_close(irecv_client_t client) { | 189 | irecv_error_t irecv_close(irecv_client_t client) { |
| 186 | if (client != NULL) { | 190 | if (client != NULL) { |
| 187 | if (client->handle != NULL) { | 191 | if (client->handle != NULL) { |
| 188 | libusb_release_interface(client->handle, 1); | 192 | libusb_release_interface(client->handle, client->interface); |
| 189 | libusb_close(client->handle); | 193 | libusb_close(client->handle); |
| 190 | client->handle = NULL; | 194 | client->handle = NULL; |
| 191 | } | 195 | } |
| @@ -212,39 +216,11 @@ irecv_error_t irecv_set_debug(irecv_client_t client, int level) { | |||
| 212 | return IRECV_E_SUCCESS; | 216 | return IRECV_E_SUCCESS; |
| 213 | } | 217 | } |
| 214 | 218 | ||
| 215 | irecv_error_t irecv_send(irecv_client_t client, unsigned char* command) { | ||
| 216 | if (client == NULL || client->handle == NULL) { | ||
| 217 | return IRECV_E_NO_DEVICE; | ||
| 218 | } | ||
| 219 | |||
| 220 | unsigned int length = strlen(command); | ||
| 221 | if (length >= 0x100) { | ||
| 222 | length = 0xFF; | ||
| 223 | } | ||
| 224 | |||
| 225 | if (client->send_callback != NULL) { | ||
| 226 | // Call our user defined callback first, this must return a number of bytes to send | ||
| 227 | // or zero to abort send. | ||
| 228 | length = client->send_callback(client, command, length); | ||
| 229 | } | ||
| 230 | |||
| 231 | if (length > 0) { | ||
| 232 | irecv_send_command(client, command); | ||
| 233 | } | ||
| 234 | |||
| 235 | return IRECV_E_SUCCESS; | ||
| 236 | } | ||
| 237 | |||
| 238 | irecv_error_t irecv_send_command(irecv_client_t client, unsigned char* command) { | 219 | irecv_error_t irecv_send_command(irecv_client_t client, unsigned char* command) { |
| 239 | if (client == NULL || client->handle == NULL) { | 220 | if (client == NULL || client->handle == NULL) { |
| 240 | return IRECV_E_NO_DEVICE; | 221 | return IRECV_E_NO_DEVICE; |
| 241 | } | 222 | } |
| 242 | /* | 223 | |
| 243 | irecv_error_t error = irecv_set_interface(client, 1, 1); | ||
| 244 | if(error != IRECV_E_SUCCESS) { | ||
| 245 | return error; | ||
| 246 | } | ||
| 247 | */ | ||
| 248 | unsigned int length = strlen(command); | 224 | unsigned int length = strlen(command); |
| 249 | if (length >= 0x100) { | 225 | if (length >= 0x100) { |
| 250 | length = 0xFF; | 226 | length = 0xFF; |
| @@ -252,6 +228,7 @@ irecv_error_t irecv_send_command(irecv_client_t client, unsigned char* command) | |||
| 252 | 228 | ||
| 253 | irecv_event_t event; | 229 | irecv_event_t event; |
| 254 | if(client->precommand_callback != NULL) { | 230 | if(client->precommand_callback != NULL) { |
| 231 | event.size = length; | ||
| 255 | event.data = command; | 232 | event.data = command; |
| 256 | event.type = IRECV_PRECOMMAND; | 233 | event.type = IRECV_PRECOMMAND; |
| 257 | if(client->precommand_callback(client, &event)) { | 234 | if(client->precommand_callback(client, &event)) { |
| @@ -264,6 +241,7 @@ irecv_error_t irecv_send_command(irecv_client_t client, unsigned char* command) | |||
| 264 | } | 241 | } |
| 265 | 242 | ||
| 266 | if(client->postcommand_callback != NULL) { | 243 | if(client->postcommand_callback != NULL) { |
| 244 | event.size = length; | ||
| 267 | event.data = command; | 245 | event.data = command; |
| 268 | event.type = IRECV_POSTCOMMAND; | 246 | event.type = IRECV_POSTCOMMAND; |
| 269 | if(client->postcommand_callback(client, &event)) { | 247 | if(client->postcommand_callback(client, &event)) { |
| @@ -312,12 +290,7 @@ irecv_error_t irecv_get_status(irecv_client_t client, unsigned int* status) { | |||
| 312 | *status = 0; | 290 | *status = 0; |
| 313 | return IRECV_E_NO_DEVICE; | 291 | return IRECV_E_NO_DEVICE; |
| 314 | } | 292 | } |
| 315 | /* | 293 | |
| 316 | irecv_error_t error = irecv_set_interface(client, 1, 1); | ||
| 317 | if(error != IRECV_E_SUCCESS) { | ||
| 318 | return error; | ||
| 319 | } | ||
| 320 | */ | ||
| 321 | unsigned char buffer[6]; | 294 | unsigned char buffer[6]; |
| 322 | memset(buffer, '\0', 6); | 295 | memset(buffer, '\0', 6); |
| 323 | if (libusb_control_transfer(client->handle, 0xA1, 3, 0, 0, buffer, 6, 1000) != 6) { | 296 | if (libusb_control_transfer(client->handle, 0xA1, 3, 0, 0, buffer, 6, 1000) != 6) { |
| @@ -335,12 +308,7 @@ irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, un | |||
| 335 | if (client == NULL || client->handle == NULL) { | 308 | if (client == NULL || client->handle == NULL) { |
| 336 | return IRECV_E_NO_DEVICE; | 309 | return IRECV_E_NO_DEVICE; |
| 337 | } | 310 | } |
| 338 | /* | 311 | |
| 339 | error = irecv_set_interface(client, 1, 1); | ||
| 340 | if(error != IRECV_E_SUCCESS) { | ||
| 341 | return error; | ||
| 342 | } | ||
| 343 | */ | ||
| 344 | int last = length % 0x800; | 312 | int last = length % 0x800; |
| 345 | int packets = length / 0x800; | 313 | int packets = length / 0x800; |
| 346 | if (last != 0) { | 314 | if (last != 0) { |
| @@ -387,54 +355,22 @@ irecv_error_t irecv_receive(irecv_client_t client) { | |||
| 387 | if (client == NULL || client->handle == NULL) { | 355 | if (client == NULL || client->handle == NULL) { |
| 388 | return IRECV_E_NO_DEVICE; | 356 | return IRECV_E_NO_DEVICE; |
| 389 | } | 357 | } |
| 390 | /* | 358 | |
| 391 | irecv_error_t error = irecv_set_interface(client, 1, 1); | ||
| 392 | if(error != IRECV_E_SUCCESS) { | ||
| 393 | return error; | ||
| 394 | } | ||
| 395 | */ | ||
| 396 | int bytes = 0; | 359 | int bytes = 0; |
| 397 | while (libusb_bulk_transfer(client->handle, 0x81, buffer, BUFFER_SIZE, &bytes, 100) == 0) { | 360 | while (libusb_bulk_transfer(client->handle, 0x81, buffer, BUFFER_SIZE, &bytes, 100) == 0) { |
| 398 | if (bytes > 0) { | 361 | if (bytes > 0) { |
| 399 | if (client->receive_callback != NULL) { | 362 | if (client->received_callback != NULL) { |
| 400 | if (client->receive_callback(client, buffer, bytes) != bytes) { | 363 | irecv_event_t event; |
| 401 | return IRECV_E_UNKNOWN_ERROR; | 364 | event.size = bytes; |
| 365 | event.data = buffer; | ||
| 366 | event.type = IRECV_RECEIVED; | ||
| 367 | if (client->received_callback(client, &event) != 0) { | ||
| 368 | return IRECV_E_SUCCESS; | ||
| 402 | } | 369 | } |
| 403 | } | 370 | } |
| 404 | } else | 371 | } else break; |
| 405 | break; | ||
| 406 | } | ||
| 407 | |||
| 408 | return IRECV_E_SUCCESS; | ||
| 409 | } | ||
| 410 | |||
| 411 | int irecv_default_sender(irecv_client_t client, unsigned char* data, int size) { | ||
| 412 | return size; | ||
| 413 | } | ||
| 414 | |||
| 415 | int irecv_default_receiver(irecv_client_t client, unsigned char* data, int size) { | ||
| 416 | int i = 0; | ||
| 417 | for (i = 0; i < size; i++) { | ||
| 418 | printf("%c", data[i]); | ||
| 419 | } | ||
| 420 | return size; | ||
| 421 | } | ||
| 422 | |||
| 423 | irecv_error_t irecv_set_receiver(irecv_client_t client, irecv_receive_callback callback) { | ||
| 424 | if (client == NULL) { | ||
| 425 | return IRECV_E_NO_DEVICE; | ||
| 426 | } | ||
| 427 | |||
| 428 | client->receive_callback = callback; | ||
| 429 | return IRECV_E_SUCCESS; | ||
| 430 | } | ||
| 431 | |||
| 432 | irecv_error_t irecv_set_sender(irecv_client_t client, irecv_send_callback callback) { | ||
| 433 | if (client == NULL) { | ||
| 434 | return IRECV_E_NO_DEVICE; | ||
| 435 | } | 372 | } |
| 436 | 373 | ||
| 437 | client->send_callback = callback; | ||
| 438 | return IRECV_E_SUCCESS; | 374 | return IRECV_E_SUCCESS; |
| 439 | } | 375 | } |
| 440 | 376 | ||
| @@ -442,12 +378,7 @@ irecv_error_t irecv_getenv(irecv_client_t client, unsigned char** var) { | |||
| 442 | if (client == NULL || client->handle == NULL) { | 378 | if (client == NULL || client->handle == NULL) { |
| 443 | return IRECV_E_NO_DEVICE; | 379 | return IRECV_E_NO_DEVICE; |
| 444 | } | 380 | } |
| 445 | /* | 381 | |
| 446 | irecv_error_t error = irecv_set_interface(client, 1, 1); | ||
| 447 | if(error != IRECV_E_SUCCESS) { | ||
| 448 | return error; | ||
| 449 | } | ||
| 450 | */ | ||
| 451 | unsigned char* value = (unsigned char*) malloc(256); | 382 | unsigned char* value = (unsigned char*) malloc(256); |
| 452 | if (value == NULL) { | 383 | if (value == NULL) { |
| 453 | return IRECV_E_OUT_OF_MEMORY; | 384 | return IRECV_E_OUT_OF_MEMORY; |
| @@ -488,12 +419,7 @@ irecv_error_t irecv_send_exploit(irecv_client_t client) { | |||
| 488 | if (client == NULL || client->handle == NULL) { | 419 | if (client == NULL || client->handle == NULL) { |
| 489 | return IRECV_E_NO_DEVICE; | 420 | return IRECV_E_NO_DEVICE; |
| 490 | } | 421 | } |
| 491 | /* | 422 | |
| 492 | irecv_error_t error = irecv_set_interface(client, 1, 1); | ||
| 493 | if(error != IRECV_E_SUCCESS) { | ||
| 494 | return error; | ||
| 495 | } | ||
| 496 | */ | ||
| 497 | libusb_control_transfer(client->handle, 0x21, 2, 0, 0, NULL, 0, 100); | 423 | libusb_control_transfer(client->handle, 0x21, 2, 0, 0, NULL, 0, 100); |
| 498 | return IRECV_E_SUCCESS; | 424 | return IRECV_E_SUCCESS; |
| 499 | } | 425 | } |
