From cbf05996ebaec10ecdb46c8ba52144f9d531aa12 Mon Sep 17 00:00:00 2001 From: ian Date: Tue, 15 Jan 2008 22:34:36 +0000 Subject: [PATCH] dump decoding of transmitted nmra data --- hostside/realtime.c | 107 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/hostside/realtime.c b/hostside/realtime.c index 18e1f13..bfab9e2 100644 --- a/hostside/realtime.c +++ b/hostside/realtime.c @@ -109,6 +109,108 @@ ErrorCode safety_problem(Train *tra, Segment *seg, const char *fmt,...) { 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; il; 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) { @@ -159,7 +261,8 @@ static void *serial_readable(oop_source *evts, int fd, 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) @@ -204,6 +307,8 @@ void serial_transmit(const PicInsn *pi) { delim= ","; } oprintf(UPO,">\n"); + } else if (pi->d[0] == 0xff) { + oprint_nmradata(pi); } else { picinsn_decode(pi, pic_command_infos, &pii, &objnum); if (!pii) -- 2.30.2