introduce linebuffer.[ch]
This commit is contained in:
parent
5957dcc2bb
commit
b0532dd7b1
2
Makefile
2
Makefile
@ -2,7 +2,7 @@ CFLAGS := -O2 -pipe -Wall
|
|||||||
|
|
||||||
all: zyxel-revert compress decompress cfgpatch
|
all: zyxel-revert compress decompress cfgpatch
|
||||||
|
|
||||||
zyxel-revert: event.o filedata.o logging.o context.o serial.o statemachine.o xmodem.o zyxel-revert.o
|
zyxel-revert: event.o filedata.o linebuffer.o logging.o context.o serial.o statemachine.o xmodem.o zyxel-revert.o
|
||||||
$(CC) $(CFLAGS) $^ -o $@
|
$(CC) $(CFLAGS) $^ -o $@
|
||||||
|
|
||||||
compress: filedata.o lzsc.o romfile.o compress.o
|
compress: filedata.o lzsc.o romfile.o compress.o
|
||||||
|
@ -18,8 +18,15 @@ struct context * create_context(const char *filename)
|
|||||||
|
|
||||||
memset(ctx, 0, sizeof(struct context));
|
memset(ctx, 0, sizeof(struct context));
|
||||||
|
|
||||||
|
ctx->lbuf = create_linebuffer(256);
|
||||||
|
if (ctx->lbuf == NULL) {
|
||||||
|
free(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->file = get_filedata(filename);
|
ctx->file = get_filedata(filename);
|
||||||
if (ctx->file == NULL) {
|
if (ctx->file == NULL) {
|
||||||
|
free(ctx->lbuf);
|
||||||
free(ctx);
|
free(ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -36,6 +43,7 @@ int destroy_context(struct context *ctx)
|
|||||||
ctx->dev_close(ctx);
|
ctx->dev_close(ctx);
|
||||||
|
|
||||||
free(ctx->file);
|
free(ctx->file);
|
||||||
|
free(ctx->lbuf);
|
||||||
free(ctx);
|
free(ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define _CONTEXT_H_
|
#define _CONTEXT_H_
|
||||||
|
|
||||||
#include "filedata.h"
|
#include "filedata.h"
|
||||||
|
#include "linebuffer.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
struct context {
|
struct context {
|
||||||
@ -21,8 +22,7 @@ struct context {
|
|||||||
int state;
|
int state;
|
||||||
|
|
||||||
/* line buffer */
|
/* line buffer */
|
||||||
char linebuf[256];
|
struct linebuffer *lbuf;
|
||||||
int linepos;
|
|
||||||
|
|
||||||
/* xmodem */
|
/* xmodem */
|
||||||
int lastpkt;
|
int lastpkt;
|
||||||
|
68
linebuffer.c
Normal file
68
linebuffer.c
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "linebuffer.h"
|
||||||
|
|
||||||
|
struct linebuffer * create_linebuffer(int size)
|
||||||
|
{
|
||||||
|
struct linebuffer *retval = malloc(sizeof(struct linebuffer) + size);
|
||||||
|
if (retval == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
retval->size = size;
|
||||||
|
retval->pos = 0;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int linebuffer_read(struct linebuffer *lbuf, int fd)
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
int len = read(fd, buf, sizeof(buf));
|
||||||
|
if (len <= 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
/* "understand" backspace */
|
||||||
|
if (buf[i] == 0x08 && lbuf->pos > 0) {
|
||||||
|
lbuf->pos--;
|
||||||
|
|
||||||
|
/* copy */
|
||||||
|
} else if (buf[i] >= ' ' || buf[i] == '\r') {
|
||||||
|
lbuf->data[lbuf->pos++] = buf[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lbuf->pos > lbuf->size)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * linebuffer_get(struct linebuffer *lbuf)
|
||||||
|
{
|
||||||
|
char *newline = memchr(lbuf->data, '\r', lbuf->pos);
|
||||||
|
if (newline == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char *retval = NULL;
|
||||||
|
*newline = '\0';
|
||||||
|
|
||||||
|
int len = newline - lbuf->data;
|
||||||
|
if (len > 0)
|
||||||
|
retval = strdup(lbuf->data);
|
||||||
|
|
||||||
|
lbuf->pos -= len +1;
|
||||||
|
memmove(lbuf->data, newline +1, lbuf->pos);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int linebuffer_clear(struct linebuffer *lbuf)
|
||||||
|
{
|
||||||
|
int oldpos = lbuf->pos;
|
||||||
|
lbuf->pos = 0;
|
||||||
|
return oldpos;
|
||||||
|
}
|
18
linebuffer.h
Normal file
18
linebuffer.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef _LINEBUFFER_H_
|
||||||
|
#define _LINEBUFFER_H_
|
||||||
|
|
||||||
|
struct linebuffer {
|
||||||
|
int size;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
char data[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct linebuffer * create_linebuffer(int size);
|
||||||
|
|
||||||
|
int linebuffer_read(struct linebuffer *lbuf, int fd);
|
||||||
|
char * linebuffer_get(struct linebuffer *lbuf);
|
||||||
|
|
||||||
|
int linebuffer_clear(struct linebuffer *lbuf);
|
||||||
|
|
||||||
|
#endif /* _LINEBUFFER_H_ */
|
3
serial.c
3
serial.c
@ -55,9 +55,6 @@ static int setbaudrate(struct context *ctx, int baudrate)
|
|||||||
cfsetispeed(&sdev->newtio, baudrate);
|
cfsetispeed(&sdev->newtio, baudrate);
|
||||||
cfsetospeed(&sdev->newtio, baudrate);
|
cfsetospeed(&sdev->newtio, baudrate);
|
||||||
|
|
||||||
/* flush linebuffer */
|
|
||||||
ctx->linepos = 0;
|
|
||||||
|
|
||||||
if (tcsetattr(ctx->fd, TCSANOW, &sdev->newtio) != 0) {
|
if (tcsetattr(ctx->fd, TCSANOW, &sdev->newtio) != 0) {
|
||||||
log_print(LOG_WARN, "open_serial(): tcsetattr()");
|
log_print(LOG_WARN, "open_serial(): tcsetattr()");
|
||||||
close(ctx->fd);
|
close(ctx->fd);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
#include "linebuffer.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "xmodem.h"
|
#include "xmodem.h"
|
||||||
|
|
||||||
@ -39,57 +40,6 @@ enum {
|
|||||||
MSG_BAUD_LOW,
|
MSG_BAUD_LOW,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int my_readline(int fd, struct context *ctx, char **retval)
|
|
||||||
{
|
|
||||||
char *newline = memchr(ctx->linebuf, '\r', ctx->linepos);
|
|
||||||
if (newline != NULL) {
|
|
||||||
int len = newline - ctx->linebuf;
|
|
||||||
*newline = '\0';
|
|
||||||
if (len > 0)
|
|
||||||
*retval = strdup(ctx->linebuf);
|
|
||||||
|
|
||||||
ctx->linepos -= len +1;
|
|
||||||
memmove(ctx->linebuf, newline +1, ctx->linepos);
|
|
||||||
|
|
||||||
newline = memchr(ctx->linebuf, '\r', ctx->linepos);
|
|
||||||
return ((*retval != NULL) ? 1 : 0) + ((newline != NULL) ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
char buf[32];
|
|
||||||
int len = read(fd, buf, sizeof(buf));
|
|
||||||
if (len <= 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
int i, numlines = 0;
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
/* "understand" backspace */
|
|
||||||
if (buf[i] == 0x08 && ctx->linepos > 0) {
|
|
||||||
ctx->linepos--;
|
|
||||||
|
|
||||||
/* export buffer */
|
|
||||||
} else if (buf[i] == '\r') {
|
|
||||||
if (*retval == NULL) {
|
|
||||||
ctx->linebuf[ctx->linepos] = '\0';
|
|
||||||
|
|
||||||
if (ctx->linepos > 0)
|
|
||||||
*retval = strdup(ctx->linebuf);
|
|
||||||
|
|
||||||
ctx->linepos = 0;
|
|
||||||
numlines = 1;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ctx->linebuf[ctx->linepos++] = buf[i];
|
|
||||||
numlines++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy */
|
|
||||||
} else if (buf[i] >= ' ') {
|
|
||||||
ctx->linebuf[ctx->linepos++] = buf[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return numlines;
|
|
||||||
}
|
|
||||||
|
|
||||||
int statemachine_read(int fd, void *privdata)
|
int statemachine_read(int fd, void *privdata)
|
||||||
{
|
{
|
||||||
struct context *ctx = (struct context *)privdata;
|
struct context *ctx = (struct context *)privdata;
|
||||||
@ -101,15 +51,11 @@ int statemachine_read(int fd, void *privdata)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int numlines;
|
if (linebuffer_read(ctx->lbuf, fd) < 0)
|
||||||
do {
|
return -1;
|
||||||
char *line = NULL;
|
|
||||||
numlines = my_readline(fd, ctx, &line);
|
|
||||||
if (numlines < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (line == NULL)
|
char *line;
|
||||||
return 0;
|
while ((line = linebuffer_get(ctx->lbuf)) != NULL) {
|
||||||
|
|
||||||
log_print(LOG_DEBUG, "%s: '%s'", ctx->devname, line);
|
log_print(LOG_DEBUG, "%s: '%s'", ctx->devname, line);
|
||||||
|
|
||||||
@ -141,7 +87,7 @@ int statemachine_read(int fd, void *privdata)
|
|||||||
/* follow device to high baudrate */
|
/* follow device to high baudrate */
|
||||||
} else if (msg == MSG_BAUD_HIGH) {
|
} else if (msg == MSG_BAUD_HIGH) {
|
||||||
ctx->dev_setbaudrate(ctx, B115200);
|
ctx->dev_setbaudrate(ctx, B115200);
|
||||||
numlines = 0;
|
linebuffer_clear(ctx->lbuf);
|
||||||
|
|
||||||
ctx->state = STATE_XMODEM;
|
ctx->state = STATE_XMODEM;
|
||||||
write(fd, "ATLC\r\n", 6);
|
write(fd, "ATLC\r\n", 6);
|
||||||
@ -154,11 +100,11 @@ int statemachine_read(int fd, void *privdata)
|
|||||||
/* follow device to low baudrate */
|
/* follow device to low baudrate */
|
||||||
} else if (msg == MSG_BAUD_LOW) {
|
} else if (msg == MSG_BAUD_LOW) {
|
||||||
ctx->dev_setbaudrate(ctx, B9600);
|
ctx->dev_setbaudrate(ctx, B9600);
|
||||||
numlines = 0;
|
linebuffer_clear(ctx->lbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(line);
|
free(line);
|
||||||
} while (numlines > 1);
|
};
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user