summaryrefslogtreecommitdiff
path: root/src/dfu_load.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dfu_load.c')
-rw-r--r--src/dfu_load.c84
1 files changed, 53 insertions, 31 deletions
diff --git a/src/dfu_load.c b/src/dfu_load.c
index 64f7009..a461614 100644
--- a/src/dfu_load.c
+++ b/src/dfu_load.c
@@ -9,7 +9,7 @@
*
* Copyright 2007-2008 Harald Welte <laforge@gnumonks.org>
* Copyright 2013 Hans Petter Selasky <hps@bitfrost.no>
- * Copyright 2014 Tormod Volden <debian.tormod@gmail.com>
+ * Copyright 2014-2016 Tormod Volden <debian.tormod@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,6 +26,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#define __USE_MINGW_ANSI_STDIO 1
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -43,7 +48,7 @@
int dfuload_do_upload(struct dfu_if *dif, int xfer_size,
int expected_size, int fd)
{
- int total_bytes = 0;
+ off_t total_bytes = 0;
unsigned short transaction = 0;
unsigned char *buf;
int ret;
@@ -51,49 +56,52 @@ int dfuload_do_upload(struct dfu_if *dif, int xfer_size,
buf = dfu_malloc(xfer_size);
printf("Copying data from DFU device to PC\n");
- dfu_progress_bar("Upload", 0, 1);
while (1) {
int rc;
+ dfu_progress_bar("Upload", total_bytes, expected_size);
rc = dfu_upload(dif->dev_handle, dif->interface,
- xfer_size, transaction++, buf);
+ xfer_size, transaction++, buf);
if (rc < 0) {
- warnx("Error during upload");
+ warnx("\nError during upload (%s)",
+ libusb_error_name(rc));
ret = rc;
- goto out_free;
+ break;
}
dfu_file_write_crc(fd, 0, buf, rc);
total_bytes += rc;
if (total_bytes < 0)
- errx(EX_SOFTWARE, "Received too many bytes (wraparound)");
+ errx(EX_SOFTWARE, "\nReceived too many bytes (wraparound)");
if (rc < xfer_size) {
/* last block, return */
- ret = total_bytes;
+ ret = 0;
break;
}
+ }
+ free(buf);
+ if (ret == 0) {
+ dfu_progress_bar("Upload", total_bytes, total_bytes);
+ } else {
dfu_progress_bar("Upload", total_bytes, expected_size);
+ printf("\n");
}
- ret = 0;
-
-out_free:
- dfu_progress_bar("Upload", total_bytes, total_bytes);
if (total_bytes == 0)
printf("\nFailed.\n");
- free(buf);
- if (verbose)
- printf("Received a total of %i bytes\n", total_bytes);
+ else
+ printf("Received a total of %lli bytes\n", (long long) total_bytes);
+
if (expected_size != 0 && total_bytes != expected_size)
- errx(EX_SOFTWARE, "Unexpected number of bytes uploaded from device");
+ warnx("Unexpected number of bytes uploaded from device");
return ret;
}
int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file)
{
- int bytes_sent;
- int expected_size;
+ off_t bytes_sent;
+ off_t expected_size;
unsigned char *buf;
unsigned short transaction = 0;
struct dfu_status dst;
@@ -107,19 +115,20 @@ int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file)
dfu_progress_bar("Download", 0, 1);
while (bytes_sent < expected_size) {
- int bytes_left;
+ off_t bytes_left;
int chunk_size;
bytes_left = expected_size - bytes_sent;
if (bytes_left < xfer_size)
- chunk_size = bytes_left;
+ chunk_size = (int) bytes_left;
else
chunk_size = xfer_size;
ret = dfu_download(dif->dev_handle, dif->interface,
- chunk_size, transaction++, chunk_size ? buf : NULL);
+ chunk_size, transaction++, chunk_size ? buf : NULL);
if (ret < 0) {
- warnx("Error during download");
+ warnx("Error during download (%s)",
+ libusb_error_name(ret));
goto out;
}
bytes_sent += chunk_size;
@@ -128,7 +137,8 @@ int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file)
do {
ret = dfu_get_status(dif, &dst);
if (ret < 0) {
- errx(EX_IOERR, "Error during download get_status");
+ errx(EX_IOERR, "Error during download get_status (%s)",
+ libusb_error_name(ret));
goto out;
}
@@ -138,11 +148,14 @@ int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file)
/* Wait while device executes flashing */
milli_sleep(dst.bwPollTimeout);
+ if (verbose > 1)
+ fprintf(stderr, "Poll timeout %i ms\n", dst.bwPollTimeout);
} while (1);
+
if (dst.bStatus != DFU_STATUS_OK) {
printf(" failed!\n");
- printf("state(%u) = %s, status(%u) = %s\n", dst.bState,
+ printf("DFU state(%u) = %s, status(%u) = %s\n", dst.bState,
dfu_state_to_string(dst.bState), dst.bStatus,
dfu_status_to_string(dst.bStatus));
ret = -1;
@@ -152,26 +165,27 @@ int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file)
}
/* send one zero sized download request to signalize end */
- ret = dfu_download(dif->dev_handle, dif->interface,
- 0, transaction, NULL);
+ ret = dfu_download(dif->dev_handle, dif->interface, 0, transaction, NULL);
if (ret < 0) {
- errx(EX_IOERR, "Error sending completion packet");
+ errx(EX_IOERR, "Error sending completion packet (%s)",
+ libusb_error_name(ret));
goto out;
}
dfu_progress_bar("Download", bytes_sent, bytes_sent);
if (verbose)
- printf("Sent a total of %i bytes\n", bytes_sent);
+ printf("Sent a total of %lli bytes\n", (long long) bytes_sent);
get_status:
/* Transition to MANIFEST_SYNC state */
ret = dfu_get_status(dif, &dst);
if (ret < 0) {
- warnx("unable to read DFU status after completion");
+ warnx("unable to read DFU status after completion (%s)",
+ libusb_error_name(ret));
goto out;
}
- printf("state(%u) = %s, status(%u) = %s\n", dst.bState,
+ printf("DFU state(%u) = %s, status(%u) = %s\n", dst.bState,
dfu_state_to_string(dst.bState), dst.bStatus,
dfu_status_to_string(dst.bStatus));
@@ -186,11 +200,19 @@ get_status:
milli_sleep(1000);
goto get_status;
break;
+ case DFU_STATE_dfuMANIFEST_WAIT_RST:
+ printf("Resetting USB to switch back to runtime mode\n");
+ ret = libusb_reset_device(dif->dev_handle);
+ if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND) {
+ fprintf(stderr, "error resetting after download (%s)\n",
+ libusb_error_name(ret));
+ }
+ break;
case DFU_STATE_dfuIDLE:
break;
}
printf("Done!\n");
out:
- return bytes_sent;
+ return ret;
}