/*
* dfu-suffix
*
* Copyright 2011-2012 Stefan Schmidt <stefan@datenfreihafen.org>
* Copyright 2013 Hans Petter Selasky <hps@bitfrost.no>
* Copyright 2014 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <getopt.h>
#include <string.h>
#include "portable.h"
#include "dfu_file.h"
enum mode {
MODE_NONE,
MODE_ADD,
MODE_DEL,
MODE_CHECK
};
int verbose;
static void help(void)
{
fprintf(stderr, "Usage: dfu-suffix [options] ...\n"
" -h --help\t\t\tPrint this help message\n"
" -V --version\t\t\tPrint the version number\n"
" -c --check <file>\t\tCheck DFU suffix of <file>\n"
" -a --add <file>\t\tAdd DFU suffix to <file>\n"
" -D --delete <file>\t\tDelete DFU suffix from <file>\n"
" -p --pid <productID>\t\tAdd product ID into DFU suffix in <file>\n"
" -v --vid <vendorID>\t\tAdd vendor ID into DFU suffix in <file>\n"
" -d --did <deviceID>\t\tAdd device ID into DFU suffix in <file>\n"
" -S --spec <specID>\t\tAdd DFU specification ID into DFU suffix in <file>\n"
);
exit(EX_USAGE);
}
static void print_version(void)
{
printf("dfu-suffix (%s) %s\n\n", PACKAGE, PACKAGE_VERSION);
printf("Copyright 2011-2012 Stefan Schmidt, 2013-2014 Tormod Volden\n"
"This program is Free Software and has ABSOLUTELY NO WARRANTY\n"
"Please report bugs to %s\n\n", PACKAGE_BUGREPORT);
}
static struct option opts[] = {
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'V' },
{ "check", 1, 0, 'c' },
{ "add", 1, 0, 'a' },
{ "delete", 1, 0, 'D' },
{ "pid", 1, 0, 'p' },
{ "vid", 1, 0, 'v' },
{ "did", 1, 0, 'd' },
{ "spec", 1, 0, 'S' },
};
int main(int argc, char **argv)
{
struct dfu_file file;
int pid, vid, did, spec;
enum mode mode = MODE_NONE;
/* make sure all prints are flushed */
setvbuf(stdout, NULL, _IONBF, 0);
print_version();
pid = vid = did = 0xffff;
spec = 0x0100; /* Default to bcdDFU version 1.0 */
memset(&file, 0, sizeof(file));
while (1) {
int c, option_index = 0;
c = getopt_long(argc, argv, "hVc:a:D:p:v:d:S:s:T", opts,
&option_index);
if (c == -1)
break;
switch (c) {
case 'h':
help();
break;
case 'V':
exit(0);
break;
case 'D':
file.name = optarg;
mode = MODE_DEL;
break;
case 'p':
pid = strtol(optarg, NULL, 16);
break;
case 'v':
vid = strtol(optarg, NULL, 16);
break;
case 'd':
did = strtol(optarg, NULL, 16);
break;
case 'S':
spec = strtol(optarg, NULL, 16);
break;
case 'c':
file.name = optarg;
mode = MODE_CHECK;
break;
case 'a':
file.name = optarg;
mode = MODE_ADD;
break;
default:
help();
break;
}
}
if (!file.name) {
fprintf(stderr, "You need to specify a filename\n");
help();
}
if (spec != 0x0100 && spec != 0x011a) {
fprintf(stderr, "Only DFU specification 0x0100 and 0x011a supported\n");
help();
}
switch(mode) {
case MODE_ADD:
dfu_load_file(&file, NO_SUFFIX, MAYBE_PREFIX);
file.idVendor = vid;
file.idProduct = pid;
file.bcdDevice = did;
file.bcdDFU = spec;
/* always write suffix, rewrite prefix if there was one */
dfu_store_file(&file, 1, file.size.prefix != 0);
printf("Suffix successfully added to file\n");
break;
case MODE_CHECK:
dfu_load_file(&file, NEEDS_SUFFIX, MAYBE_PREFIX);
show_suffix_and_prefix(&file);
break;
case MODE_DEL:
dfu_load_file(&file, NEEDS_SUFFIX, MAYBE_PREFIX);
dfu_store_file(&file, 0, file.size.prefix != 0);
if (file.size.suffix) /* had a suffix */
printf("Suffix successfully removed from file\n");
break;
default:
help();
break;
}
return (0);
}