start rewrite kernel
This commit is contained in:
parent
f8bf634345
commit
ca5105a6bb
|
@ -6,12 +6,16 @@
|
|||
bool
|
||||
buf_read_sock(int sock, struct bufptr *bp)
|
||||
{
|
||||
ssize_t l = zsock_recv(sock, bp->p, bp->left, 0);
|
||||
if (bp->left < 2)
|
||||
return false;
|
||||
|
||||
ssize_t l = zsock_recv(sock, bp->p, bp->left - 1, 0);
|
||||
if (l < 0)
|
||||
return false;
|
||||
|
||||
bp->left -= l;
|
||||
bp->p += l;
|
||||
*bp->p = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
/* This is a pointer _into_ a buffer. It is incremented (and the variable
|
||||
* "left" decremented) after each operation.
|
||||
*
|
||||
* Space is always left for a NUL terminator.
|
||||
*/
|
||||
struct bufptr {
|
||||
char *p;
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
#ifndef LSC
|
||||
#define LSC
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef LSC_MAXARG
|
||||
# define LSC_MAXARG 32
|
||||
#endif
|
||||
|
||||
#ifndef LSC_MAXBUF
|
||||
# define LSC_MAXBUF 1024
|
||||
#endif
|
||||
|
||||
struct lsc_line {
|
||||
size_t name;
|
||||
char *buf[LSC_MAXARG];
|
||||
size_t len;
|
||||
};
|
||||
|
||||
struct lsc_parser {
|
||||
int state;
|
||||
|
||||
char intbuf[LSC_MAXBUF];
|
||||
size_t len;
|
||||
|
||||
char *rptr;
|
||||
};
|
||||
|
||||
enum lsc_r {
|
||||
LSC_MORE,
|
||||
LSC_OVERFLOW,
|
||||
LSC_ARG_OVERFLOW,
|
||||
LSC_INVALID_ARGUMENT,
|
||||
LSC_COMPLETE
|
||||
};
|
||||
|
||||
void lsc_reset(struct lsc_parser *, char *);
|
||||
enum lsc_r lsc_read(struct lsc_parser *,
|
||||
struct lsc_line *);
|
||||
static void lsc_load_ptr(struct lsc_parser *in, char *p) {
|
||||
in->rptr = p;
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef LSC_IMPLEMENTATION
|
||||
|
||||
enum { LSC_READ, LSC_DISCARD };
|
||||
|
||||
static void reset_parse_state(struct lsc_parser *in) {
|
||||
in->state = LSC_READ;
|
||||
in->len = 0;
|
||||
}
|
||||
|
||||
void lsc_reset(struct lsc_parser *in, char *p) {
|
||||
reset_parse_state(in);
|
||||
in->rptr = p;
|
||||
}
|
||||
|
||||
static enum lsc_r lsc_parse(struct lsc_parser *in,
|
||||
struct lsc_line *line) {
|
||||
char *s = in->intbuf;
|
||||
enum lsc_r r = LSC_ARG_OVERFLOW;
|
||||
|
||||
line->name = (*s == ':');
|
||||
line->len = 0;
|
||||
|
||||
while (line->len < LSC_MAXARG) {
|
||||
line->buf[line->len++] = s;
|
||||
for (; *s && *s != '\t'; s++);
|
||||
|
||||
if (!*s) {
|
||||
r = LSC_COMPLETE;
|
||||
break;
|
||||
} else {
|
||||
*s = 0;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
reset_parse_state(in);
|
||||
return r;
|
||||
}
|
||||
|
||||
enum lsc_r lsc_read(struct lsc_parser *psr,
|
||||
struct lsc_line *line) {
|
||||
char c;
|
||||
|
||||
if (!psr || !psr->rptr || !line)
|
||||
return LSC_INVALID_ARGUMENT;
|
||||
|
||||
while ((c = *psr->rptr)) {
|
||||
psr->rptr++;
|
||||
if (psr->state == LSC_DISCARD) {
|
||||
if (c == '\n') {
|
||||
reset_parse_state(psr);
|
||||
return LSC_OVERFLOW;
|
||||
}
|
||||
} else {
|
||||
switch (c) {
|
||||
case '\n':
|
||||
psr->intbuf[psr->len] = 0;
|
||||
return lsc_parse(psr, line);
|
||||
default:
|
||||
if (psr->len == LSC_MAXBUF)
|
||||
psr->state = LSC_DISCARD;
|
||||
psr->intbuf[psr->len++] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LSC_MORE;
|
||||
}
|
||||
#endif
|
|
@ -5,23 +5,126 @@
|
|||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include "sock.h"
|
||||
#include "buf.h"
|
||||
|
||||
#define LSC_IMPLEMENTATION
|
||||
#include "lsc.h"
|
||||
|
||||
LOG_MODULE_REGISTER(main);
|
||||
|
||||
#define PORT 6626
|
||||
|
||||
enum {
|
||||
IDENT,
|
||||
ADC,
|
||||
DAC,
|
||||
|
||||
CL_SETPT,
|
||||
CL_P,
|
||||
CL_I,
|
||||
CL_ARM,
|
||||
CL_ERR,
|
||||
CL_Z,
|
||||
CL_CYCLES,
|
||||
CL_DELAY,
|
||||
|
||||
RASTER_MAX_SAMPLES,
|
||||
RASTER_MAX_LINES,
|
||||
RASTER_SETTLE_TIME,
|
||||
RASTER_DX,
|
||||
RASTER_DY,
|
||||
RASTER_USED_ADCS,
|
||||
RASTER_ARM,
|
||||
|
||||
ARGS_NUM
|
||||
};
|
||||
|
||||
static int _strcmp(const void *p1, const void *p2) {return strcmp(p1,p2);}
|
||||
|
||||
static int
|
||||
client_exec(int sock, struct lsc_line *l)
|
||||
{
|
||||
static char buf[4096];
|
||||
# define stringify(s) #s
|
||||
# define mkid(s) [s] = stringify(s)
|
||||
static const char *argnames[ARGS_NUM] = {
|
||||
mkid(IDENT),
|
||||
mkid(ADC),
|
||||
mkid(DAC),
|
||||
|
||||
mkid(CL_SETPT),
|
||||
mkid(CL_P),
|
||||
mkid(CL_I),
|
||||
mkid(CL_ARM),
|
||||
mkid(CL_ERR),
|
||||
mkid(CL_Z),
|
||||
mkid(CL_CYCLES),
|
||||
mkid(CL_DELAY),
|
||||
|
||||
mkid(RASTER_MAX_SAMPLES),
|
||||
mkid(RASTER_MAX_LINES),
|
||||
mkid(RASTER_SETTLE_TIME),
|
||||
mkid(RASTER_DX),
|
||||
mkid(RASTER_DY),
|
||||
mkid(RASTER_USED_ADCS),
|
||||
mkid(RASTER_ARM)
|
||||
};
|
||||
# undef mkid
|
||||
# undef stringify
|
||||
|
||||
char **p = bsearch(l->buf[l->name], argnames, ARGS_NUM,
|
||||
sizeof(argnames[0]), _strcmp);
|
||||
if (!p) {
|
||||
sock_name_printf(sock, l, buf, sizeof(buf),
|
||||
"ERROR\tunknown command\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (p - argnames) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
client_parse(int cli)
|
||||
{
|
||||
static char buf[LSC_MAXBUF];
|
||||
static struct bufptr bp = {buf, sizeof(buf)};
|
||||
static struct lsc_parser psr = {0};
|
||||
static bool first = true;
|
||||
struct lsc_line l;
|
||||
|
||||
if (first) {
|
||||
lsc_reset(&psr, buf);
|
||||
first = false;
|
||||
}
|
||||
|
||||
switch (lsc_read(&psr, &l)) {
|
||||
case LSC_OVERFLOW:
|
||||
LOG_ERR("client command overflow\n");
|
||||
break;
|
||||
case LSC_OVERFLOW:
|
||||
LOG_ERR("client command argument overflow\n");
|
||||
break;
|
||||
case LSC_INVALID_ARGUMENT:
|
||||
LOG_ERR("programmer misuse");
|
||||
break;
|
||||
case LSC_COMPLETE:
|
||||
// process
|
||||
lsc_reset(&psr, buf);
|
||||
break:
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
process_client(int cli)
|
||||
{
|
||||
enum fds {
|
||||
CLIENT_FD,
|
||||
SCANDATA_FD,
|
||||
MAXFDS
|
||||
};
|
||||
|
||||
static void
|
||||
process_client(int cli)
|
||||
{
|
||||
struct zsock_pollfd fds[MAXFDS] = {0};
|
||||
struct clireadbuf readbuf = {0};
|
||||
|
||||
client_buf_reset(&readbuf);
|
||||
|
||||
fds[CLIENT_FD].fd = cli;
|
||||
fds[CLIENT_FD].events = ZSOCK_POLLIN;
|
||||
|
@ -29,19 +132,9 @@ process_client(int cli)
|
|||
fds[SCANDATA_FD].fd = -1;
|
||||
|
||||
while (zsock_poll(fds, MAXFDS, 0) >= 0) {
|
||||
if (fds[CLIENT_FD].revents | POLLIN) {
|
||||
if (!client_read_into_buf(cli, &readbuf)) {
|
||||
INFO_WRN("client_read_into_buf: %d", errno);
|
||||
goto cleanup;
|
||||
if (fds[CLIENT_FD].revents | POLLIN)
|
||||
client_parse(cli);
|
||||
}
|
||||
|
||||
if (readbuf.st == MSG_READY) {
|
||||
msg_parse_dispatch(cli, &readbuf);
|
||||
client_buf_reset(&buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
cleanup:
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include <zephyr/net/socket.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include "sock.h"
|
||||
#include "lsc.h"
|
||||
|
||||
LOG_MODULE_REGISTER(sock);
|
||||
|
||||
|
@ -58,36 +60,50 @@ server_accept_client(int server)
|
|||
return client;
|
||||
}
|
||||
|
||||
bool
|
||||
client_read_into_buf(int sock, struct clireadbuf *buf)
|
||||
int
|
||||
sock_vprintf(int sock, char *buf, int buflen, char *fmt, va_list va)
|
||||
{
|
||||
if (buf->st == MSG_READY) {
|
||||
LOG_WRN("%s called while MSG_READY: misuse", __func__);
|
||||
return true;
|
||||
int w = vsnprintk(buf, buflen, fmt, va);
|
||||
if (w < 0)
|
||||
return b;
|
||||
else if (w <= buflen)
|
||||
return w - buflen;
|
||||
|
||||
ssize_t left = w;
|
||||
char *p = buf;
|
||||
while (left > 0) {
|
||||
ssize_t i = zsock_send(sock, p, left, 0);
|
||||
if (i < 0)
|
||||
return 0;
|
||||
p += i;
|
||||
left -= i;
|
||||
}
|
||||
|
||||
if (!buf_read_sock(sock, &buf->b))
|
||||
return false;
|
||||
|
||||
if (buf->b.left == 0) switch (buf->st) {
|
||||
case WAIT_ON_HEADER: {
|
||||
uint16_t len;
|
||||
memcpy(&len, buf->buf, sizeof(len));
|
||||
buf->b.left = ntohs(len);
|
||||
buf->st = READING_CLIENT;
|
||||
break;
|
||||
} case READING_CLIENT:
|
||||
buf->st = MSG_READY;
|
||||
break;
|
||||
return w;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
client_buf_reset(struct clireadbuf *buf)
|
||||
int
|
||||
sock_name_printf(int sock, struct lsc_line *l, char *buf, int buflen, char *fmt, ...)
|
||||
{
|
||||
buf->st = WAIT_ON_HEADER;
|
||||
buf->b.p = buf->buf;
|
||||
buf->b.left = sizeof(uint16_t);
|
||||
if (l->name) {
|
||||
int r = sock_printf(sock, buf, buflen, "%s\t", l->buf[0]);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
int r = sock_vprintf(sock, buf, buflen, fmt, va);
|
||||
va_end(va);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
sock_printf(int sock, char *buf, int buflen, char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
int r = sock_vprintf(sock, buf, buflen, fmt, va);
|
||||
va_end(va);
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -1,19 +1,3 @@
|
|||
#pragma once
|
||||
#include "buf.h"
|
||||
int server_init_sock(int port);
|
||||
int server_accept_client(int server);
|
||||
|
||||
#define CLIREADBUF_SIZ 1024
|
||||
enum clireadbuf_state {
|
||||
WAIT_ON_HEADER,
|
||||
READING_CLIENT,
|
||||
MSG_READY
|
||||
};
|
||||
struct clireadbuf {
|
||||
struct bufptr b;
|
||||
enum clireadbuf_state st;
|
||||
char buf[CLIREADBUF_SIZ];
|
||||
};
|
||||
|
||||
bool client_read_into_buf(int sock, struct clireadbuf *buf);
|
||||
void client_buf_reset(struct clireadbuf *buf);
|
||||
|
|
Loading…
Reference in New Issue