summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libirecovery.h1
-rw-r--r--src/libirecovery.c49
2 files changed, 50 insertions, 0 deletions
diff --git a/include/libirecovery.h b/include/libirecovery.h
index 20ecfc7..0a99405 100644
--- a/include/libirecovery.h
+++ b/include/libirecovery.h
@@ -69,6 +69,7 @@ struct irecv_client {
69 unsigned short mode; 69 unsigned short mode;
70 libusb_context* context; 70 libusb_context* context;
71 libusb_device_handle* handle; 71 libusb_device_handle* handle;
72 irecv_event_cb_t progress_callback;
72 irecv_event_cb_t received_callback; 73 irecv_event_cb_t received_callback;
73 irecv_event_cb_t precommand_callback; 74 irecv_event_cb_t precommand_callback;
74 irecv_event_cb_t postcommand_callback; 75 irecv_event_cb_t postcommand_callback;
diff --git a/src/libirecovery.c b/src/libirecovery.c
index 1303fc5..acf1d6b 100644
--- a/src/libirecovery.c
+++ b/src/libirecovery.c
@@ -27,6 +27,8 @@
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
30void irecv_print_progress(const char* operation, float progress);
31
30irecv_error_t irecv_open(irecv_client_t* pclient) { 32irecv_error_t irecv_open(irecv_client_t* pclient) {
31 int i = 0; 33 int i = 0;
32 char serial[256]; 34 char serial[256];
@@ -158,6 +160,9 @@ irecv_error_t irecv_event_subscribe(irecv_client_t client, irecv_event_type type
158 client->postcommand_callback = callback; 160 client->postcommand_callback = callback;
159 break; 161 break;
160 162
163 case IRECV_PROGRESS:
164 client->progress_callback = callback;
165
161 default: 166 default:
162 return IRECV_E_UNKNOWN_ERROR; 167 return IRECV_E_UNKNOWN_ERROR;
163 } 168 }
@@ -179,6 +184,9 @@ irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type ty
179 client->postcommand_callback = NULL; 184 client->postcommand_callback = NULL;
180 break; 185 break;
181 186
187 case IRECV_PROGRESS:
188 client->progress_callback = NULL;
189
182 default: 190 default:
183 return IRECV_E_UNKNOWN_ERROR; 191 return IRECV_E_UNKNOWN_ERROR;
184 } 192 }
@@ -316,6 +324,8 @@ irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, un
316 } 324 }
317 325
318 int i = 0; 326 int i = 0;
327 double count = 0;
328 double progress = 0;
319 unsigned int status = 0; 329 unsigned int status = 0;
320 for (i = 0; i < packets; i++) { 330 for (i = 0; i < packets; i++) {
321 int size = i + 1 < packets ? 0x800 : last; 331 int size = i + 1 < packets ? 0x800 : last;
@@ -336,6 +346,18 @@ irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, un
336 return IRECV_E_USB_UPLOAD; 346 return IRECV_E_USB_UPLOAD;
337 } 347 }
338 348
349 count += size;
350 if(client->progress_callback != NULL) {
351 irecv_event_t event;
352 event.type = IRECV_PROGRESS;
353 event.data = NULL;
354 event.size = count/length;
355 client->progress_callback(client, &event);
356 }
357 else if((count / (double) length) * 100.0 > progress) {
358 progress = (count / (double) length) * 100.0;
359 irecv_print_progress("Uploading", progress);
360 }
339 } 361 }
340 362
341 libusb_control_transfer(client->handle, 0x21, 1, 0, 0, buffer, 0, 1000); 363 libusb_control_transfer(client->handle, 0x21, 1, 0, 0, buffer, 0, 1000);
@@ -503,3 +525,30 @@ const char* irecv_strerror(irecv_error_t error) {
503 525
504 return NULL; 526 return NULL;
505} 527}
528
529void irecv_print_progress(const char* operation, float progress) {
530 int i = 0;
531 if(progress < 0) {
532 return;
533 }
534
535 if(progress > 100) {
536 progress = 100;
537 }
538
539 printf("\r%s [", operation);
540 for(i = 0; i < 50; i++) {
541 if(i < progress / 2) {
542 printf("=");
543 } else {
544 printf(" ");
545 }
546 }
547
548 printf("] %3.1f%%", progress);
549 fflush(stdout);
550 if(progress == 100) {
551 printf("\n");
552 }
553
554}