return EC_Safety;
}
+/*---------- printing nmra data ----------*/
+
+typedef struct {
+ const Byte *i, *o;
+ int npending;
+ unsigned datapending;
+} NmraDecCtx;
+
+static void nmradec_init(NmraDecCtx *d, const PicInsn *pi) {
+ d->i= pi->d;
+ d->o= pi->d + pi->l;
+ d->npending= 0;
+ d->datapending= 0;
+}
+
+static void nmradec_getbits(NmraDecCtx *d, int *nbits_io, unsigned *bits_r) {
+ int use= *nbits_io;
+ while (d->npending < use) {
+ if (d->i >= d->o) break;
+ d->datapending <<= 7;
+ d->datapending |= *d->i & 0x7f;
+ d->npending += 7;
+ if (!(*d->i++ & 0x80)) break;
+ }
+ if (d->npending < use) use= d->npending;
+ d->npending -= use;
+ *bits_r= (d->datapending >> d->npending) & ~(~0u << use);
+ *nbits_io= use;
+}
+
+static void nmra_decodeforpic(const PicInsn *pi,
+ void (*on_idle)(void *u, int),
+ void (*on_packet)(void *u, const Nmra*),
+ void (*on_error)(void *u, int reasonchar),
+ void *u) {
+ /* reasonchars:
+ * # - bad checksum
+ * ! - too little idle
+ * $ - truncated
+ */
+ NmraDecCtx d;
+ Nmra n;
+ int need_idle=7, got_idle=0;
+ unsigned got, csum;
+ int nbits;
+
+ nmradec_init(&d,pi);
+ for (;;) {
+ nbits=1; nmradec_getbits(&d,&nbits,&got);
+ if (got) { got_idle++; continue; }
+ if (got_idle) on_idle(u,got_idle);
+ if (!nbits) return;
+ if (got_idle < need_idle) on_error(u,'!');
+ got_idle= 0;
+
+ n.l=0; csum=0;
+ do {
+ nbits=8; nmradec_getbits(&d,&nbits,&got);
+ n.d[n.l++]= got;
+ csum ^= got;
+ if (nbits<8) on_error(u,'$');
+
+ nbits=1; nmradec_getbits(&d,&nbits,&got);
+ if (nbits<1) on_error(u,'$');
+ } while (nbits && !got);
+
+ if (csum) on_error(u,'#');
+ else n.l--;
+
+ on_packet(u,&n);
+ need_idle= 14;
+ }
+}
+
+static void opn_idle(void *u, int idle) {
+ static const char dots[]= "......."; /* at least base/2 */
+ const int base= 14;
+ int largers= idle / base;
+ int units= idle % base;
+
+ oprintf(UPO," %.*s%.*s%.*s",
+ units/2, dots,
+ largers, ":::::::" /* enough */,
+ (units+1)/2, dots);
+}
+static void opn_error(void *u, int rc) { oprintf(UPO," %c",rc); }
+static void opn_packet(void *u, const Nmra *n) {
+ int i;
+ const char *delim= " <";
+ for (i=0; i<n->l; i++) {
+ oprintf(UPO,"%s%02x",delim,n->d[i]);
+ delim=" ";
+ }
+ oprintf(UPO,">");
+}
+
+static void oprint_nmradata(const PicInsn *pi) {
+ oprintf(UPO,"picio out nmradata");
+ nmra_decodeforpic(pi, opn_idle,opn_packet,opn_error, 0);
+ oprintf(UPO,"\n");
+}
+
/*---------- command channel handling (oop_read, obc) ----------*/
static void command_doline(ParseState *ps, CommandInput *cmdi) {
oop_event evt, void *u0) {
int r, buf_used;
- r= read(serial_fd, &serial_buf.d, sizeof(serial_buf.d) - serial_buf.l);
+ r= read(serial_fd, &serial_buf.d + serial_buf.l,
+ sizeof(serial_buf.d) - serial_buf.l);
if (r==0) die("serial port - eof");
if (r==-1) {
if (errno == EWOULDBLOCK || errno == EINTR)
delim= ",";
}
oprintf(UPO,">\n");
+ } else if (pi->d[0] == 0xff) {
+ oprint_nmradata(pi);
} else {
picinsn_decode(pi, pic_command_infos, &pii, &objnum);
if (!pii)