@@ -5,6 +5,10 @@ | |||
#include "linebuffer.h" | |||
#include "list.h" | |||
#define FLAG_CONFIG 0x01 | |||
#define FLAG_FIRMWARE 0x02 | |||
#define FLAG_SPEEDUP 0x04 | |||
struct context { | |||
struct list_head list; | |||
@@ -20,6 +24,7 @@ struct context { | |||
/* statemachine */ | |||
int state; | |||
int flags; | |||
/* line buffer */ | |||
struct linebuffer *lbuf; |
@@ -75,13 +75,18 @@ int statemachine_read(int fd, void *privdata) | |||
/* debug mode entered */ | |||
} else if (msg == MSG_DEBUG) { | |||
/* if device supports it, switch to high baudrate */ | |||
if (ctx->dev_setbaudrate != NULL) { | |||
if ((ctx->flags & FLAG_SPEEDUP) && ctx->dev_setbaudrate != NULL) { | |||
ctx->state = STATE_SWITCH_BAUDRATE; | |||
write(fd, "ATBA5\r\n", 7); | |||
} else { | |||
ctx->state = STATE_XMODEM; | |||
write(fd, "ATLC\r\n", 6); | |||
if (ctx->flags & FLAG_CONFIG) | |||
write(fd, "ATLC\r\n", 6); | |||
else if (ctx->flags & FLAG_FIRMWARE) | |||
write(fd, "ATUR\r\n", 6); | |||
} | |||
/* follow device to high baudrate */ | |||
@@ -90,7 +95,12 @@ int statemachine_read(int fd, void *privdata) | |||
linebuffer_clear(ctx->lbuf); | |||
ctx->state = STATE_XMODEM; | |||
write(fd, "ATLC\r\n", 6); | |||
if (ctx->flags & FLAG_CONFIG) | |||
write(fd, "ATLC\r\n", 6); | |||
else if (ctx->flags & FLAG_FIRMWARE) | |||
write(fd, "ATUR\r\n", 6); | |||
/* transfer was success */ | |||
} else if (msg == MSG_XMODEM_OK && ctx->state == STATE_XMODEM_COMPLETE) { |
@@ -62,12 +62,12 @@ int xmodem_read(int fd, void *privdata) | |||
switch (pkt.header) { | |||
case XM_C: /* first packet */ | |||
log_print(LOG_DEBUG, "%s: XMODEM started", ctx->devname); | |||
log_print(LOG_DEBUG, "%s: XMODEM started (%d bytes)", ctx->devname, ctx->file->size); | |||
pktnum = 0; | |||
break; | |||
case XM_ACK: /* next packet */ | |||
if (ctx->lastpkt * 128 == ctx->file->size) | |||
if (ctx->lastpkt * 128 >= ctx->file->size) | |||
return -1; | |||
pktnum = ctx->lastpkt +1; |
@@ -10,31 +10,41 @@ | |||
#include "serial.h" | |||
static struct option opts[] = { | |||
{"config", 1, 0, 'c'}, | |||
{"device", 1, 0, 'd'}, | |||
{"device", 1, 0, 'f'}, | |||
{"firmware", 1, 0, 'f'}, | |||
{"slow", 0, 0, 's'}, | |||
{0, 0, 0, 0} | |||
}; | |||
int main(int argc, char *argv[]) | |||
{ | |||
char *devicename = NULL, *filename = NULL; | |||
int code, arg = 0; | |||
int code, arg = 0, flags = FLAG_SPEEDUP; | |||
do { | |||
code = getopt_long(argc, argv, "d:f:", opts, &arg); | |||
code = getopt_long(argc, argv, "c:d:f:s", opts, &arg); | |||
switch (code) { | |||
case 'c': filename = optarg; | |||
flags |= FLAG_CONFIG; | |||
break; | |||
case 'd': devicename = optarg; | |||
break; | |||
case 'f': filename = optarg; | |||
flags |= FLAG_FIRMWARE; | |||
break; | |||
case 'h': /* help */ | |||
printf("Usage: zyxel-revert -d <device> -f <file>\n"); | |||
printf("Usage: zyxel-revert -d <device> [-s] [ -f <file> | -c <file> ]\n"); | |||
exit(0); | |||
break; | |||
case 's': flags &= ~FLAG_SPEEDUP; | |||
break; | |||
case '?': /* error */ | |||
exit(-1); | |||
break; | |||
@@ -44,11 +54,16 @@ int main(int argc, char *argv[]) | |||
} | |||
} while (code != -1); | |||
if (devicename == NULL || filename == NULL) | |||
return -1; | |||
struct context *ctx = create_context(filename); | |||
if (ctx == NULL) | |||
exit(1); | |||
if (devicename == NULL || serial_init(ctx, devicename)) { | |||
ctx->flags = flags; | |||
if (serial_init(ctx, devicename)) { | |||
context_close(); | |||
exit(1); | |||
} |