start rewrite kernel

This commit is contained in:
Peter McGoron 2023-01-01 21:10:02 +00:00
parent f8bf634345
commit ca5105a6bb
6 changed files with 270 additions and 59 deletions

View File

@ -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;
}

View File

@ -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;

112
software/src/lsc.h Normal file
View File

@ -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

View File

@ -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 fds {
CLIENT_FD,
SCANDATA_FD,
MAXFDS
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
};
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 (readbuf.st == MSG_READY) {
msg_parse_dispatch(cli, &readbuf);
client_buf_reset(&buf);
}
}
if (fds[CLIENT_FD].revents | POLLIN)
client_parse(cli);
}
cleanup:
}
void

View File

@ -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;
return w;
}
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;
int
sock_name_printf(int sock, struct lsc_line *l, char *buf, int buflen, char *fmt, ...)
{
if (l->name) {
int r = sock_printf(sock, buf, buflen, "%s\t", l->buf[0]);
if (r < 0)
return r;
}
return true;
va_list va;
va_start(va, fmt);
int r = sock_vprintf(sock, buf, buflen, fmt, va);
va_end(va);
return r;
}
void
client_buf_reset(struct clireadbuf *buf)
int
sock_printf(int sock, char *buf, int buflen, char *fmt, ...)
{
buf->st = WAIT_ON_HEADER;
buf->b.p = buf->buf;
buf->b.left = sizeof(uint16_t);
va_list va;
va_start(va, fmt);
int r = sock_vprintf(sock, buf, buflen, fmt, va);
va_end(va);
return r;
}

View File

@ -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);