/* ** Copyright 2001, Brian Swetland ** All Rights Reserved. Please read the provided LICENSE file. */ #include #define fbuf (xio->buf) #define fcount (xio->count) #define fnextseq (xio->nextseq) #define flastseq (xio->lastseq) #define fescape (xio->escape) #define ferrors (xio->errors) void xio_init(XIO *xio) { xio->debugcount = 0; fcount = 0; fnextseq = 1; flastseq = -1; fescape = 0; ferrors = 0; } #define CHATTY 0 void xio_in(XIO *xio, u1 data) { if(data == XFRAME){ if(fcount >= 8) { xframe *f; int i,s; f = (xframe*) fbuf; #if CHATTY printf("PKT %08x (%08x) %04x (%04x) %02x %02x\n", f->a32, adler32(1, fbuf + 4, fcount - 4), f->len, fcount, f->seq, f->cmd); #endif if(f->len != fcount) { ferrors++; goto done; } if(f->a32 != adler32(1, fbuf + 4, fcount - 4)){ ferrors++; goto done; } for(i = 0; xcommands[i].handler != 0; i++){ if(xcommands[i].command == f->cmd) { s = xcommands[i].handler(f); if((f->cmd == XCMD_ACK) || (f->cmd == XCMD_ERR)) { goto done; } else { if(s < 0) { f->cmd = XCMD_ERR; f->len = 8; } else { f->cmd = XCMD_ACK; f->len = 8 + s; } f->a32 = adler32(1, fbuf + 4, f->len - 4); xio_out(fbuf, f->len); goto done; } } } } done: fcount = 0; fescape = 0; return; } if(fcount == MAXPACKET) return; if(data == XESCAPE) { fescape = 1; } else { if(fescape) { fescape = 0; if(data == XESC_AE) { data = 0xAE; } else if(data == XESC_AD) { data = 0xAD; } else { return; } } fbuf[fcount++] = data; } } int xio_rpc(XIO *xio, xframe *f) { f->seq = fnextseq++; f->a32 = adler32(1, ((u1*)f) + 4, f->len - 4); xio_out((u1*) f, f->len); return xio_wait(xio, f); } int xio_rpc_nowait(XIO *xio, xframe *f) { f->seq = fnextseq++; f->a32 = adler32(1, ((u1*)f) + 4, f->len - 4); xio_out((u1*) f, f->len); return 0; }