diff options
Diffstat (limited to 'src/dfu_load.c')
-rw-r--r-- | src/dfu_load.c | 84 |
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; } |