Move functions within main.c to new dfu_util.c/.h

Signed-off-by: Roger Meier <r.meier@siemens.com>
Add CFLAG -Wextra and lot of type casts

Signed-off-by: Roger Meier <r.meier@siemens.com>
Use nanosleep instead of usleep for delays

After downloading the dfu-util 0.7 binary distribution for Windows
(MinGW), I noticed that the milli_sleep(2000) delay after a detach was
not delaying at all. Grabbing the source, and doing some debugging, I
found that MinGW now provides a usleep() implementation (HAVE_USLEEP
gets defined by configure script), but it will just return immediately
if the specified delay is 1000000 or greater. According to the usleep
man page, operation is only defined in the range [0, 1000000], with
behaviour outside of this range being undefined, so TECHNICALLY it's not
a bug.

Anyways, my "quick hack" was to just swap the order of the HAVE_USLEEP
and HAVE_WINDOWS_H checks in src/portable.h so Windows uses Sleep.  But
then I figured other platforms may have similarly restricted usleep
implementations, and the "correct" fix would be to use nanosleep for
delays instead.  Hence, this patch.

Note that MinGW doesn't currently have nanosleep, so Windows will still
fall back to using Sleep, but I've also tested this under Ubuntu 11 to
confirm the nanosleep implementation works.

The "do {...} while (0)" loop is used to "swallow the semicolon", see
http://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html
Revise help messages

Signed-off-by: Roger Meier <r.meier@siemens.com>
Seek to end of file before checking length when opening upload file

Unlike Linux, under Windows, the position returned by ftell() immediately
after opening a file for append is 0, regardless of the file size. A bug
was raised in MinGW because of this difference:

http://sourceforge.net/p/mingw/bugs/1558/

But it was closed as "won't fix" because Microsoft documents its ftell()
behaviour here:

http://msdn.microsoft.com/en-us/library/0ys3hc0b

Specifically, note this paragraph:

"Note that when a file is opened for appending data, the current file
position is determined by the last I/O operation, not by where the next
write would occur. For example, if a file is opened for an append and the
last operation was a read, the file position is the point where the next
read operation would start, not where the next write would start. (When a
file is opened for appending, the file position is moved to end of file
before any write operation.) If no I/O operation has yet occurred on a
file opened for appending, the file position is the beginning of the
file."

As such, to properly determine the pre-existing length of a file opened
for append under Windows, we must first perform a seek to the end of the
file.  Hence this change to add an fseek() call when checking the length
of the output file for an upload operation.
Report the serial number of the devices found
Allow to select device by serial number
www: Mention MacPorts and merge Releases/Binaries sections

Thanks to Benoit Triquet for adding dfu-util to MacPorts!
Add new option to configure detach delay

Under Windows, re-enumerating a USB device after DFU detach can take
several seconds, resulting in "losing" the device with the current 2
second delay.  To allow users to customize this delay as their
requirements dictate, a new -E (--detach-delay) option has been added
to dfu-util, specifying the delay in seconds.

Under Windows ONLY, the default for this detach delay is now 5 seconds,
while it is left at 2 seconds for all other platforms.
Report bcdDevice for found DFU devices

To provide additional information to users about their DFU device(s), the
bcdDevice field is now displayed as part of the DFU device information.
This field is used to specify the firmware version of the device, and the
DFU suffix contains a matching field which can be used for performing
version checking.

In addition, the print_dfu_if() function is now used to display device
information when first opening the DFU capable device, for consistency
with other locations where device information is displayed (and because
it is more important to know the bcdDevice version at this time, rather
than after having switched into DFU mode).
Fix crash on listing DFU interfaces

The recent change in 78d8efe to add serial number display introduced a
bug where the DFU list operation would crash if a DFU capable device was
found which had a serial number, but no alternate interface name string.
This is because the code to open the USB device, if it had not
previously been opened, was only done in the get_alt_name() function,
when an alternate interface name string is present, and not in the
get_serial() function.

Both get_alt_name() and get_serial() have been modified to open the USB
device, if necessary, and close it afterwards if it was not open when the
function was called.  In addition, the dev_handle structure element is now
being set to NULL after each close to avoid potential use of a bad handle.
dfuse: Remove extraneous status request on DFU_LEAVE

An additional dfu_get_status() was hitting on the device after it was
run off to manifestation state, and would always fail with an error
message.

Thanks to Christopher Head for pointing out this.

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
main: dfuError state means DFU mode

If the device reports the dfuError state it must already be in
DFU mode and we do not need to detach.

Also remove non-necessary break after exit().

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
DFU mode vendor, product, and serial specification

The "-d" option has been expanded to allow separate specification of the
vendor and product IDs for a device in DFU mode.  This enhancement was
done in a backwards compatible fashion such that anyone using the previous
"-d" functionality should see identical matching behaviour (i.e. same
vendor and product ID expected in both run-time and DFU mode).  To specify
DFU mode vendor and product IDs, add a comma to the end of the run-time
vendor and product ID specifier, followed by the DFU mode vendor and
product ID.  For example, "-d 1111:2222,3333:4444" will match only a
run-time device with vendor ID 0x1111 and product ID 0x2222, OR a DFU mode
device with vendor ID 0x3333 and product ID 0x4444.  Leaving any component
blank will match any device for that field (e.g. "-d 1111:,:4444" will
match a run-time device with vendor ID 0x1111 and ANY product ID, OR a DFU
mode device with ANY vendor ID but the product ID must be 0x4444).

The "-S" option has been expanded to allow separate specification of the
serial number for a device in DFU mode.  A DFU mode serial number is
specified by adding a comma following the run-time serial number, followed
by the DFU mode serial number.  If no comma is found in the argument then
the same serial number will be expected in both run-time and DFU mode.  If
a comma is present but no serial number is specified after the comma, then
any serial number is permitted for a device in DFU mode.  Note that comma
is not a valid character in a USB serial number, so this parsing shouldn't
conflict with the ability to specify any valid serial number.
Do not bail if GET_STATUS is not supported in appIDLE state

According to both versions of DFU specification(v. 1.1 and 1.0) it is
optional for a DFU compatible device to implement GET_STATUS request
in appIDLE state, which means that current behaviour of dfu-util,
namely to bail out if GET_STATUS request fails, is incompatible with
devices that do not implement aforementioned request in appIDLE state.
This commit adds the support of such devices by making assumption that
device is in appIDLE state if GET_STATUS returns -EPIPE and proceeding
to send DFU_DETACH request.

[Bradley Scott]
- remove old extraneous space in dfu_get_status() call
- initialize all fields of status structure
- only report state and status if it was retrieved successfully

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Reviewed-by: Bradley Scott <Bradley.Scott@confuseacat.org>
Tested-by: Bradley Scott <Bradley.Scott@confuseacat.org>
Signed-off-by: Bradley Scott <Bradley.Scott@confuseacat.org>
Use AC_CONFIG_HEADERS instead of AM_CONFIG_HEADER

AM_CONFIG_HEADER has been deprecated for years and has been removed from
autotools 1.13.
dfuse: Explicit set the dfuse_address when leaving

Otherwise the dfuse leave request will jump to the wrong place
as soon as the download is longer than one DFU transfer.
dfuse: Verbose decode failing special commands
dfuse_mem: Device Feature is not erasable, despite tagged as 'g' on STM32F407

[Tormod]
Move free() so we do not reference the free'd string.
Add quirk for transfer size 64 on M-Audio Sonic device

Thanks to Raf D for reporting the needed transfer size.

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>