start rewrite kernel
This commit is contained in:
parent
f8bf634345
commit
ca5105a6bb
|
@ -6,12 +6,16 @@
|
||||||
bool
|
bool
|
||||||
buf_read_sock(int sock, struct bufptr *bp)
|
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)
|
if (l < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bp->left -= l;
|
bp->left -= l;
|
||||||
bp->p += l;
|
bp->p += l;
|
||||||
|
*bp->p = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
/* This is a pointer _into_ a buffer. It is incremented (and the variable
|
/* This is a pointer _into_ a buffer. It is incremented (and the variable
|
||||||
* "left" decremented) after each operation.
|
* "left" decremented) after each operation.
|
||||||
|
*
|
||||||
|
* Space is always left for a NUL terminator.
|
||||||
*/
|
*/
|
||||||
struct bufptr {
|
struct bufptr {
|
||||||
char *p;
|
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 <zephyr/logging/log.h>
|
||||||
|
|
||||||
#include "sock.h"
|
#include "sock.h"
|
||||||
|
#include "buf.h"
|
||||||
|
|
||||||
|
#define LSC_IMPLEMENTATION
|
||||||
|
#include "lsc.h"
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(main);
|
LOG_MODULE_REGISTER(main);
|
||||||
|
|
||||||
#define PORT 6626
|
#define PORT 6626
|
||||||
enum fds {
|
|
||||||
CLIENT_FD,
|
enum {
|
||||||
SCANDATA_FD,
|
IDENT,
|
||||||
MAXFDS
|
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
|
static void
|
||||||
process_client(int cli)
|
process_client(int cli)
|
||||||
{
|
{
|
||||||
|
enum fds {
|
||||||
|
CLIENT_FD,
|
||||||
|
SCANDATA_FD,
|
||||||
|
MAXFDS
|
||||||
|
};
|
||||||
struct zsock_pollfd fds[MAXFDS] = {0};
|
struct zsock_pollfd fds[MAXFDS] = {0};
|
||||||
struct clireadbuf readbuf = {0};
|
|
||||||
|
|
||||||
client_buf_reset(&readbuf);
|
|
||||||
|
|
||||||
fds[CLIENT_FD].fd = cli;
|
fds[CLIENT_FD].fd = cli;
|
||||||
fds[CLIENT_FD].events = ZSOCK_POLLIN;
|
fds[CLIENT_FD].events = ZSOCK_POLLIN;
|
||||||
|
@ -29,19 +132,9 @@ process_client(int cli)
|
||||||
fds[SCANDATA_FD].fd = -1;
|
fds[SCANDATA_FD].fd = -1;
|
||||||
|
|
||||||
while (zsock_poll(fds, MAXFDS, 0) >= 0) {
|
while (zsock_poll(fds, MAXFDS, 0) >= 0) {
|
||||||
if (fds[CLIENT_FD].revents | POLLIN) {
|
if (fds[CLIENT_FD].revents | POLLIN)
|
||||||
if (!client_read_into_buf(cli, &readbuf)) {
|
client_parse(cli);
|
||||||
INFO_WRN("client_read_into_buf: %d", errno);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (readbuf.st == MSG_READY) {
|
|
||||||
msg_parse_dispatch(cli, &readbuf);
|
|
||||||
client_buf_reset(&buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
cleanup:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include <zephyr/net/socket.h>
|
#include <zephyr/net/socket.h>
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
|
#include "sock.h"
|
||||||
|
#include "lsc.h"
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(sock);
|
LOG_MODULE_REGISTER(sock);
|
||||||
|
|
||||||
|
@ -58,36 +60,50 @@ server_accept_client(int server)
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
int
|
||||||
client_read_into_buf(int sock, struct clireadbuf *buf)
|
sock_vprintf(int sock, char *buf, int buflen, char *fmt, va_list va)
|
||||||
{
|
{
|
||||||
if (buf->st == MSG_READY) {
|
int w = vsnprintk(buf, buflen, fmt, va);
|
||||||
LOG_WRN("%s called while MSG_READY: misuse", __func__);
|
if (w < 0)
|
||||||
return true;
|
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 w;
|
||||||
return false;
|
}
|
||||||
|
|
||||||
if (buf->b.left == 0) switch (buf->st) {
|
int
|
||||||
case WAIT_ON_HEADER: {
|
sock_name_printf(int sock, struct lsc_line *l, char *buf, int buflen, char *fmt, ...)
|
||||||
uint16_t len;
|
{
|
||||||
memcpy(&len, buf->buf, sizeof(len));
|
if (l->name) {
|
||||||
buf->b.left = ntohs(len);
|
int r = sock_printf(sock, buf, buflen, "%s\t", l->buf[0]);
|
||||||
buf->st = READING_CLIENT;
|
if (r < 0)
|
||||||
break;
|
return r;
|
||||||
} case READING_CLIENT:
|
|
||||||
buf->st = MSG_READY;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
va_list va;
|
||||||
|
va_start(va, fmt);
|
||||||
|
int r = sock_vprintf(sock, buf, buflen, fmt, va);
|
||||||
|
va_end(va);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
client_buf_reset(struct clireadbuf *buf)
|
sock_printf(int sock, char *buf, int buflen, char *fmt, ...)
|
||||||
{
|
{
|
||||||
buf->st = WAIT_ON_HEADER;
|
va_list va;
|
||||||
buf->b.p = buf->buf;
|
va_start(va, fmt);
|
||||||
buf->b.left = sizeof(uint16_t);
|
int r = sock_vprintf(sock, buf, buflen, fmt, va);
|
||||||
|
va_end(va);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,3 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "buf.h"
|
|
||||||
int server_init_sock(int port);
|
int server_init_sock(int port);
|
||||||
int server_accept_client(int server);
|
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