summaryrefslogtreecommitdiffstats
path: root/src/libirecovery.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libirecovery.c')
-rw-r--r--src/libirecovery.c76
1 files changed, 45 insertions, 31 deletions
diff --git a/src/libirecovery.c b/src/libirecovery.c
index 630a9b7..c31a424 100644
--- a/src/libirecovery.c
+++ b/src/libirecovery.c
@@ -23,27 +23,21 @@
23 23
24#include "libirecovery.h" 24#include "libirecovery.h"
25 25
26static unsigned int irecv_debug = 0; 26irecv_device_t* irecv_init() {
27
28int irecv_init(irecv_device** p_device) {
29 struct libusb_context* usb_context = NULL; 27 struct libusb_context* usb_context = NULL;
30 28
31 libusb_init(&usb_context); 29 libusb_init(&usb_context);
32 if (irecv_debug) libusb_set_debug(usb_context, 3); 30 irecv_device_t* device = (irecv_device_t*) malloc(sizeof(irecv_device_t));
33
34 irecv_device* device = (irecv_device*) malloc(sizeof(irecv_device));
35 if (device == NULL) { 31 if (device == NULL) {
36 *p_device = NULL; 32 return NULL;
37 return IRECV_ERROR_OUT_OF_MEMORY;
38 } 33 }
39 memset(device, '\0', sizeof(irecv_device)); 34 memset(device, '\0', sizeof(irecv_device_t));
40 device->context = usb_context; 35 device->context = usb_context;
41 36
42 *p_device = device; 37 return device;
43 return IRECV_SUCCESS;
44} 38}
45 39
46int irecv_open(irecv_device* device) { 40int irecv_open(irecv_device_t* device) {
47 int i = 0; 41 int i = 0;
48 int usb_device_count = 0; 42 int usb_device_count = 0;
49 struct libusb_device* usb_device = NULL; 43 struct libusb_device* usb_device = NULL;
@@ -77,7 +71,7 @@ int irecv_open(irecv_device* device) {
77 return IRECV_ERROR_NO_DEVICE; 71 return IRECV_ERROR_NO_DEVICE;
78} 72}
79 73
80int irecv_reset(irecv_device* device) { 74int irecv_reset(irecv_device_t* device) {
81 if (device == NULL || device->handle != NULL) { 75 if (device == NULL || device->handle != NULL) {
82 return IRECV_ERROR_NO_DEVICE; 76 return IRECV_ERROR_NO_DEVICE;
83 } 77 }
@@ -86,7 +80,7 @@ int irecv_reset(irecv_device* device) {
86 return IRECV_SUCCESS; 80 return IRECV_SUCCESS;
87} 81}
88 82
89int irecv_close(irecv_device* device) { 83int irecv_close(irecv_device_t* device) {
90 if (device == NULL || device->handle != NULL) { 84 if (device == NULL || device->handle != NULL) {
91 return IRECV_ERROR_NO_DEVICE; 85 return IRECV_ERROR_NO_DEVICE;
92 } 86 }
@@ -96,7 +90,7 @@ int irecv_close(irecv_device* device) {
96 return IRECV_SUCCESS; 90 return IRECV_SUCCESS;
97} 91}
98 92
99int irecv_exit(irecv_device* device) { 93int irecv_exit(irecv_device_t* device) {
100 if (device != NULL) { 94 if (device != NULL) {
101 if (device->handle != NULL) { 95 if (device->handle != NULL) {
102 libusb_close(device->handle); 96 libusb_close(device->handle);
@@ -115,12 +109,12 @@ int irecv_exit(irecv_device* device) {
115 return IRECV_SUCCESS; 109 return IRECV_SUCCESS;
116} 110}
117 111
118void irecv_set_debug(int level) { 112void irecv_set_debug(irecv_device_t* device, int level) {
119 printf("Debug has been set to %d\n", level); 113 libusb_set_debug(device->context, level);
120 irecv_debug = level; 114 device->debug = level;
121} 115}
122 116
123int irecv_send_command(irecv_device* device, const char* command) { 117int irecv_send_command(irecv_device_t* device, unsigned char* command) {
124 if(device == NULL || device->handle == NULL) { 118 if(device == NULL || device->handle == NULL) {
125 return IRECV_ERROR_NO_DEVICE; 119 return IRECV_ERROR_NO_DEVICE;
126 } 120 }
@@ -129,16 +123,23 @@ int irecv_send_command(irecv_device* device, const char* command) {
129 if(length >= 0x100) { 123 if(length >= 0x100) {
130 return IRECV_ERROR_INVALID_INPUT; 124 return IRECV_ERROR_INVALID_INPUT;
131 } 125 }
132 126
133 int ret = libusb_control_transfer(device->handle, 0x40, 0, 0, 0, (unsigned char*) command, length+1, 100); 127 if(device->send_callback != NULL) {
134 if(ret < 0) { 128 // Call our user defined callback first, this must return a number of bytes to send
135 return IRECV_ERROR_UNKNOWN; 129 // or zero to abort send.
130 length = device->send_callback(device, command, length);
131 if(length > 0) {
132 int ret = libusb_control_transfer(device->handle, 0x40, 0, 0, 0, (unsigned char*) command, length+1, 100);
133 if(ret < 0) {
134 return IRECV_ERROR_UNKNOWN;
135 }
136 }
136 } 137 }
137 138
138 return IRECV_SUCCESS; 139 return IRECV_SUCCESS;
139} 140}
140 141
141int irecv_send_file(irecv_device* device, const char* filename) { 142int irecv_send_file(irecv_device_t* device, const char* filename) {
142 FILE* file = fopen(filename, "rb"); 143 FILE* file = fopen(filename, "rb");
143 if (file == NULL) { 144 if (file == NULL) {
144 return IRECV_ERROR_FILE_NOT_FOUND; 145 return IRECV_ERROR_FILE_NOT_FOUND;
@@ -165,7 +166,7 @@ int irecv_send_file(irecv_device* device, const char* filename) {
165 return irecv_send_buffer(device, buffer, length); 166 return irecv_send_buffer(device, buffer, length);
166} 167}
167 168
168unsigned int irecv_get_status(irecv_device* device) { 169unsigned int irecv_get_status(irecv_device_t* device) {
169 unsigned char status[6]; 170 unsigned char status[6];
170 memset(status, '\0', 6); 171 memset(status, '\0', 6);
171 if(libusb_control_transfer(device->handle, 0xA1, 3, 0, 0, status, 6, 500) != 6) { 172 if(libusb_control_transfer(device->handle, 0xA1, 3, 0, 0, status, 6, 500) != 6) {
@@ -174,7 +175,7 @@ unsigned int irecv_get_status(irecv_device* device) {
174 return (unsigned int) status[4]; 175 return (unsigned int) status[4];
175} 176}
176 177
177int irecv_send_buffer(irecv_device* device, unsigned char* buffer, int length) { 178int irecv_send_buffer(irecv_device_t* device, unsigned char* buffer, int length) {
178 int last = length % 0x800; 179 int last = length % 0x800;
179 int packets = length / 0x800; 180 int packets = length / 0x800;
180 if (last != 0) { 181 if (last != 0) {
@@ -200,13 +201,26 @@ int irecv_send_buffer(irecv_device* device, unsigned char* buffer, int length) {
200 } 201 }
201 202
202 libusb_control_transfer(device->handle, 0x21, 1, i, 0, buffer, 0, 1000); 203 libusb_control_transfer(device->handle, 0x21, 1, i, 0, buffer, 0, 1000);
203 for (i = 6; i <= 8; i++) { 204 for (i = 0; i < 3; i++) {
204 if (irecv_get_status(device) != i) { 205 irecv_get_status(device);
205 free(buffer);
206 return IRECV_ERROR_USB_STATUS;
207 }
208 } 206 }
209 207
210 free(buffer); 208 free(buffer);
211 return IRECV_SUCCESS; 209 return IRECV_SUCCESS;
212} 210}
211
212void irecv_update(irecv_device_t* device) {
213 if(device->receive_callback == NULL) {
214 return;
215 }
216}
217
218int irecv_set_receiver(irecv_device_t* device, irecv_receive_callback callback) {
219 device->receive_callback = callback;
220 return IRECV_SUCCESS;
221}
222
223int irecv_set_sender(irecv_device_t* device, irecv_send_callback callback) {
224 device->send_callback = callback;
225 return IRECV_SUCCESS;
226}