/* * dfu-suffix * * Copyright 2011-2012 Stefan Schmidt * Copyright 2013 Hans Petter Selasky * Copyright 2014 Tormod Volden * * 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 #include #include #include #include #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 \t\tCheck DFU suffix of \n" " -a --add \t\tAdd DFU suffix to \n" " -D --delete \t\tDelete DFU suffix from \n" " -p --pid \t\tAdd product ID into DFU suffix in \n" " -v --vid \t\tAdd vendor ID into DFU suffix in \n" " -d --did \t\tAdd device ID into DFU suffix in \n" " -S --spec \t\tAdd DFU specification ID into DFU suffix in \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); }