/*
* dfu-prefix
*
* Copyright 2011-2012 Stefan Schmidt <stefan@datenfreihafen.org>
* Copyright 2013 Hans Petter Selasky <hps@bitfrost.no>
* Copyright 2014 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
*
* 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-prefix [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 prefix of <file>\n"
" -D --delete <file>\t\tDelete DFU prefix from <file>\n"
" -a --add <file>\t\tAdd DFU prefix to <file>\n"
"In combination with -a:\n"
);
fprintf(stderr, " -s --stellaris-address <address> Add TI Stellaris address prefix to <file>\n"
"In combination with -D or -c:\n"
" -T --stellaris\t\tAct on TI Stellaris address prefix of <file>\n"
"In combination with -a or -D or -c:\n"
" -L --lpc-prefix\t\tUse NXP LPC DFU prefix format\n"
);
exit(EX_USAGE);
}
static void print_version(void)
{
printf("dfu-prefix (%s) %s\n\n", PACKAGE, PACKAGE_VERSION);
printf("Copyright 2011-2012 Stefan Schmidt, 2014 Uwe Bonnes\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' },
{ "stellaris-address", 1, 0, 's' },
{ "stellaris", 0, 0, 'T' },
{ "LPC", 0, 0, 'L' },
};
int main(int argc, char **argv)
{
struct dfu_file file;
enum mode mode = MODE_NONE;
enum prefix_type type = ZERO_PREFIX;
uint32_t lmdfu_flash_address = 0;
char *end;
/* make sure all prints are flushed */
setvbuf(stdout, NULL, _IONBF, 0);
print_version();
memset(&file, 0, sizeof(file));
while (1) {
int c, option_index = 0;
c = getopt_long(argc, argv, "hVc:a:D:p:v:d:s:TL", 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 'c':
file.name = optarg;
mode = MODE_CHECK;
break;
case 'a':
file.name = optarg;
mode = MODE_ADD;
break;
case 's':
lmdfu_flash_address = strtoul(optarg, &end, 0);
if (*end) {
errx(EX_IOERR, "Invalid lmdfu "
"address: %s", optarg);
}
/* fall-through */
case 'T':
type = LMDFU_PREFIX;
break;
case 'L':
type = LPCDFU_UNENCRYPTED_PREFIX;
break;
default:
help();
break;
}
}
if (!file.name) {
fprintf(stderr, "You need to specify a filename\n");
help();
}
switch(mode) {
case MODE_ADD:
if (type == ZERO_PREFIX)
errx(EX_IOERR, "Prefix type must be specified");
dfu_load_file(&file, MAYBE_SUFFIX, NO_PREFIX);
file.lmdfu_address = lmdfu_flash_address;
file.prefix_type = type;
printf("Adding prefix to file\n");
dfu_store_file(&file, file.size.suffix != 0, 1);
break;
case MODE_CHECK:
dfu_load_file(&file, MAYBE_SUFFIX, MAYBE_PREFIX);
show_suffix_and_prefix(&file);
if (type > ZERO_PREFIX && file.prefix_type != type)
errx(EX_IOERR, "No prefix of requested type");
break;
case MODE_DEL:
dfu_load_file(&file, MAYBE_SUFFIX, NEEDS_PREFIX);
if (type > ZERO_PREFIX && file.prefix_type != type)
errx(EX_IOERR, "No prefix of requested type");
printf("Removing prefix from file\n");
/* if there was a suffix, rewrite it */
dfu_store_file(&file, file.size.suffix != 0, 0);
break;
default:
help();
break;
}
return (0);
}