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);
+}