fix readline handline

This commit is contained in:
Olaf Rempel 2007-04-30 19:06:17 +02:00
parent a15af2d522
commit 65b85824ed
3 changed files with 72 additions and 56 deletions

View File

@ -36,7 +36,7 @@ static int open_serial(struct context *ctx, const char *devname)
} }
bzero(&sdev->newtio, sizeof(struct termios)); bzero(&sdev->newtio, sizeof(struct termios));
sdev->newtio.c_cflag = B9600 | CRTSCTS | CS8 | CLOCAL | CREAD; sdev->newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
tcflush(ctx->fd, TCIOFLUSH); tcflush(ctx->fd, TCIOFLUSH);

View File

@ -41,16 +41,18 @@ enum {
static int my_readline(int fd, struct context *ctx, char **retval) static int my_readline(int fd, struct context *ctx, char **retval)
{ {
/* TODO: not tested */
char *newline = memchr(ctx->linebuf, '\r', ctx->linepos); char *newline = memchr(ctx->linebuf, '\r', ctx->linepos);
if (newline != NULL) { if (newline != NULL) {
int len = newline - ctx->linebuf;
*newline = '\0'; *newline = '\0';
*retval = strdup(ctx->linebuf); if (len > 0)
*retval = strdup(ctx->linebuf);
ctx->linepos -= (newline - ctx->linebuf); ctx->linepos -= len +1;
memmove(ctx->linebuf, newline +1, ctx->linepos); memmove(ctx->linebuf, newline +1, ctx->linepos);
return 0; newline = memchr(ctx->linebuf, '\r', ctx->linepos);
return ((*retval != NULL) ? 1 : 0) + ((newline != NULL) ? 1 : 0);
} }
char buf[32]; char buf[32];
@ -58,27 +60,34 @@ static int my_readline(int fd, struct context *ctx, char **retval)
if (len <= 0) if (len <= 0)
return -1; return -1;
int i; int i, numlines = 0;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
/* "understand" backspace */ /* "understand" backspace */
if (buf[i] == 0x08 && ctx->linepos > 0) { if (buf[i] == 0x08 && ctx->linepos > 0) {
ctx->linepos--; ctx->linepos--;
/* export buffer */ /* export buffer */
} else if (buf[i] == '\r' && *retval == NULL) { } else if (buf[i] == '\r') {
ctx->linebuf[ctx->linepos] = '\0'; if (*retval == NULL) {
ctx->linebuf[ctx->linepos] = '\0';
if (ctx->linepos > 0) if (ctx->linepos > 0)
*retval = strdup(ctx->linebuf); *retval = strdup(ctx->linebuf);
ctx->linepos = 0; ctx->linepos = 0;
numlines = 1;
} else {
ctx->linebuf[ctx->linepos++] = buf[i];
numlines++;
}
/* copy */ /* copy */
} else if (buf[i] >= ' ') { } else if (buf[i] >= ' ') {
ctx->linebuf[ctx->linepos++] = buf[i]; ctx->linebuf[ctx->linepos++] = buf[i];
} }
} }
return 0; return numlines;
} }
int statemachine_read(int fd, void *privdata) int statemachine_read(int fd, void *privdata)
@ -92,57 +101,64 @@ int statemachine_read(int fd, void *privdata)
return 0; return 0;
} }
char *line = NULL; int numlines;
if (my_readline(fd, ctx, &line) < 0) do {
return -1; char *line = NULL;
numlines = my_readline(fd, ctx, &line);
if (numlines < 0)
return -1;
if (line == NULL) if (line == NULL)
return 0; return 0;
log_print(LOG_DEBUG, "%s: '%s'", ctx->devname, line); log_print(LOG_DEBUG, "%s: '%s'", ctx->devname, line);
int msg = 0; int msg = 0;
while (rx_msg[msg] != NULL) { while (rx_msg[msg] != NULL) {
if (strcmp(line, rx_msg[msg]) == 0) if (strcmp(line, rx_msg[msg]) == 0)
break; break;
msg++; msg++;
}
/* wait for "Press any key" */
if (msg == MSG_DEBUG_ASK) {
ctx->state = STATE_DEBUG_ASK;
write(fd, "\r\n", 2);
/* debug mode entered */
} else if (msg == MSG_DEBUG) {
/* if device supports it, switch to high baudrate */
if (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);
} }
/* follow device to high baudrate */ /* wait for "Press any key" */
} else if (msg == MSG_BAUD_HIGH) { if (msg == MSG_DEBUG_ASK) {
ctx->dev_setbaudrate(ctx, B115200); ctx->state = STATE_DEBUG_ASK;
write(fd, "\r\n", 2);
ctx->state = STATE_XMODEM; /* debug mode entered */
write(fd, "ATLC\r\n", 6); } else if (msg == MSG_DEBUG) {
/* if device supports it, switch to high baudrate */
if (ctx->dev_setbaudrate != NULL) {
ctx->state = STATE_SWITCH_BAUDRATE;
write(fd, "ATBA5\r\n", 7);
/* transfer was success */ } else {
} else if (msg == MSG_XMODEM_OK && ctx->state == STATE_XMODEM_COMPLETE) { ctx->state = STATE_XMODEM;
ctx->state = STATE_BOOT; write(fd, "ATLC\r\n", 6);
write(fd, "ATGR\r\n", 6); }
/* follow device to low baudrate */ /* follow device to high baudrate */
} else if (msg == MSG_BAUD_LOW) { } else if (msg == MSG_BAUD_HIGH) {
ctx->dev_setbaudrate(ctx, B9600); ctx->dev_setbaudrate(ctx, B115200);
} numlines = 0;
ctx->state = STATE_XMODEM;
write(fd, "ATLC\r\n", 6);
/* transfer was success */
} else if (msg == MSG_XMODEM_OK && ctx->state == STATE_XMODEM_COMPLETE) {
ctx->state = STATE_BOOT;
write(fd, "ATGR\r\n", 6);
/* follow device to low baudrate */
} else if (msg == MSG_BAUD_LOW) {
ctx->dev_setbaudrate(ctx, B9600);
numlines = 0;
}
free(line);
} while (numlines > 1);
free(line);
return 0; return 0;
} }

View File

@ -1,5 +1,5 @@
[global] [global]
configdata 350LI2C1.rom.own configdata 350LI2C1.rom
[ports] [ports]
serial /dev/ttyUSB0 serial /dev/ttyS0