Compare commits
2 commits
c1b08412cf
...
d2749e7404
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2749e7404 | ||
|
|
f24ca1a5c7 |
2 changed files with 329 additions and 121 deletions
185
d3d.py
185
d3d.py
|
|
@ -1,9 +1,184 @@
|
||||||
#! /usr/bin/python3
|
#! /usr/bin/python3
|
||||||
import os, sys, os.path, time
|
import os, sys, os.path, time, math
|
||||||
os.chdir(os.path.dirname(sys.argv[0]))
|
os.chdir(os.path.dirname(sys.argv[0]))
|
||||||
os.system("screen ./d3d.rc")
|
os.system("screen ./d3d.rc")
|
||||||
wd = open("d3d/irena-live", "w")
|
|
||||||
|
class watchdog:
|
||||||
|
period = 60
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.wd = open("d3d/irena-live", "w")
|
||||||
|
self.time = time.time() + self.period
|
||||||
|
|
||||||
|
def due(self):
|
||||||
|
return time.time() >= self.time
|
||||||
|
|
||||||
|
def kick(self):
|
||||||
|
self.wd.write(".");
|
||||||
|
self.wd.flush()
|
||||||
|
self.time += self.period
|
||||||
|
|
||||||
|
dog = watchdog()
|
||||||
|
|
||||||
|
from led import LED
|
||||||
|
Rate_LED = LED("/var/run/gpio/Rate_LED")
|
||||||
|
Error_LED = LED("/var/run/gpio/Error_LED")
|
||||||
|
|
||||||
|
class parse_status:
|
||||||
|
|
||||||
|
"parse the lines of the `irena-status` file"
|
||||||
|
|
||||||
|
verbosity = 1
|
||||||
|
|
||||||
|
def __init__(self, lines):
|
||||||
|
self.hosttime = time.time()
|
||||||
|
self.parse(lines)
|
||||||
|
|
||||||
|
def parse(self, lines):
|
||||||
|
rates = False
|
||||||
|
self.states = {}
|
||||||
|
self.rates = {}
|
||||||
|
for l in lines:
|
||||||
|
ll = l.split()
|
||||||
|
if ll[0]=="irena":
|
||||||
|
self.version = ll[2]
|
||||||
|
self.time=int(ll[4])
|
||||||
|
fhosttime = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(self.hosttime))
|
||||||
|
if verbosity >= 1:
|
||||||
|
print(f"Host time {fhosttime}, Status time {ll[5]}")
|
||||||
|
if ll[0]=="data":
|
||||||
|
rates = True
|
||||||
|
if not l[0].isdigit():
|
||||||
|
continue
|
||||||
|
if not rates:
|
||||||
|
self.rates[ll[1]] = parse_state(ll)
|
||||||
|
else:
|
||||||
|
self.rate[ll[1]] = parse_rate(ll)
|
||||||
|
|
||||||
|
max_age = 300
|
||||||
|
|
||||||
|
def old(self):
|
||||||
|
return self.time + self.max_age < self.hosttime
|
||||||
|
|
||||||
|
def analyse(self):
|
||||||
|
"Try to identify failure modes and lauch mitigations"
|
||||||
|
pass
|
||||||
|
|
||||||
|
def set_Rate(self, LED):
|
||||||
|
"Set the green LED frequency based on trigger rate"
|
||||||
|
r = self["T_rate"].value.percent()
|
||||||
|
r = max(0, min(100, r))
|
||||||
|
f = log(r+1)/log(100)*4+0.1
|
||||||
|
LED.sine_freq(f)
|
||||||
|
|
||||||
|
def set_ERROR(self, LED):
|
||||||
|
"Set the yellow LED based on warning or error status counts"
|
||||||
|
ne = 0
|
||||||
|
nw = 0
|
||||||
|
for s in self.status:
|
||||||
|
if not s.is_ok():
|
||||||
|
if s.is_warn():
|
||||||
|
nw += 1
|
||||||
|
else:
|
||||||
|
ne += 1
|
||||||
|
if ne:
|
||||||
|
LED.blink_freq(10 - min(ne,19)/2)
|
||||||
|
elif nw:
|
||||||
|
LED.on(amp = 20*min(5,nw))
|
||||||
|
else:
|
||||||
|
LED.off()
|
||||||
|
|
||||||
|
class parse_state:
|
||||||
|
def __init__(self, ll):
|
||||||
|
self.ix = int(ll[0])
|
||||||
|
self.name = ll[1]
|
||||||
|
self.value = float(ll[2])
|
||||||
|
self.mean = float(ll[3])
|
||||||
|
self.units = ll[4]
|
||||||
|
self.age = int(ll[5])
|
||||||
|
self.status = ll[6]
|
||||||
|
self.reset = int(ll[7])
|
||||||
|
self.limits = list(map(float, ll[8:]))
|
||||||
|
if !self.is_ok() and verbosity>=1:
|
||||||
|
print(self)
|
||||||
|
|
||||||
|
def is_ok(self):
|
||||||
|
return self.status == "OK"
|
||||||
|
|
||||||
|
def is_warn(self):
|
||||||
|
return self.status == "WARN"
|
||||||
|
|
||||||
|
def is_error(self):
|
||||||
|
return self.status == "ERROR"
|
||||||
|
|
||||||
|
def percent(self):
|
||||||
|
return 100*(self.value - self.limits[1])/(self.limits[2]-self.limits[1])
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return " ".join([f"{self.name}:",
|
||||||
|
f"{self.mean} {self.units}",
|
||||||
|
f"{self.status}",
|
||||||
|
f"{self.percent():.1f} %",
|
||||||
|
])
|
||||||
|
|
||||||
|
class parse_rate:
|
||||||
|
|
||||||
|
def __init__(self, ll):
|
||||||
|
self.ix = int(ll[0])
|
||||||
|
self.name = ll[1]
|
||||||
|
self.alloc_per_sec = int(ll[2])
|
||||||
|
self.alloc_bytes = int(ll[3])
|
||||||
|
self.used_percent = float(ll[4])
|
||||||
|
self.used_bytes = int(ll[5])
|
||||||
|
self.dropped_percent = float(ll[6])
|
||||||
|
self.dropped_bytes = int(ll[7])
|
||||||
|
self.burst = int(ll[8])
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return " ".join([f"{self.name}:",
|
||||||
|
f"{self.alloc_per_sec}/s,",
|
||||||
|
f"used: {self.used_percent:.1f} %,",
|
||||||
|
f"dropped: {self.dropped_percent:.1f} %",
|
||||||
|
])
|
||||||
|
|
||||||
|
def restart_irena():
|
||||||
|
pass
|
||||||
|
|
||||||
|
last_status = 0
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
wd.write(".");
|
|
||||||
wd.flush()
|
t = time.time()
|
||||||
time.sleep(10)
|
t0 = t+10
|
||||||
|
t1 = Rate_LED.update()
|
||||||
|
t2 = Rate_LED.update()
|
||||||
|
dt = t-min(t1,t2,t3)
|
||||||
|
if dt>0:
|
||||||
|
time.sleep(dt)
|
||||||
|
|
||||||
|
if t > last_status + 10:
|
||||||
|
try:
|
||||||
|
with open("d3d/irena-status") as st:
|
||||||
|
status=parse_status(st.readlines(hint=0x2000))
|
||||||
|
except Exception as e:
|
||||||
|
if verbosity >= 0:
|
||||||
|
print(repr(e))
|
||||||
|
continue
|
||||||
|
|
||||||
|
if last_status != status.time:
|
||||||
|
status.analyse()
|
||||||
|
status.set_Rate(Rate_LED)
|
||||||
|
status.set_Error(Error_LED)
|
||||||
|
|
||||||
|
last_status = status.time
|
||||||
|
|
||||||
|
if not dog.due():
|
||||||
|
continue
|
||||||
|
|
||||||
|
if status.old():
|
||||||
|
restart_irena()
|
||||||
|
if verbosity >= 0:
|
||||||
|
print(f"not kicking the dog because status is {status.hosttime - status.time} s old")
|
||||||
|
continue
|
||||||
|
|
||||||
|
dog.kick()
|
||||||
|
|
|
||||||
253
irena.c
253
irena.c
|
|
@ -28,37 +28,71 @@ const char version[] = IRENA_VERSION;
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
FILE *mout;
|
FILE *mout;
|
||||||
|
|
||||||
int maintainance = 0;
|
int maintainance = 0;
|
||||||
int verbosity[2] = {1,1};
|
int verbosity[2] = {1,1};
|
||||||
int in_prompt;
|
int in_prompt;
|
||||||
|
const char *prompt;
|
||||||
|
|
||||||
void check_prompt()
|
void check_prompt()
|
||||||
{
|
{
|
||||||
if (in_prompt==1) {
|
if (in_prompt==1) {
|
||||||
fprintf(mout, "\n");
|
fprintf(stderr, "\r\e[K");
|
||||||
in_prompt = 2;
|
in_prompt = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void restore_prompt()
|
||||||
|
{
|
||||||
|
if (in_prompt != 2)
|
||||||
|
return;
|
||||||
|
in_prompt = 1;
|
||||||
|
// int nread;
|
||||||
|
// TIOCINQ/FIONREAD returns what is available to read immediately,
|
||||||
|
// not the contents of the incomplete line. Not usefull!
|
||||||
|
// Inject a CR, read the line, reinject all those characters?
|
||||||
|
// if (ioctl(0, TIOCINQ, &nread))
|
||||||
|
// do not call merror()!
|
||||||
|
// return;
|
||||||
|
if (prompt) {
|
||||||
|
fprintf(stderr, "%s…(^R)…", prompt);
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
if (0) {
|
||||||
|
char rprnt = 'R' & 0x1f;
|
||||||
|
ioctl(0, TIOCSTI, &rprnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void silent(int v) { if (verbosity[0] < v) verbosity[1] = 0; }
|
static inline void silent(int v) { if (verbosity[0] < v) verbosity[1] = 0; }
|
||||||
static inline void unsilent() { verbosity[1] = verbosity[0]; }
|
static inline void unsilent() { verbosity[1] = verbosity[0]; }
|
||||||
static inline void loud(int v) { if (v > verbosity[0]) verbosity[1] = v; }
|
static inline void loud(int v) { if (v > verbosity[0]) verbosity[1] = v; }
|
||||||
static inline int verbose(int v) { v = verbosity[1] >= v; unsilent(); if (v) check_prompt(); return v; }
|
static inline int verbose(int v) { v = verbosity[1] >= v; unsilent(); if (v) check_prompt(); return v; }
|
||||||
|
static inline void unverbose() { restore_prompt(); }
|
||||||
|
|
||||||
|
int mprintf(int v, const char *restrict format, ...)
|
||||||
|
{
|
||||||
|
if (!verbose(v)) return 0;
|
||||||
|
va_list ap;
|
||||||
|
va_start (ap, format);
|
||||||
|
int r = vfprintf(mout, format, ap);
|
||||||
|
unverbose();
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
// replacement for perror()
|
// replacement for perror()
|
||||||
void merror(const char *s)
|
void merror(const char *s)
|
||||||
{
|
{
|
||||||
int e = errno;
|
int e = errno;
|
||||||
if (verbose(-1))
|
mprintf(-1, "%s: %s\n", s, strerror(e));
|
||||||
fprintf(mout, "%s: %s\n", s, strerror(e));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEBUG 3
|
#define DEBUG 3
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
# define debug(fmt, ...) if (verbose(DEBUG)) fprintf(mout, fmt, __VA_ARGS__)
|
# define debug(fmt, ...) mprintf(DEBUG, fmt, __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
# define debug(fmt, ...)
|
# define debug(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -207,13 +241,10 @@ void file_close(struct file_format *ff)
|
||||||
if (rename(ff->filename, fn))
|
if (rename(ff->filename, fn))
|
||||||
merror(ff->filename);
|
merror(ff->filename);
|
||||||
}
|
}
|
||||||
if (verbose(2))
|
mprintf(2, "closed and renamed «%s» to «%s»\n", ff->filename, fn);
|
||||||
fprintf(mout, "closed and renamed «%s» to «%s»\n", ff->filename, fn);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (verbose(2))
|
|
||||||
fprintf(mout, "closed file «%s»\n", ff->filename);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mprintf(2, "closed file «%s»\n", ff->filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_open(struct file_format *ff, time_t t)
|
void file_open(struct file_format *ff, time_t t)
|
||||||
|
|
@ -236,7 +267,7 @@ void file_open(struct file_format *ff, time_t t)
|
||||||
}
|
}
|
||||||
if (!strcmp(ff->filename, "stderr")) {
|
if (!strcmp(ff->filename, "stderr")) {
|
||||||
if (!(ff->flags & FILE_STDIO)) {
|
if (!(ff->flags & FILE_STDIO)) {
|
||||||
fprintf(mout, "cannot use write() on «stderr»\n");
|
mprintf(-1, "cannot use write() on «stderr»\n");
|
||||||
ff->flags |= FILE_ERROR;
|
ff->flags |= FILE_ERROR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -248,9 +279,7 @@ void file_open(struct file_format *ff, time_t t)
|
||||||
char *mode = ff->flags&FILE_APPEND ? "a" : "w";
|
char *mode = ff->flags&FILE_APPEND ? "a" : "w";
|
||||||
ff->f = fopen(ff->filename, mode);
|
ff->f = fopen(ff->filename, mode);
|
||||||
if (ff->f) {
|
if (ff->f) {
|
||||||
if (verbose(2))
|
mprintf(2, "fopen(%s, %s)\n", ff->filename, mode);
|
||||||
fprintf(mout, "fopen(%s, %s)\n",
|
|
||||||
ff->filename, mode);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -260,8 +289,7 @@ void file_open(struct file_format *ff, time_t t)
|
||||||
f = O_CREAT|O_WRONLY|O_TRUNC;
|
f = O_CREAT|O_WRONLY|O_TRUNC;
|
||||||
ff->fd = open(ff->filename, f, 0664);
|
ff->fd = open(ff->filename, f, 0664);
|
||||||
if (ff->fd>=0) {
|
if (ff->fd>=0) {
|
||||||
if (verbose(2))
|
mprintf(2, "open(%s)\n", ff->filename);
|
||||||
fprintf(mout, "open(%s)\n", ff->filename);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -300,7 +328,7 @@ int config_file(struct file_format *f, int na, char **av)
|
||||||
int do_close = 0;
|
int do_close = 0;
|
||||||
int do_open = 0;
|
int do_open = 0;
|
||||||
if (na<1 || na>5) {
|
if (na<1 || na>5) {
|
||||||
fprintf(mout,
|
mprintf(-2,
|
||||||
"usage: %s [«strftime» [«rotate» [«modulus» [«flags»]]]] [close|rotate]\n"
|
"usage: %s [«strftime» [«rotate» [«modulus» [«flags»]]]] [close|rotate]\n"
|
||||||
"- «strftime»: filename strftime format | stdout | stderr\n"
|
"- «strftime»: filename strftime format | stdout | stderr\n"
|
||||||
"- «rotate»: rotation interval, seconds (-1 for no change)\n"
|
"- «rotate»: rotation interval, seconds (-1 for no change)\n"
|
||||||
|
|
@ -342,7 +370,7 @@ int config_file(struct file_format *f, int na, char **av)
|
||||||
if (flags & FILE_STDOUT) fnf = "stdout";
|
if (flags & FILE_STDOUT) fnf = "stdout";
|
||||||
}
|
}
|
||||||
if (strlen(fnf) > MAX_FN-2) {
|
if (strlen(fnf) > MAX_FN-2) {
|
||||||
fprintf(mout, "filename format too long (>%d): %s\n", MAX_FN-2, fnf);
|
mprintf(-2, "filename format too long (>%d): %s\n", MAX_FN-2, fnf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
strncpy(f->format, fnf, MAX_FN-1);
|
strncpy(f->format, fnf, MAX_FN-1);
|
||||||
|
|
@ -354,7 +382,7 @@ int config_file(struct file_format *f, int na, char **av)
|
||||||
else if (do_open)
|
else if (do_open)
|
||||||
file_open(f, 0);
|
file_open(f, 0);
|
||||||
int io = is_open(f);
|
int io = is_open(f);
|
||||||
fprintf(mout, "%s '%s' %d %d 0x%x '%s'\n",
|
mprintf(-2, "%s '%s' %d %d 0x%x '%s'\n",
|
||||||
av[0], f->format, f->rotate, f->rotate_modulus, f->flags,
|
av[0], f->format, f->rotate, f->rotate_modulus, f->flags,
|
||||||
io ? f->filename : "CLOSED");
|
io ? f->filename : "CLOSED");
|
||||||
return io;
|
return io;
|
||||||
|
|
@ -582,7 +610,7 @@ int config_priority(int na, char **av)
|
||||||
na--;
|
na--;
|
||||||
}
|
}
|
||||||
if (na<2 || na>6) {
|
if (na<2 || na>6) {
|
||||||
fprintf(mout,
|
mprintf(-2,
|
||||||
"usage: %s [«index» [«rate» [«inst» [«burst» [«flags»]]]]] [global] [reset]\n"
|
"usage: %s [«index» [«rate» [«inst» [«burst» [«flags»]]]]] [global] [reset]\n"
|
||||||
"- configure data rate limits\n"
|
"- configure data rate limits\n"
|
||||||
"- «index»: 0…%d: table index\n"
|
"- «index»: 0…%d: table index\n"
|
||||||
|
|
@ -604,7 +632,7 @@ int config_priority(int na, char **av)
|
||||||
|| number(av[1], &index))
|
|| number(av[1], &index))
|
||||||
return -1;
|
return -1;
|
||||||
if (index<0 || index>=NPRIO) {
|
if (index<0 || index>=NPRIO) {
|
||||||
fprintf(mout, "rate index %d out of range 0…%d\n",
|
mprintf(-2, "rate index %d out of range 0…%d\n",
|
||||||
index, NPRIO-1);
|
index, NPRIO-1);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -614,7 +642,7 @@ int config_priority(int na, char **av)
|
||||||
if (burst >= 0) ep->inst_burst = burst;
|
if (burst >= 0) ep->inst_burst = burst;
|
||||||
if (flags != -1) ep->flags = flags;
|
if (flags != -1) ep->flags = flags;
|
||||||
flags |= fflags;
|
flags |= fflags;
|
||||||
fprintf(mout, "%s: %s %u %u %u %u 0x%x -> %llu(%llu)/%llu %u/%u\n",
|
mprintf(-2, "%s: %s %u %u %u %u 0x%x -> %llu(%llu)/%llu %u/%u\n",
|
||||||
ep->name, av[0], index, ep->rate, ep->inst_rate, ep->inst_burst, ep->flags,
|
ep->name, av[0], index, ep->rate, ep->inst_rate, ep->inst_burst, ep->flags,
|
||||||
ep->sent, ep->dropped, ep->allowed, ep->inst_sent, ep->inst_burst);
|
ep->sent, ep->dropped, ep->allowed, ep->inst_sent, ep->inst_burst);
|
||||||
if (do_reset)
|
if (do_reset)
|
||||||
|
|
@ -950,7 +978,7 @@ void print_status(FILE *f, time_t t)
|
||||||
did_reset = 1;
|
did_reset = 1;
|
||||||
tried_reset = 1;
|
tried_reset = 1;
|
||||||
if (did_reset) {
|
if (did_reset) {
|
||||||
fprintf(mout, "IRENA ARM RESET SENT %s = %-.*f exceeds (%g, %g)\n",
|
mprintf(-2, "IRENA ARM RESET SENT %s = %-.*f exceeds (%g, %g)\n",
|
||||||
st->name, st->digits, mean, st->limits[0], st->limits[3]);
|
st->name, st->digits, mean, st->limits[0], st->limits[3]);
|
||||||
st->did_reset = t;
|
st->did_reset = t;
|
||||||
last_status_reset = t;
|
last_status_reset = t;
|
||||||
|
|
@ -971,11 +999,14 @@ void print_status(FILE *f, time_t t)
|
||||||
int config_status(int na, char **av)
|
int config_status(int na, char **av)
|
||||||
{
|
{
|
||||||
if (na==1) {
|
if (na==1) {
|
||||||
|
if (verbose(-2)) {
|
||||||
print_status(mout, 0);
|
print_status(mout, 0);
|
||||||
|
unverbose();
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (na!=2 && (na<6 || na>9)) {
|
if (na!=2 && (na<6 || na>9)) {
|
||||||
fprintf(mout,
|
mprintf(-2,
|
||||||
"usage: %s [«index» [«red» «yellow» «yellow» «red» [«tau» [«reset»] [«flags»]]]]\n"
|
"usage: %s [«index» [«red» «yellow» «yellow» «red» [«tau» [«reset»] [«flags»]]]]\n"
|
||||||
"- «index»: 0…%d, table index\n"
|
"- «index»: 0…%d, table index\n"
|
||||||
"- «red»: lower/upper error limit\n"
|
"- «red»: lower/upper error limit\n"
|
||||||
|
|
@ -998,7 +1029,7 @@ int config_status(int na, char **av)
|
||||||
if (number(av[1], &index))
|
if (number(av[1], &index))
|
||||||
return -1;
|
return -1;
|
||||||
if (index<0 || index>=NSTAT) {
|
if (index<0 || index>=NSTAT) {
|
||||||
fprintf(mout, "limits index %d out of range 0…%d\n",
|
mprintf(-2, "limits index %d out of range 0…%d\n",
|
||||||
index, NSTAT-1);
|
index, NSTAT-1);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -1027,7 +1058,7 @@ int config_status(int na, char **av)
|
||||||
else
|
else
|
||||||
st->flags |= ST_DO_RESET;
|
st->flags |= ST_DO_RESET;
|
||||||
else
|
else
|
||||||
fprintf(mout, "%s … «reset» = reset | noreset | «seconds»\n", av[0]);
|
mprintf(-2, "%s … «reset» = reset | noreset | «seconds»\n", av[0]);
|
||||||
if (na>=9) {
|
if (na>=9) {
|
||||||
int f;
|
int f;
|
||||||
if (!number(av[8], &f)) {
|
if (!number(av[8], &f)) {
|
||||||
|
|
@ -1036,7 +1067,7 @@ int config_status(int na, char **av)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(mout, "%s %s[%u] %g %g %g %g %s tau %d reset %d flags 0x%04x\n",
|
mprintf(-2, "%s %s[%u] %g %g %g %g %s tau %d reset %d flags 0x%04x\n",
|
||||||
av[0], st->name, index,
|
av[0], st->name, index,
|
||||||
st->limits[0], st->limits[1], st->limits[2], st->limits[3],
|
st->limits[0], st->limits[1], st->limits[2], st->limits[3],
|
||||||
st->units, st->tau, st->reset_delay, st->flags);
|
st->units, st->tau, st->reset_delay, st->flags);
|
||||||
|
|
@ -1197,8 +1228,7 @@ int arm_reset()
|
||||||
arm_reset_uart(i_buf.fd, reset_flags);
|
arm_reset_uart(i_buf.fd, reset_flags);
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
if (verbose(0))
|
mprintf(0, "Sent hardware RESET, mode %d\n", reset_flags);
|
||||||
fprintf(mout, "Sent hardware RESET, mode %d\n", reset_flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1282,18 +1312,18 @@ int test_serial_read_buffer(int na, char **av)
|
||||||
{
|
{
|
||||||
int s = 1;
|
int s = 1;
|
||||||
if (na>=2 && number(av[1], &s)) {
|
if (na>=2 && number(av[1], &s)) {
|
||||||
fprintf(mout, "usage: %s [«seconds»]\n", av[0]);
|
mprintf(-2, "usage: %s [«seconds»]\n", av[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (i_buf.fd<0) {
|
if (i_buf.fd<0) {
|
||||||
|
mprintf(-2, "uart is closed\n");
|
||||||
return -1;
|
return -1;
|
||||||
fprintf(mout, "uart is closed\n");
|
|
||||||
}
|
}
|
||||||
buffer_reset(&i_buf);
|
buffer_reset(&i_buf);
|
||||||
sleep(s);
|
sleep(s);
|
||||||
char buf[65536];
|
char buf[65536];
|
||||||
int n = read(i_buf.fd, &buf, sizeof(buf)-1);
|
int n = read(i_buf.fd, &buf, sizeof(buf)-1);
|
||||||
fprintf(mout, "uart read buffer size >= %d\n", n);
|
mprintf(-2, "uart read buffer size >= %d\n", n);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1328,8 +1358,7 @@ int base64_decode(const char *l, unsigned char *b, size_t n)
|
||||||
else if (!i && (!c || c=='\n'))
|
else if (!i && (!c || c=='\n'))
|
||||||
return m;
|
return m;
|
||||||
else if (c&0x80 || !bb[i] && c!='A') {
|
else if (c&0x80 || !bb[i] && c!='A') {
|
||||||
if (verbose(0))
|
mprintf(0, "Base64 format error: %s\n", l);
|
||||||
fprintf(mout, "Base64 format error: %s\n", l);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1394,8 +1423,8 @@ int base85_decode(const char *l, unsigned char *b, size_t n)
|
||||||
l++;
|
l++;
|
||||||
int ll = base85_decode1(l, (unsigned int*)(b+m));
|
int ll = base85_decode1(l, (unsigned int*)(b+m));
|
||||||
if (!ll) {
|
if (!ll) {
|
||||||
if (*l && verbose(0))
|
if (*l)
|
||||||
fprintf(mout, "invalid base85: «%s»\n", l);
|
mprintf(0, "invalid base85: «%s»\n", l);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
l += ll;
|
l += ll;
|
||||||
|
|
@ -2158,23 +2187,21 @@ int send_irena_command(const char *c)
|
||||||
{
|
{
|
||||||
static int no_uart;
|
static int no_uart;
|
||||||
if (i_buf.fd <= 0) {
|
if (i_buf.fd <= 0) {
|
||||||
if (!no_uart && verbose(-1))
|
if (!no_uart)
|
||||||
fprintf(mout, "irena: no uart: %s\n", c);
|
mprintf(-1, "irena: no uart: %s\n", c);
|
||||||
no_uart++;
|
no_uart++;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
no_uart=0;
|
no_uart=0;
|
||||||
time_t t = time(0);
|
time_t t = time(0);
|
||||||
if (last_irena_command_sent+1 >= t) {
|
if (last_irena_command_sent+1 >= t) {
|
||||||
if (verbose(3))
|
mprintf(3, "IRENA CMD postponed: %s\n", c);
|
||||||
fprintf(mout, "IRENA CMD postponed: %s\n", c);
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
size_t sl = strlen(c);
|
size_t sl = strlen(c);
|
||||||
int n = write(i_buf.fd, c, sl);
|
int n = write(i_buf.fd, c, sl);
|
||||||
last_irena_command_sent = t;
|
last_irena_command_sent = t;
|
||||||
if (verbose(2))
|
mprintf(2, "IRENA CMD sent: «%s»\n", c);
|
||||||
fprintf(mout, "IRENA CMD sent: «%s»\n", c);
|
|
||||||
if (n==sl)
|
if (n==sl)
|
||||||
n += write(i_buf.fd, "\n", 1);
|
n += write(i_buf.fd, "\n", 1);
|
||||||
if (n != sl+1)
|
if (n != sl+1)
|
||||||
|
|
@ -2183,8 +2210,7 @@ int send_irena_command(const char *c)
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (verbose(-1))
|
mprintf(-1, "incomplete write: %d/%lu %s\n", n, strlen(c), c);
|
||||||
fprintf(mout, "incomplete write: %d/%lu %s\n", n, strlen(c), c);
|
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -2235,6 +2261,8 @@ void send_fct(time_t t)
|
||||||
void process_line(const char *l)
|
void process_line(const char *l)
|
||||||
{
|
{
|
||||||
// ack a sent command when we see the response
|
// ack a sent command when we see the response
|
||||||
|
if (!*l)
|
||||||
|
return;
|
||||||
if (*l=='.' || *l=='m')
|
if (*l=='.' || *l=='m')
|
||||||
last_irena_command_sent = 0;
|
last_irena_command_sent = 0;
|
||||||
int fmt = 0;
|
int fmt = 0;
|
||||||
|
|
@ -2243,19 +2271,16 @@ void process_line(const char *l)
|
||||||
if (fmt) {
|
if (fmt) {
|
||||||
fct_got_data++;
|
fct_got_data++;
|
||||||
fct_packets++;
|
fct_packets++;
|
||||||
if (verbose(3))
|
mprintf(3, "DATA received: «%s»\n", l);
|
||||||
fprintf(mout, "DATA received: «%s»\n", l);
|
|
||||||
process_base64(fmt, l+5);
|
process_base64(fmt, l+5);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (*l && !strncmp(l+1, "FCT ", 4)) {
|
if (*l && !strncmp(l+1, "FCT ", 4)) {
|
||||||
fct_ack++;
|
fct_ack++;
|
||||||
if (verbose(4))
|
mprintf(4, "FCT ACK received %d, «%s»\n", fct_ack, l);
|
||||||
fprintf(mout, "FCT ACK received %d, «%s»\n", fct_ack, l);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (verbose(1))
|
mprintf(1, "IRENA: %s\n", l);
|
||||||
fprintf(mout, "IRENA: %s\n", l);
|
|
||||||
eprintf(EP_M, "I %s\n", l);
|
eprintf(EP_M, "I %s\n", l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2331,14 +2356,12 @@ int send_file(const char *fn, const char *cfmt, unsigned int drop)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (i >= 2) {
|
if (i >= 2) {
|
||||||
if (verbose(-1))
|
mprintf(-1, "more than two in parameters «%s»\n", cfmt);
|
||||||
fprintf(mout, "more than two in parameters «%s»\n", cfmt);
|
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
while (index(".-+#0123456789", *s)) s++;
|
while (index(".-+#0123456789", *s)) s++;
|
||||||
if (!*s || !index("diuoOxX", *s)) {
|
if (!*s || !index("diuoOxX", *s)) {
|
||||||
if (verbose(-1))
|
mprintf(-1, "invalid format «%s»\n", cfmt);
|
||||||
fprintf(mout, "invalid format «%s»\n", cfmt);
|
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
|
@ -2360,8 +2383,7 @@ int send_file(const char *fn, const char *cfmt, unsigned int drop)
|
||||||
int d = 1;
|
int d = 1;
|
||||||
if (drop) while (d<128 && buf[d]==buf[0]) d++;
|
if (drop) while (d<128 && buf[d]==buf[0]) d++;
|
||||||
if (d>=128 && buf[0]==0xffffffff) {
|
if (d>=128 && buf[0]==0xffffffff) {
|
||||||
if (verbose(2))
|
mprintf(2, "dropping block %d\n", a/128);
|
||||||
fprintf(mout, "dropping block %d\n", a/128);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (int i=0; i<128; ) {
|
for (int i=0; i<128; ) {
|
||||||
|
|
@ -2376,9 +2398,9 @@ int send_file(const char *fn, const char *cfmt, unsigned int drop)
|
||||||
poll_uart(1);
|
poll_uart(1);
|
||||||
char *res = poll_response(2);
|
char *res = poll_response(2);
|
||||||
if (!res)
|
if (!res)
|
||||||
fprintf(mout, "timeout for cmd «%s»\n", cmd);
|
mprintf(-2, "timeout for cmd «%s»\n", cmd);
|
||||||
else if (strncmp(res+1, "303", 3))
|
else if (strncmp(res+1, "303", 3))
|
||||||
fprintf(mout, "invalid response to «%s» → «%s»\n", cmd, res);
|
mprintf(-2, "invalid response to «%s» → «%s»\n", cmd, res);
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
poll_uart(0);
|
poll_uart(0);
|
||||||
|
|
@ -2392,8 +2414,8 @@ int send_file(const char *fn, const char *cfmt, unsigned int drop)
|
||||||
int cs = snprintf(cmd, 128, cfmt, a, n);
|
int cs = snprintf(cmd, 128, cfmt, a, n);
|
||||||
if (cs <= 127)
|
if (cs <= 127)
|
||||||
process_cmd(cmd);
|
process_cmd(cmd);
|
||||||
else if (verbose(-1))
|
else
|
||||||
fprintf(mout, "sendfile format too long «%s»\n", cmd);
|
mprintf(-1, "sendfile format too long «%s»\n", cmd);
|
||||||
}
|
}
|
||||||
do_cron(0, CR_BUFFER, 1);
|
do_cron(0, CR_BUFFER, 1);
|
||||||
a += n;
|
a += n;
|
||||||
|
|
@ -2417,8 +2439,7 @@ int set_clock(int do_sleep)
|
||||||
while (ts.tv_nsec < 900000000) {
|
while (ts.tv_nsec < 900000000) {
|
||||||
ts.tv_nsec += 50000000;
|
ts.tv_nsec += 50000000;
|
||||||
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &ts, 0);
|
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &ts, 0);
|
||||||
if (verbose(3))
|
mprintf(3, "slept 50ms ns=%lu\n", ts.tv_nsec);
|
||||||
fprintf(mout, "slept 50ms ns=%lu\n", ts.tv_nsec);
|
|
||||||
poll_uart(1);
|
poll_uart(1);
|
||||||
clock_gettime(CLOCK_REALTIME, &ts);
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
}
|
}
|
||||||
|
|
@ -2495,8 +2516,7 @@ const char *cmd_socket_name() {
|
||||||
int close_cmd_socket()
|
int close_cmd_socket()
|
||||||
{
|
{
|
||||||
if (cmd_socket_fd >= 0) {
|
if (cmd_socket_fd >= 0) {
|
||||||
if (verbose(1))
|
mprintf(1, "closing cmd socket: «%s»\n", cmd_socket_name());
|
||||||
fprintf(mout, "closing cmd socket: «%s»\n", cmd_socket_name());
|
|
||||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, cmd_socket_fd, 0);
|
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, cmd_socket_fd, 0);
|
||||||
close(cmd_socket_fd);
|
close(cmd_socket_fd);
|
||||||
cmd_socket_fd = -1;
|
cmd_socket_fd = -1;
|
||||||
|
|
@ -2566,17 +2586,20 @@ int open_cmd_socket(int na, char **av)
|
||||||
cmd_socket_addr.u.sun_family = AF_UNIX;
|
cmd_socket_addr.u.sun_family = AF_UNIX;
|
||||||
strncpy(cmd_socket_addr.u.sun_path, av[na-1], sizeof(cmd_socket_addr.u.sun_path)-1);
|
strncpy(cmd_socket_addr.u.sun_path, av[na-1], sizeof(cmd_socket_addr.u.sun_path)-1);
|
||||||
if (force && !unlink(cmd_socket_addr.u.sun_path))
|
if (force && !unlink(cmd_socket_addr.u.sun_path))
|
||||||
fprintf(mout, "socket «%s» unlinked\n", cmd_socket_addr.u.sun_path);
|
mprintf(-2, "socket «%s» unlinked\n", cmd_socket_addr.u.sun_path);
|
||||||
}
|
}
|
||||||
else if (na==1) {
|
else if (na==1) {
|
||||||
is_open:
|
is_open:
|
||||||
|
if (verbose(-1)) {
|
||||||
fprintf(mout, "command socket is %s«%s»\n", mode, cmd_socket_name());
|
fprintf(mout, "command socket is %s«%s»\n", mode, cmd_socket_name());
|
||||||
print_asocket(mout);
|
print_asocket(mout);
|
||||||
|
unverbose();
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
usage:
|
usage:
|
||||||
fprintf(mout,
|
mprintf(-2,
|
||||||
"usage: %s [unix «path» | tcp «port»]"
|
"usage: %s [unix «path» | tcp «port»]"
|
||||||
" [interactive|noninteractive] [close]\n", av[0]);
|
" [interactive|noninteractive] [close]\n", av[0]);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -2608,7 +2631,7 @@ int open_cmd_socket(int na, char **av)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(mout, "opened %ssocket «%s»\n", mode, cmd_socket_name());
|
mprintf(-2, "opened %ssocket «%s»\n", mode, cmd_socket_name());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2624,7 +2647,7 @@ int accept_cmd_socket(int fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_buf.fd >= 0) {
|
if (s_buf.fd >= 0) {
|
||||||
fprintf(mout, "command socket busy\n");
|
mprintf(-2, "command socket busy\n");
|
||||||
close(sfd);
|
close(sfd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -2652,11 +2675,13 @@ int accept_cmd_socket(int fd)
|
||||||
return sfd;
|
return sfd;
|
||||||
}
|
}
|
||||||
cmd_socket_flags |= SOCK_IS_MOUT;
|
cmd_socket_flags |= SOCK_IS_MOUT;
|
||||||
fprintf(mout, "irena %s\n", version);
|
mprintf(-2, "irena %s\n", version);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose(0))
|
if (verbose(0)) {
|
||||||
print_asocket(stderr);
|
print_asocket(stderr);
|
||||||
|
unverbose();
|
||||||
|
}
|
||||||
|
|
||||||
return sfd;
|
return sfd;
|
||||||
}
|
}
|
||||||
|
|
@ -2675,6 +2700,7 @@ int close_acmd_socket()
|
||||||
if (verbose(0)) {
|
if (verbose(0)) {
|
||||||
print_asocket(stderr);
|
print_asocket(stderr);
|
||||||
fprintf(stderr, "closing socket connection\n");
|
fprintf(stderr, "closing socket connection\n");
|
||||||
|
unverbose();
|
||||||
}
|
}
|
||||||
if (s_buf.fd >= 0) {
|
if (s_buf.fd >= 0) {
|
||||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, s_buf.fd, 0))
|
if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, s_buf.fd, 0))
|
||||||
|
|
@ -2694,7 +2720,7 @@ int number(char *s, int *i)
|
||||||
char *e;
|
char *e;
|
||||||
int ii = strtol(s, &e, 0);
|
int ii = strtol(s, &e, 0);
|
||||||
if (*e) {
|
if (*e) {
|
||||||
fprintf(mout, "invalid number: %s\n", s);
|
mprintf(-2, "invalid number: %s\n", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*i = ii;
|
*i = ii;
|
||||||
|
|
@ -2707,7 +2733,7 @@ int index_number(char *s, int *i)
|
||||||
char *e;
|
char *e;
|
||||||
int ii = strtol(s+1, &e, 0);
|
int ii = strtol(s+1, &e, 0);
|
||||||
if (*e != ']') {
|
if (*e != ']') {
|
||||||
fprintf(mout, "invalid index: %s\n", s);
|
mprintf(-2, "invalid index: %s\n", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*i = ii;
|
*i = ii;
|
||||||
|
|
@ -2719,7 +2745,7 @@ int float_number(char *s, double *d)
|
||||||
char *e;
|
char *e;
|
||||||
double dd = strtod(s, &e);
|
double dd = strtod(s, &e);
|
||||||
if (*e) {
|
if (*e) {
|
||||||
fprintf(mout, "invalid float number: %s\n", s);
|
mprintf(-2, "invalid float number: %s\n", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*d = dd;
|
*d = dd;
|
||||||
|
|
@ -2828,7 +2854,7 @@ int process_script(const char *fn)
|
||||||
{
|
{
|
||||||
static int recursion = 0;
|
static int recursion = 0;
|
||||||
if (recursion>10) {
|
if (recursion>10) {
|
||||||
fprintf(mout, "script: «%s»: nested too deep, limit 10\n", fn);
|
mprintf(-2, "script: «%s»: nested too deep, limit 10\n", fn);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2842,7 +2868,7 @@ int process_script(const char *fn)
|
||||||
char cmd[128];
|
char cmd[128];
|
||||||
while (fgets(cmd, sizeof(cmd), f)) {
|
while (fgets(cmd, sizeof(cmd), f)) {
|
||||||
if (!index(cmd, '\n')) {
|
if (!index(cmd, '\n')) {
|
||||||
fprintf(mout, "script: unterminated or long line: «%s»\n", cmd);
|
mprintf(-2, "script: unterminated or long line: «%s»\n", cmd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
process_cmd(cmd);
|
process_cmd(cmd);
|
||||||
|
|
@ -2863,26 +2889,27 @@ int process_cmd(char *l)
|
||||||
int na = split(l, 10, av);
|
int na = split(l, 10, av);
|
||||||
if (!na || av[0][0]=='#')
|
if (!na || av[0][0]=='#')
|
||||||
return 0;
|
return 0;
|
||||||
check_prompt();
|
if (verbose(2) || !strcmp(av[0], "echo") && verbose(-2)) {
|
||||||
if (verbose(2) || !strcmp(av[0], "echo")) {
|
|
||||||
fprintf(mout, "CMD:");
|
fprintf(mout, "CMD:");
|
||||||
for (int i=0; i<na; i++)
|
for (int i=0; i<na; i++)
|
||||||
fprintf(mout, " «%s»", av[i]);
|
fprintf(mout, " «%s»", av[i]);
|
||||||
fprintf(mout, "\n");
|
fprintf(mout, "\n");
|
||||||
|
unverbose();
|
||||||
}
|
}
|
||||||
if (!strcmp(av[0], "echo")) {
|
if (!strcmp(av[0], "echo")) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(av[0], "version")) {
|
if (!strcmp(av[0], "version")) {
|
||||||
fprintf(mout, "irena version %s\n", version);
|
mprintf(-2, "irena version %s\n", version);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int help = na>=2 && !strcmp(av[1], "help");
|
int help = na>=2 && !strcmp(av[1], "help");
|
||||||
|
|
||||||
if (!strcmp(av[0], "help")) {
|
if (!strcmp(av[0], "help")) {
|
||||||
fprintf(mout, "available commands\n"
|
if (!verbose(-2)) return 0;
|
||||||
|
mprintf(-2, "available commands\n"
|
||||||
"commands:\n"
|
"commands:\n"
|
||||||
"\thelp\n"
|
"\thelp\n"
|
||||||
"\tversion\n"
|
"\tversion\n"
|
||||||
|
|
@ -2911,10 +2938,13 @@ int process_cmd(char *l)
|
||||||
"\n"
|
"\n"
|
||||||
);
|
);
|
||||||
print_numbers(mout);
|
print_numbers(mout);
|
||||||
|
unverbose();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!strcmp(av[0], "numbers")) {
|
if (!strcmp(av[0], "numbers")) {
|
||||||
|
if (!verbose(-2)) return 0;
|
||||||
print_numbers(mout);
|
print_numbers(mout);
|
||||||
|
unverbose();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2933,9 +2963,9 @@ int process_cmd(char *l)
|
||||||
}
|
}
|
||||||
if (help || ii<0 || na+ii > nn) {
|
if (help || ii<0 || na+ii > nn) {
|
||||||
if (nn>1)
|
if (nn>1)
|
||||||
fprintf(mout, "usage: %s [[«i»]] «%s» [… %d items]\n", n->name, n->doc, nn);
|
mprintf(-2, "usage: %s [[«i»]] «%s» [… %d items]\n", n->name, n->doc, nn);
|
||||||
else
|
else
|
||||||
fprintf(mout, "usage: %s «%s»\n", n->name, n->doc);
|
mprintf(-2, "usage: %s «%s»\n", n->name, n->doc);
|
||||||
na = 0;
|
na = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2958,14 +2988,17 @@ int process_cmd(char *l)
|
||||||
if (r)
|
if (r)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (verbose(-2)) {
|
||||||
print_number(mout, n);
|
print_number(mout, n);
|
||||||
|
unverbose();
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(av[0], "exit")) {
|
if (!strcmp(av[0], "exit")) {
|
||||||
int code = 0;
|
int code = 0;
|
||||||
if (help || na>2 || na==2 && number(av[1], &code)) {
|
if (help || na>2 || na==2 && number(av[1], &code)) {
|
||||||
fprintf(mout, "usage: exit [«status»]\n");
|
mprintf(-2, "usage: exit [«status»]\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
file_close(&data_file);
|
file_close(&data_file);
|
||||||
|
|
@ -2978,7 +3011,7 @@ int process_cmd(char *l)
|
||||||
if (!strcmp(av[0], "sleep")) {
|
if (!strcmp(av[0], "sleep")) {
|
||||||
int sec;
|
int sec;
|
||||||
if (help || na!=2 || number(av[1], &sec)) {
|
if (help || na!=2 || number(av[1], &sec)) {
|
||||||
fprintf(mout, "usage: sleep «seconds»\n");
|
mprintf(-2, "usage: sleep «seconds»\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
sleep(sec);
|
sleep(sec);
|
||||||
|
|
@ -2987,7 +3020,7 @@ int process_cmd(char *l)
|
||||||
|
|
||||||
if (!strcmp(av[0], "script")) {
|
if (!strcmp(av[0], "script")) {
|
||||||
if (help || na!=2) {
|
if (help || na!=2) {
|
||||||
fprintf(mout, "usage: script «filename»\n");
|
mprintf(-2, "usage: script «filename»\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return process_script(av[1]);
|
return process_script(av[1]);
|
||||||
|
|
@ -2998,7 +3031,7 @@ int process_cmd(char *l)
|
||||||
int drop = 0;
|
int drop = 0;
|
||||||
int i = 2;
|
int i = 2;
|
||||||
if (help) {
|
if (help) {
|
||||||
fprintf(mout, "usage: sendfile [drop] «filename» [«command»]\n"
|
mprintf(-2, "usage: sendfile [drop] «filename» [«command»]\n"
|
||||||
"- send contents of «filename» as 512 Byte blocks into the flashbuffer,\n"
|
"- send contents of «filename» as 512 Byte blocks into the flashbuffer,\n"
|
||||||
"- optionally, send irena «command»,\n"
|
"- optionally, send irena «command»,\n"
|
||||||
"- execute any cron items flagged `buffer`.\n"
|
"- execute any cron items flagged `buffer`.\n"
|
||||||
|
|
@ -3036,14 +3069,14 @@ int process_cmd(char *l)
|
||||||
if (!strcmp(av[2], "1000000")) baud = B1000000;
|
if (!strcmp(av[2], "1000000")) baud = B1000000;
|
||||||
if (!strcmp(av[2], "1500000")) baud = B1500000;
|
if (!strcmp(av[2], "1500000")) baud = B1500000;
|
||||||
if (baud==B0) {
|
if (baud==B0) {
|
||||||
fprintf(mout, "uart: illegal baud rate: %s\n"
|
mprintf(-2, "uart: illegal baud rate: %s\n"
|
||||||
"valid: 9600, 38400, 57600, 115200, 921600, 1000000, 1500000\n"
|
"valid: 9600, 38400, 57600, 115200, 921600, 1000000, 1500000\n"
|
||||||
"default: 921600\n", av[2]);
|
"default: 921600\n", av[2]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (help || na<2 || na>4 || na==4 && !do_reset) {
|
if (help || na<2 || na>4 || na==4 && !do_reset) {
|
||||||
fprintf(mout,
|
mprintf(-2,
|
||||||
"usage: uart «tty» [«baudrate»] [«reset»]\n"
|
"usage: uart «tty» [«baudrate»] [«reset»]\n"
|
||||||
"- open the serial port,\n"
|
"- open the serial port,\n"
|
||||||
"- optionally reset the µC, and\n"
|
"- optionally reset the µC, and\n"
|
||||||
|
|
@ -3064,7 +3097,7 @@ int process_cmd(char *l)
|
||||||
|
|
||||||
if (!strcmp(av[0], "irena") || !strcmp(av[0],"var")) {
|
if (!strcmp(av[0], "irena") || !strcmp(av[0],"var")) {
|
||||||
if (help || na <= 1) {
|
if (help || na <= 1) {
|
||||||
fprintf(mout,
|
mprintf(-2,
|
||||||
"usage: irena «command»\n"
|
"usage: irena «command»\n"
|
||||||
"usage: var «variable command»\n"
|
"usage: var «variable command»\n"
|
||||||
" (short for `irena var «command»`)\n"
|
" (short for `irena var «command»`)\n"
|
||||||
|
|
@ -3095,7 +3128,7 @@ int process_cmd(char *l)
|
||||||
if (na>3 || na>2 && !config)
|
if (na>3 || na>2 && !config)
|
||||||
do_sleep = -1;
|
do_sleep = -1;
|
||||||
if (help || do_sleep < 0) {
|
if (help || do_sleep < 0) {
|
||||||
fprintf(mout,
|
mprintf(-2,
|
||||||
"usage: set_clock [nosleep|sleep|drift|fudge] [config]\n"
|
"usage: set_clock [nosleep|sleep|drift|fudge] [config]\n"
|
||||||
"- set the µC RTC to the current host time.\n"
|
"- set the µC RTC to the current host time.\n"
|
||||||
"option `sleep`: Wait until the end of the current second.\n"
|
"option `sleep`: Wait until the end of the current second.\n"
|
||||||
|
|
@ -3145,9 +3178,14 @@ int process_cmd(char *l)
|
||||||
|
|
||||||
if (!strcmp(av[0], "cron")) {
|
if (!strcmp(av[0], "cron")) {
|
||||||
if (help || config_cron(na, av) == -1)
|
if (help || config_cron(na, av) == -1)
|
||||||
fprintf(mout, "usage:\tcron [«index» [«flags»… [«delay» «cmd»]]]\n"
|
mprintf(-2, "usage:\tcron [«index» [«flags»… [«delay» «cmd»]]]\n"
|
||||||
"\tcron force «flags»… [«times»]\n"
|
"\tcron force «flags»… [«times»]\n"
|
||||||
"\tcron «index» delete\n");
|
"\tcron «index» delete\n"
|
||||||
|
"\t\tindex: `next`, 0 … 15\n"
|
||||||
|
"\t\tflags: init reset once ever buffer\n"
|
||||||
|
"\t\t\tgot_hk got_cntr got_bate did_let\n"
|
||||||
|
"\t\t\trotate_data rotate_cntr rotate_stat\n"
|
||||||
|
);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3159,14 +3197,14 @@ int process_cmd(char *l)
|
||||||
for (pp=paths; pp->name; pp++)
|
for (pp=paths; pp->name; pp++)
|
||||||
if (na<2 || !strcmp(av[1], pp->name)) {
|
if (na<2 || !strcmp(av[1], pp->name)) {
|
||||||
if (na<3)
|
if (na<3)
|
||||||
fprintf(mout, "path %s %s\n", pp->name, *pp->path);
|
mprintf(-2, "path %s %s\n", pp->name, *pp->path);
|
||||||
else if (na==3)
|
else if (na==3)
|
||||||
strncpy(*pp->path, av[2], MAX_FN-1);
|
strncpy(*pp->path, av[2], MAX_FN-1);
|
||||||
if (na>1)
|
if (na>1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (help || na>3 || na>1 && !pp->name)
|
if (help || na>3 || na>1 && !pp->name)
|
||||||
fprintf(mout, "usage:\tpath [«name» [«value»]]\n");
|
mprintf(-2, "usage:\tpath [«name» [«value»]]\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3174,7 +3212,7 @@ int process_cmd(char *l)
|
||||||
// #! /usr/bin/env ./irena
|
// #! /usr/bin/env ./irena
|
||||||
return process_script(av[0]);
|
return process_script(av[0]);
|
||||||
|
|
||||||
fprintf(mout, "unknown command '%s', try help\n", av[0]);
|
mprintf(-2, "unknown command '%s', try help\n", av[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3238,7 +3276,7 @@ int config_cron(int na, char **av)
|
||||||
struct cron *cr = &cron[i];
|
struct cron *cr = &cron[i];
|
||||||
if (!*cr->cmd)
|
if (!*cr->cmd)
|
||||||
continue;
|
continue;
|
||||||
fprintf(mout, "%s %d 0x%04x %d (%d@%ld) «%s»\n",
|
mprintf(-2, "%s %d 0x%04x %d (%d@%ld) «%s»\n",
|
||||||
av[0], i, cr->flags, cr->delay, cr->times, cr->when, cr->cmd);
|
av[0], i, cr->flags, cr->delay, cr->times, cr->when, cr->cmd);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -3252,7 +3290,7 @@ int config_cron(int na, char **av)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (idx<0) {
|
if (idx<0) {
|
||||||
fprintf(mout, "no free crontab entries\n");
|
mprintf(-2, "no free crontab entries\n");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3314,7 +3352,7 @@ int config_cron(int na, char **av)
|
||||||
if (idx<0) {
|
if (idx<0) {
|
||||||
if (!flags || ai!=na)
|
if (!flags || ai!=na)
|
||||||
return -1;
|
return -1;
|
||||||
fprintf(mout, "forcing cron flags 0x%04x, %d times\n", flags, delay);
|
mprintf(-2, "forcing cron flags 0x%04x, %d times\n", flags, delay);
|
||||||
do_cron(0, flags, delay);
|
do_cron(0, flags, delay);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -3332,7 +3370,7 @@ int config_cron(int na, char **av)
|
||||||
strncpy(cr->cmd, av[ai], CRON_CMD_SIZE-1);
|
strncpy(cr->cmd, av[ai], CRON_CMD_SIZE-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(mout, "%s %d 0x%04x %d (%d@%ld) «%s»\n",
|
mprintf(-2, "%s %d 0x%04x %d (%d@%ld) «%s»\n",
|
||||||
av[0], idx, cr->flags, cr->delay, cr->times, cr->when, cr->cmd);
|
av[0], idx, cr->flags, cr->delay, cr->times, cr->when, cr->cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -3371,10 +3409,9 @@ int main(int argc, char **argv)
|
||||||
for (int i=1; i<argc && argv[i]; i++)
|
for (int i=1; i<argc && argv[i]; i++)
|
||||||
process_cmd(argv[i]);
|
process_cmd(argv[i]);
|
||||||
|
|
||||||
const char *prompt = NULL;
|
|
||||||
if (isatty(0) && isatty(2)) {
|
if (isatty(0) && isatty(2)) {
|
||||||
prompt = "IRENA> ";
|
prompt = "IRENA> ";
|
||||||
fprintf(mout, prompt);
|
fprintf(stderr, prompt);
|
||||||
in_prompt = 1;
|
in_prompt = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3390,8 +3427,8 @@ int main(int argc, char **argv)
|
||||||
int n = epoll_wait(epoll_fd, eev, 2, 1000);
|
int n = epoll_wait(epoll_fd, eev, 2, 1000);
|
||||||
time_t t = time(0);
|
time_t t = time(0);
|
||||||
for (int i=0; i<n; i++) {
|
for (int i=0; i<n; i++) {
|
||||||
if (eev[i].events != EPOLLIN && verbose(2))
|
if (eev[i].events != EPOLLIN)
|
||||||
fprintf(mout, "epoll: fd=%d events=0x%x\n", eev[i].data.fd, eev[i].events);
|
mprintf(2, "epoll: fd=%d events=0x%x\n", eev[i].data.fd, eev[i].events);
|
||||||
if (eev[i].data.fd == cmd_socket_fd)
|
if (eev[i].data.fd == cmd_socket_fd)
|
||||||
accept_cmd_socket(cmd_socket_fd);
|
accept_cmd_socket(cmd_socket_fd);
|
||||||
else if (eev[i].data.fd == s_buf.fd) {
|
else if (eev[i].data.fd == s_buf.fd) {
|
||||||
|
|
@ -3399,7 +3436,9 @@ int main(int argc, char **argv)
|
||||||
if (!l)
|
if (!l)
|
||||||
close_acmd_socket(&s_buf);
|
close_acmd_socket(&s_buf);
|
||||||
while (l) {
|
while (l) {
|
||||||
|
in_prompt = 0;
|
||||||
process_cmd(l);
|
process_cmd(l);
|
||||||
|
in_prompt = !!prompt;
|
||||||
l = get_line(&s_buf, 0);
|
l = get_line(&s_buf, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3407,14 +3446,7 @@ int main(int argc, char **argv)
|
||||||
poll_uart(eev[i].events);
|
poll_uart(eev[i].events);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int do_read = eev[i].events;
|
char *l = get_line(&c_buf, eev[i].events);
|
||||||
if (prompt && in_prompt==2 && do_read) {
|
|
||||||
fprintf(stderr, prompt);
|
|
||||||
reprint_line(stderr, &c_buf);
|
|
||||||
in_prompt = 1;
|
|
||||||
do_read = 0;
|
|
||||||
}
|
|
||||||
char *l = get_line(&c_buf, do_read);
|
|
||||||
while (l) {
|
while (l) {
|
||||||
in_prompt = 0;
|
in_prompt = 0;
|
||||||
process_cmd(l);
|
process_cmd(l);
|
||||||
|
|
@ -3423,6 +3455,7 @@ int main(int argc, char **argv)
|
||||||
fprintf(stderr, "M:%s", prompt);
|
fprintf(stderr, "M:%s", prompt);
|
||||||
else
|
else
|
||||||
fprintf(stderr, prompt);
|
fprintf(stderr, prompt);
|
||||||
|
if (mout==stderr)
|
||||||
in_prompt = 1;
|
in_prompt = 1;
|
||||||
}
|
}
|
||||||
l = get_line(&c_buf, 0);
|
l = get_line(&c_buf, 0);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue