summaryrefslogtreecommitdiffstats
path: root/src/libirecovery.c
diff options
context:
space:
mode:
authorGravatar Joshua Hill2010-05-17 18:40:58 -0400
committerGravatar Joshua Hill2010-05-17 18:40:58 -0400
commitcf12a431935f814b6f0b98fe43915c48fde2fcf0 (patch)
tree8b2b2acdbbec86fecf7cc1901282bb8d6ae3a18d /src/libirecovery.c
parent34fc43b128e475fda4e9834689e3649eba82c4c9 (diff)
downloadlibirecovery-cf12a431935f814b6f0b98fe43915c48fde2fcf0.tar.gz
libirecovery-cf12a431935f814b6f0b98fe43915c48fde2fcf0.tar.bz2
Implemented irecv_getenv() and added a number of bug fixes
Diffstat (limited to 'src/libirecovery.c')
-rw-r--r--src/libirecovery.c79
1 files changed, 59 insertions, 20 deletions
diff --git a/src/libirecovery.c b/src/libirecovery.c
index bcea61c..b8eb224 100644
--- a/src/libirecovery.c
+++ b/src/libirecovery.c
@@ -52,8 +52,8 @@ irecv_device_t* irecv_init() {
52 } 52 }
53 memset(device, '\0', sizeof(irecv_device_t)); 53 memset(device, '\0', sizeof(irecv_device_t));
54 54
55 irecv_set_receiver(device, &irecv_default_receiver); 55 //irecv_set_receiver(device, &irecv_default_receiver);
56 irecv_set_sender(device, &irecv_default_sender); 56 //irecv_set_sender(device, &irecv_default_sender);
57 device->context = usb_context; 57 device->context = usb_context;
58 return device; 58 return device;
59} 59}
@@ -124,15 +124,13 @@ irecv_error_t irecv_set_interface(irecv_device_t* device, int interface, int alt
124 if(device == NULL || device->handle == NULL) { 124 if(device == NULL || device->handle == NULL) {
125 return IRECV_ERROR_NO_DEVICE; 125 return IRECV_ERROR_NO_DEVICE;
126 } 126 }
127 127
128 if (libusb_claim_interface(device->handle, interface) < 0) { 128 if (libusb_claim_interface(device->handle, interface) < 0) {
129 return IRECV_ERROR_USB_INTERFACE; 129 return IRECV_ERROR_USB_INTERFACE;
130 } 130 }
131 131
132 if(alt_interface > 0) { 132 if(libusb_set_interface_alt_setting(device->handle, interface, alt_interface) < 0) {
133 if(libusb_set_interface_alt_setting(device->handle, interface, alt_interface) < 0) { 133 return IRECV_ERROR_USB_INTERFACE;
134 return IRECV_ERROR_USB_INTERFACE;
135 }
136 } 134 }
137 135
138 device->interface = interface; 136 device->interface = interface;
@@ -192,7 +190,7 @@ irecv_error_t irecv_set_debug(irecv_device_t* device, int level) {
192 return IRECV_SUCCESS; 190 return IRECV_SUCCESS;
193} 191}
194 192
195irecv_error_t irecv_send_command(irecv_device_t* device, unsigned char* command) { 193irecv_error_t irecv_send(irecv_device_t* device, unsigned char* command) {
196 if(device == NULL || device->handle == NULL) { 194 if(device == NULL || device->handle == NULL) {
197 return IRECV_ERROR_NO_DEVICE; 195 return IRECV_ERROR_NO_DEVICE;
198 } 196 }
@@ -209,6 +207,23 @@ irecv_error_t irecv_send_command(irecv_device_t* device, unsigned char* command)
209 } 207 }
210 208
211 if(length > 0) { 209 if(length > 0) {
210 irecv_send_command(device, command);
211 }
212
213 return IRECV_SUCCESS;
214}
215
216irecv_error_t irecv_send_command(irecv_device_t* device, unsigned char* command) {
217 if(device == NULL || device->handle == NULL) {
218 return IRECV_ERROR_NO_DEVICE;
219 }
220
221 unsigned int length = strlen(command);
222 if(length >= 0x100) {
223 length = 0xFF;
224 }
225
226 if(length > 0) {
212 libusb_control_transfer(device->handle, 0x40, 0, 0, 0, command, length+1, 100); 227 libusb_control_transfer(device->handle, 0x40, 0, 0, 0, command, length+1, 100);
213 } 228 }
214 229
@@ -243,7 +258,9 @@ irecv_error_t irecv_send_file(irecv_device_t* device, const char* filename) {
243 return IRECV_ERROR_UNKNOWN; 258 return IRECV_ERROR_UNKNOWN;
244 } 259 }
245 260
246 return irecv_send_buffer(device, buffer, length); 261 irecv_error_t error = irecv_send_buffer(device, buffer, length);
262 free(buffer);
263 return error;
247} 264}
248 265
249irecv_error_t irecv_get_status(irecv_device_t* device, unsigned int* status) { 266irecv_error_t irecv_get_status(irecv_device_t* device, unsigned int* status) {
@@ -254,11 +271,12 @@ irecv_error_t irecv_get_status(irecv_device_t* device, unsigned int* status) {
254 271
255 unsigned char buffer[6]; 272 unsigned char buffer[6];
256 memset(buffer, '\0', 6); 273 memset(buffer, '\0', 6);
257 if(libusb_control_transfer(device->handle, 0xA1, 3, 0, 0, buffer, 6, 500) != 6) { 274 if(libusb_control_transfer(device->handle, 0xA1, 3, 0, 0, buffer, 6, 1000) != 6) {
258 *status = 0; 275 *status = 0;
259 return IRECV_ERROR_USB_STATUS; 276 return IRECV_ERROR_USB_STATUS;
260 } 277 }
261 278
279 debug("status: %d\n", (unsigned int) buffer[4]);
262 *status = (unsigned int) buffer[4]; 280 *status = (unsigned int) buffer[4];
263 return IRECV_SUCCESS; 281 return IRECV_SUCCESS;
264} 282}
@@ -268,46 +286,52 @@ irecv_error_t irecv_send_buffer(irecv_device_t* device, unsigned char* buffer, u
268 if(device == NULL || device->handle == NULL) { 286 if(device == NULL || device->handle == NULL) {
269 return IRECV_ERROR_NO_DEVICE; 287 return IRECV_ERROR_NO_DEVICE;
270 } 288 }
271 289
272 int last = length % 0x800; 290 int last = length % 0x800;
273 int packets = length / 0x800; 291 int packets = length / 0x800;
274 if (last != 0) { 292 if (last != 0) {
275 packets++; 293 packets++;
276 } else {
277 last = 0x800;
278 } 294 }
279 295
280 int i = 0; 296 int i = 0;
281 unsigned int status = 0; 297 unsigned int status = 0;
282 for (i = 0; i < packets; i++) { 298 for (i = 0; i < packets; i++) {
283 int size = i + 1 < packets ? 0x800 : last; 299 int size = i + 1 < packets ? 0x800 : last;
284 int bytes = libusb_control_transfer(device->handle, 0x21, 1, i, 0, &buffer[i * 0x800], size, 500); 300 int bytes = libusb_control_transfer(device->handle, 0x21, 1, i, 0, &buffer[i * 0x800], size, 1000);
285 if (bytes != size) { 301 if (bytes != size) {
286 free(buffer);
287 return IRECV_ERROR_USB_UPLOAD; 302 return IRECV_ERROR_USB_UPLOAD;
288 } 303 }
289 304
305 debug("Sent %d bytes\n", bytes);
306
290 error = irecv_get_status(device, &status); 307 error = irecv_get_status(device, &status);
291 if (error != IRECV_SUCCESS || status != 5) { 308 if (error != IRECV_SUCCESS) {
292 free(buffer);
293 return error; 309 return error;
294 } 310 }
311
312 if(status != 5) {
313 return IRECV_ERROR_USB_STATUS;
314 }
315
295 } 316 }
296 317
318 //char command[0x100];
319 //memset(command, '\0', 0x100);
320 //snprintf(command, 0x100, "setenv filesize %d", length);
297 libusb_control_transfer(device->handle, 0x21, 1, i, 0, buffer, 0, 1000); 321 libusb_control_transfer(device->handle, 0x21, 1, i, 0, buffer, 0, 1000);
298 for (i = 0; i < 3; i++) { 322 for (i = 0; i < 3; i++) {
299 error = irecv_get_status(device, &status); 323 error = irecv_get_status(device, &status);
300 if(error != IRECV_SUCCESS) { 324 if(error != IRECV_SUCCESS) {
301 free(buffer);
302 return error; 325 return error;
303 } 326 }
304 } 327 }
305 328
306 free(buffer); 329 //irecv_send_command(device, command);
330
307 return IRECV_SUCCESS; 331 return IRECV_SUCCESS;
308} 332}
309 333
310irecv_error_t irecv_update(irecv_device_t* device) { 334irecv_error_t irecv_receive(irecv_device_t* device) {
311 unsigned char buffer[BUFFER_SIZE]; 335 unsigned char buffer[BUFFER_SIZE];
312 memset(buffer, '\0', BUFFER_SIZE); 336 memset(buffer, '\0', BUFFER_SIZE);
313 if(device == NULL || device->handle == NULL) { 337 if(device == NULL || device->handle == NULL) {
@@ -358,6 +382,21 @@ irecv_error_t irecv_set_sender(irecv_device_t* device, irecv_send_callback callb
358 return IRECV_SUCCESS; 382 return IRECV_SUCCESS;
359} 383}
360 384
385irecv_error_t irecv_getenv(irecv_device_t* device, unsigned char** var) {
386 unsigned char* value = (unsigned char*) malloc(0x200);
387 if(value == NULL) {
388 return IRECV_ERROR_OUT_OF_MEMORY;
389 }
390
391 int ret = libusb_control_transfer(device->handle, 0xC0, 0, 0, 0, value, 0x200, 500);
392 if(ret < 0) {
393 return IRECV_ERROR_UNKNOWN;
394 }
395
396 *var = value;
397 return IRECV_SUCCESS;
398}
399
361const char* irecv_strerror(irecv_error_t error) { 400const char* irecv_strerror(irecv_error_t error) {
362 switch(error) { 401 switch(error) {
363 case IRECV_SUCCESS: 402 case IRECV_SUCCESS: