struct ClientList clients;
-void vbadcmd(ParseState *ps, const char *fmt, va_list al) {
- oprintf(&ps->cl->ch,"error ");
- ovprintf(&ps->cl->ch,fmt,al);
- owrite(&ps->cl->ch,"\n",1);
-}
-
-const void *any_lookup(ParseState *ps, const void *inf, size_t sz) {
- const char *tname;
-
- for (;
- (tname= *(const char *const*)inf);
- inf= (const char*)inf + sz)
- if (!thiswordstrcmp(ps,tname))
- return inf;
- return 0;
-}
-
-const void *any_needword_lookup(ParseState *ps, const void *infs,
- size_t sz, const char *what) {
- const void *r;
- if (!ps_needword(ps)) return 0;
- r= any_lookup(ps,infs,sz);
- if (!r) { badcmd(ps,"unknown %s",what); return 0; }
- return r;
-}
-
-void ps_callword(ParseState *ps, const CmdInfo *infs, const char *what) {
- const CmdInfo *ci;
- ci= some_needword_lookup(ps,infs,what);
- if (ci) ci->fn(ps,ci);
-}
-
-static void *client_iferr(oop_source *evts, oop_read *cl_read,
- oop_rd_event evt, const char *errmsg, int errnoval,
- const char *data, size_t recsz, void *cl_v) {
- Client *cl= cl_v;
-
- cl->ch.error(&cl->ch, "read",
- oop_rd_errmsg(cl_read, evt,
- errnoval, OOP_RD_STYLE_GETLINE));
- return OOP_CONTINUE;
-}
-
-static void *client_ifok(oop_source *evts, oop_read *cl_read,
- oop_rd_event evt, const char *errmsg, int errnoval,
- const char *data, size_t recsz, void *cl_v) {
- Client *cl= cl_v;
- ParseState ps;
-
- if (evt == OOP_RD_EOF) {
- cl->ch.error(&cl->ch,0,0);
- return OOP_CONTINUE;
- }
-
- if (evt != OOP_RD_OK)
- return client_iferr(evts,cl_read,evt,errmsg,errnoval,data,recsz,cl_v);
-
- ps.cl= cl;
- ps.remain= data;
- ps_callword(&ps, toplevel_cmds, "command");
- return OOP_CONTINUE;
-}
-
-static void *client_exception(oop_source *evts, int fd,
- oop_event evt, void *cl_v) {
- Client *cl= cl_v;
- cl->ch.error(&cl->ch,"comms error","exception");
- return OOP_CONTINUE;
-}
-
static void new_client(int fd, OutBufferError error,
char *desc, Selector default_selectors) {
Client *cl;
int r;
cl= mmalloc(sizeof(*cl));
-
cl->sel= default_selectors;
- cl->ch.desc= desc;
- cl->ch.fd= fd;
- cl->ch.error= error;
- obc_init(&cl->ch);
-
- events->on_fd(events, fd, OOP_EXCEPTION, client_exception, cl);
-
- cl->rd= oop_rd_new_fd(events, fd, 0,0);
- if (!cl->rd) diee("oop_rd_new_fd");
- r= oop_rd_read(cl->rd, OOP_RD_STYLE_GETLINE, 1024,
- client_ifok, cl,
- client_iferr, cl);
- if (r) diee("oop_rd_read");
+
+ cl->ci.out.desc= desc;
+ cl->ci.out.fd= fd;
+ cl->ci.out.error= error;
+ cmdin_new(&cl->ci);
LIST_LINK_TAIL(clients, cl);
}
/*
- * declarations common to simple test program and real controller daemon
+ * declarations common to
+ * - simple test program
+ * - realtime daemon
+ * - multiplexer daemon
*/
#ifndef COMMON_H
#include "hostside.h"
#include "auproto-pic.h"
-oop_source *events;
FILE *dump_stream= 0;
-
-static void serial_error(OutBufferChain *ch, const char *e1, const char *e2) {
- abort();
-}
-
-static OutBufferChain serial_ochain= { (char*)"serial", -1, serial_error };
-
-static void *serial_exception(oop_source *evts, int fd,
- oop_event evt, void *cl_v) {
- char bufc;
- int r;
-
- r= read(serial_fd, &bufc, 1);
- if (r==-1) diee("serial port - exception");
- else if (r==0) die("serial port - exception, reads EOF");
- else die("serial port - exception but readable");
-}
-
-static int serial_buf_used;
-static PicInsn serial_buf;
-
-void oopicio(const char *dirn, const PicInsnInfo *pii, int objnum) {
- if (!pii->argbits)
- ooprintf(sel_picio, "picio %s %s\n", dirn, pii->name);
- else
- ooprintf(sel_picio, "picio %s %s %u\n", dirn, pii->name, objnum);
-}
-
-static void serial_incoming(const PicInsn *pi) {
- const PicInsnInfo *pii;
- int objnum;
-
- output_hex(sel_picioh, "picioh in", pi->d, pi->l);
- picinsn_decode(pi, pic_reply_infos, &pii, &objnum);
-
- if (pii) {
- oopicio("in",pii,objnum);
- pii->input_fn(pii,pi,objnum);
- } else {
- Byte byte0;
-
- assert(pi->l);
- byte0= pi->d[0];
-
- if ((byte0 & 0xc0) == 0x40 ||
- (byte0 & 0xe0) == 0x20) {
- ooprintf(sel_picdebug, "picdebug `%c'", byte0);
- } else if (byte0 == 0x0a) {
- ooprintf(sel_picdebug, "picdebug newline");
- } else {
- ooprintf(sel_picio, "picio in unknown\n");
- return;
- }
- if (picdebug_copy) {
- if (fputc(byte0, picdebug_copy) == EOF)
- diee("picdebug stream write");
- }
- }
-}
-
-static void *serial_readable(oop_source *evts, int fd,
- oop_event evt, void *u0) {
- const Byte *ep;
- int r;
-
- r= read(serial_fd, &serial_buf.d, sizeof(serial_buf.d) - serial_buf_used);
- if (r==0) die("serial port - eof");
- if (r==-1) {
- if (errno == EWOULDBLOCK || errno == EINTR)
- return OOP_CONTINUE;
- diee("serial port - read error");
- }
- serial_buf_used += r;
-
- for (;;) {
- for (serial_buf.l= 0, ep= serial_buf.d;
- serial_buf.l < serial_buf_used;
- serial_buf.l++, ep++)
- if (!(*ep & 0x80u))
- goto found_end;
-
- assert(serial_buf.l == serial_buf_used);
- if (serial_buf.l == sizeof(serial_buf.d))
- die("serial port - packet too long");
- break;
-
- found_end:
- serial_incoming(&serial_buf);
- serial_buf_used -= serial_buf.l;
- memmove(serial_buf.d, serial_buf.d + serial_buf.l, serial_buf_used);
- }
- return OOP_CONTINUE;
-}
-
-const char *device;
-
-int main(int argc, const char **argv) {
- oop_source_sys *sys_events;
- int r;
-
- device= argv[1];
- if (!device) device= "/dev/ttyS0";
-
- sys_events= oop_sys_new(); if (!sys_events) diee("oop_sys_new");
- events= oop_sys_source(sys_events); assert(events);
-
- serial_open(device);
- r= oop_fd_nonblock(serial_fd, 1); if (r) diee("nonblock(serial_fd,1)");
- serial_ochain.fd= serial_fd;
-
- stdin_client();
-
- events->on_fd(events, serial_fd, OOP_READ, serial_readable, 0);
- events->on_fd(events, serial_fd, OOP_EXCEPTION, serial_exception, 0);
- oop_sys_run(sys_events);
- abort();
-}
#include "common.h"
-#include <oop.h>
-#include <oop-read.h>
-
-typedef struct Client Client;
typedef struct ParseState ParseState;
typedef struct CmdInfo CmdInfo;
-typedef struct RetransmitNode RetransmitNode;
-
-/*---------- from obc.c ----------*/
-
-typedef struct OutBuffer OutBuffer;
-typedef struct OutBufferChain OutBufferChain;
-typedef void OutBufferError(OutBufferChain*, const char *e1, const char *e2);
-
-struct OutBufferChain {
- /* set by user: */
- char *desc;
- int fd;
- OutBufferError *error;
- /* set/used by obc_..., oprintf, etc., only */
- int done_of_head;
- struct { OutBuffer *head, *tail; } obs;
-};
-
-void obc_init(OutBufferChain *ch);
-
-void ovprintf(OutBufferChain *ch, const char *fmt, va_list al)
- __attribute__((format(printf,2,0)));
-void oprintf(OutBufferChain *ch, const char *msg, ...)
- __attribute__((format(printf,2,3)));
-void owrite(OutBufferChain *ch, const char *data, int l);
-
-/*---------- from output.c ----------*/
-
-typedef unsigned long Selector;
-#include "selectors.h"
-
-void oovprintf(Selector sel, const char *fmt, va_list al)
- __attribute__((format(printf,2,0)));
-void ooprintf(Selector sel, const char *fmt, ...)
- __attribute__((format(printf,2,3)));
-void oowrite(Selector sel, const char *data, int l);
-
-void serial_transmit(const PicInsn *pi);
-
-void output_hex(Selector sel, const char *work,
- const Byte *command, int length);
/*---------- from protocol.c ----------*/
/*---------- from hostside.c ----------*/
extern oop_source *events;
-extern FILE *picdebug_copy;
/*---------- from client.c ----------*/
-struct ClientList { Client *head, *tail; };
-extern struct ClientList clients;
-
-struct Client {
- OutBufferChain ch;
- Client *back, *next;
- Selector sel;
- oop_read *rd;
-};
-
struct ParseState {
Client *cl;
const char *remain;
const void *any_lookup(ParseState *ps, const void *infos, size_t infosz);
const void *any_needword_lookup(ParseState *ps, const void *infos,
size_t sz, const char *what);
-
-#endif /*HOSTSIDE_H*/
-/*
- * transmissions to clients
- */
-
-#include <string.h>
-#include <stdarg.h>
-
-#include "hostside.h"
-#include "auproto-pic.h"
-
-#define FOR_OOS(s) do{ \
- Client *cl, *next_cl; \
- for (cl= clients.head; \
- cl; \
- cl= next_cl) { \
- OutBufferChain *ch= &cl->ch; \
- next_cl= cl->next; \
- if (!(sel & cl->sel)) continue; \
- s; \
- } \
- }while(0)
-
-void oovprintf(Selector sel, const char *fmt, va_list al) {
- FOR_OOS( ovprintf(ch, fmt, al) );
-}
-
-void ooprintf(Selector sel, const char *fmt, ...)
- { va_list al; va_start(al,fmt); oovprintf(sel,fmt,al); va_end(al); }
-
-void oowrite(Selector sel, const char *data, int l) {
- FOR_OOS( owrite(ch, data, l) );
-}
-
-void output_hex(Selector sel, const char *word,
- const Byte *command, int length) {
- ooprintf(sel, "%s", word);
- while (length) {
- ooprintf(sel, " %02x", *command++);
- length--;
- }
- ooprintf(sel, "\n");
-}
-
-void serial_transmit(const PicInsn *pi) {
- const PicInsnInfo *pii;
- int objnum;
-
- picinsn_decode(pi, pic_command_infos, &pii, &objnum);
-
- if (!pii)
- ooprintf(sel_picio, "picio out unknown\n");
- else
- oopicio("out",pii,objnum);
-
- output_hex(sel_picioh, "picioh out", pi->d, pi->l);
- serial_transmit_now(pi->d, pi->l);
-}