diff options
Diffstat (limited to 'src/libirecovery.c')
| -rw-r--r-- | src/libirecovery.c | 100 |
1 files changed, 87 insertions, 13 deletions
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 | ||
| 30 | const char* irecv_error_invalid_input = "Invalid input"; | ||
| 31 | const char* irecv_error_unknown = "Unknown error"; | ||
| 32 | const char* irecv_error_file_not_found = "Unable to find file"; | ||
| 33 | const char* irecv_error_usb_status = "Invalid device status"; | ||
| 34 | const char* irecv_error_no_device = "Unable to find device"; | ||
| 35 | const char* irecv_error_out_of_memory = "Unable to allocate memory"; | ||
| 36 | const char* irecv_error_unable_to_connect = "Unable to connect to device"; | ||
| 37 | const char* irecv_error_usb_interface = "Unable to set device interface"; | ||
| 38 | const char* irecv_error_success = "Command completed successfully"; | ||
| 39 | const char* irecv_error_usb_upload = "Unable to upload data to device"; | ||
| 40 | const char* irecv_error_usb_configuration = "Unable to set device configuration"; | ||
| 41 | |||
| 42 | int irecv_default_sender(irecv_device_t* device, unsigned char* data, int size); | ||
| 43 | int irecv_default_receiver(irecv_device_t* device, unsigned char* data, int size); | ||
| 44 | |||
| 30 | irecv_device_t* irecv_init() { | 45 | irecv_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 | ||
| 175 | irecv_error_t irecv_send_command(irecv_device_t* device, unsigned char* command) { | 195 | irecv_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 | ||
| 331 | int irecv_default_sender(irecv_device_t* device, unsigned char* data, int size) { | ||
| 332 | return size; | ||
| 333 | } | ||
| 334 | |||
| 335 | int 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 | |||
| 311 | irecv_error_t irecv_set_receiver(irecv_device_t* device, irecv_receive_callback callback) { | 343 | irecv_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 | |||
| 361 | const 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 | } | ||
