ref: c3b784ac16bbf3f62d8d3aec49acebd2f6c77fee
author: sirjofri <sirjofri@sirjofri.de>
date: Fri Feb 17 16:51:56 EST 2023
adds first working draft
--- /dev/null
+++ b/machine.c
@@ -1,0 +1,124 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <bio.h>
+#include "machine.h"
+
+char *filename;
+Channel *chan;
+
+int running;
+
+int
+initmachine(char* file, Channel *c)
+{+ filename = file;
+
+ chan = c;
+ return 1;
+}
+
+void
+machineloop(void *c)
+{+ Channel *ch = (Channel*)c;
+ int cmd;
+ int fd;
+ Biobuf *bin, *bout;
+ void *buf;
+
+ fd = open(filename, ORDWR);
+ if (fd < 0) {+ sysfatal("can't open device file: %r");+ }
+
+ bin = Bfdopen(fd, OREAD);
+ bout = Bfdopen(fd, OWRITE);
+ if (!(bin && bout))
+ sysfatal("can't Bfdopen: %r");+
+ while (1) {+ if (nbrecv(ch, &cmd)) {+
+ if (running) {+ switch (cmd) {+ case M_Start:
+ break;
+ case M_Stop:
+ running = 0;
+#ifdef SIMULATE
+ Bprint(bout, "; stopped\n");
+#endif
+ break;
+ case M_Status:
+ break;
+ }
+ } else {+ switch (cmd) {+ case M_Start:
+ running = 1;
+#ifdef SIMULATE
+ Bprint(bout, "; started\n");
+#endif
+ break;
+ case M_Stop:
+ break;
+ case M_Status:
+ break;
+ }
+ }
+
+ }
+
+ // discard everything the printer sends
+ while (Bbuffered(bin) > 0)
+ Brdline(bin, '\n');
+
+ if (!running)
+ continue;
+
+ // machinery: write program code
+ if (program.pc >= program.data + program.size) {+ running = 0;
+ continue;
+ }
+
+ char* endl = strchr(program.pc, '\n');
+ if (endl == nil) {+ endl = program.data + program.size - 1;
+ }
+ long nbytes = endl - program.pc + 1;
+ int n = Bwrite(bout, program.pc, nbytes);
+
+ if (n != nbytes)
+ continue;
+
+ program.pc = endl + 1;
+
+ Bflush(bout);
+
+ // read ok
+ buf = Brdline(bin, '\n');
+ if (buf) {+ if (strncmp(buf, "ok", 2) == 0) {+ ;
+ }
+ //free(buf);
+ }
+ }
+}
+
+
+void
+startmachine()
+{+ int cmd = M_Start;
+ send(chan, &cmd);
+}
+
+void
+stopmachine()
+{+ int cmd = M_Stop;
+ send(chan, &cmd);
+}
--- /dev/null
+++ b/machine.h
@@ -1,0 +1,21 @@
+typedef struct Program Program;
+
+struct Program {+ char* data;
+ ulong size;
+ char* pc;
+};
+
+enum Command {+ M_Start,
+ M_Stop,
+ M_Status,
+};
+
+extern Program program;
+
+void startmachine(void);
+void stopmachine(void);
+
+int initmachine(char *file, Channel *c);
+void machineloop(void *c);
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,9 @@
+</$objtype/mkfile
+
+TARG=pronterfs
+OFILES= \
+ pronterfs.$O \
+ machine.$O
+CFLAGS=$CFLAGS '-DSIMULATE='
+
+</sys/src/cmd/mkone
--- /dev/null
+++ b/pronterfs.c
@@ -1,0 +1,167 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+#include "machine.h"
+
+void
+usage(void)
+{+ fprint(2, "usage: %s [ -s srvname ] [ -m mountpoint ] devicefile\n", argv0);
+ exits("usage");+}
+
+char *srvname = "pronterfs";
+char *mtpt = "/mnt/pronterfs";
+char *devicefile;
+
+char* Efilenotfound = "file not found";
+char* Ecnf = "command not found";
+
+Channel *chan;
+
+File* Fctl;
+File* Fprogram;
+
+Program program;
+
+void
+writeprogram(Req* r)
+{+ ulong offset;
+
+ offset = r->ifcall.offset;
+ if (offset + r->ifcall.count > program.size) {+ program.size = offset + r->ifcall.count;
+ program.data = realloc(program.data, program.size);
+ if (program.data == nil)
+ respond(r, "out of memory");
+ }
+ memmove(program.data + offset, r->ifcall.data, r->ifcall.count);
+ r->ofcall.count = r->ifcall.count;
+ Fprogram->length = program.size;
+ respond(r, nil);
+}
+
+void
+readprogram(Req* r)
+{+ ulong offset;
+ ulong count;
+
+ offset = r->ifcall.offset;
+ if (offset >= program.size) {+ r->ofcall.count = 0;
+ respond(r, nil);
+ return;
+ }
+ count = r->ifcall.count;
+ if (offset + count > program.size)
+ count = program.size - offset;
+ r->ofcall.data = program.data + offset;
+ r->ofcall.count = count;
+ respond(r, nil);
+}
+
+void
+writectl(Req *r)
+{+ char* cmd;
+
+ cmd = r->ifcall.data;
+ cmd[r->ifcall.count-1] = 0;
+
+ if (strcmp(cmd, "start") == 0) {+ startmachine();
+ respond(r, nil);
+ return;
+ }
+ if (strcmp(cmd, "stop") == 0) {+ stopmachine();
+ respond(r, nil);
+ return;
+ }
+
+ respond(r, Ecnf);
+}
+
+void
+readctl(Req *r)
+{+ respond(r, nil);
+}
+
+void
+fsread(Req *r)
+{+ if (r->fid->file == Fctl) {+ readctl(r);
+ return;
+ }
+ if (r->fid->file == Fprogram) {+ readprogram(r);
+ return;
+ }
+
+ respond(r, Efilenotfound);
+}
+
+void
+fswrite(Req *r)
+{+ if (r->fid->file == Fctl) {+ writectl(r);
+ return;
+ }
+ if (r->fid->file == Fprogram) {+ writeprogram(r);
+ return;
+ }
+ respond(r, Efilenotfound);
+}
+
+Srv fs = {+ .read = fsread,
+ .write = fswrite,
+};
+
+void
+initfiles(void)
+{+ Fctl = createfile(fs.tree->root, "ctl", "none", 0666, nil);
+ Fprogram = createfile(fs.tree->root, "program", "none", 0666, nil);
+}
+
+void
+threadmain(int argc, char **argv)
+{+ ARGBEGIN{+ case 's':
+ srvname = EARGF(usage());
+ break;
+ case 'm':
+ mtpt = EARGF(usage());
+ break;
+ }ARGEND;
+
+ if (argc != 1)
+ usage();
+
+ devicefile = argv[0];
+
+ chan = chancreate(sizeof(int), 1);
+ if (!initmachine(devicefile, chan))
+ sysfatal("initmachine: %r");+ proccreate(machineloop, chan, 8192);
+
+ program.data = malloc(1024);
+ program.pc = program.data;
+ program.size = 0;
+
+ fs.tree = alloctree(nil, nil, DMDIR|0775, nil);
+ initfiles();
+
+ threadpostmountsrv(&fs, srvname, mtpt, MREPL|MCREATE);
+ exits(nil);
+}
--
⑨