/* ** Copyright 2001, Brian Swetland ** All Rights Reserved. Please read the provided LICENSE file. */ #include #include #include #include #include #include #include #include #include #include #include "xproto.h" //#define SPEED B38400 #define SPEED B115200 #ifdef linux # define DEVICE "/dev/ttyS0" #endif // #ifdef linux #ifdef __FreeBSD__ # define DEVICE "/dev/cuaa0" #endif // #ifdef __FREEBSD__ void msg(const char *fmt, ...); void debug_msg(const char *text, int lne); static xframe *waitframe = 0; static u1 __xio[4096]; XIO *xio = (XIO*) __xio; void ui_init(); void ui_run(); int openserial(const char *device) { struct termios tio; int fd; if((fd = open(device, O_RDWR | O_NOCTTY)) < 0) return -1; memset(&tio, 0, sizeof(tio)); // tcgetattr( fd, &tio); #ifdef __FreeBSD__ tio.c_cflag = CS8 | CLOCAL | CREAD; tio.c_ispeed = SPEED; tio.c_ospeed = SPEED; #else tio.c_cflag = SPEED | CS8 | CLOCAL | CREAD; #endif tio.c_iflag = IGNPAR; tio.c_lflag = 0; /* turn of CANON, ECHO*, etc */ tio.c_cc[VTIME] = 0; tio.c_cc[VMIN] = 1; tcsetattr( fd, TCSANOW, &tio ); tcflush( fd, TCIFLUSH ); return fd; } int xio_fd; static u1 esc_ae[2] = { XESCAPE, XESC_AE }; static u1 esc_ad[2] = { XESCAPE, XESC_AD }; static u1 framec[2] = { '\r', XFRAME }; void xio_out(const u1 *data, int len) { u1 x; write(xio_fd, framec, 2); while(len-- > 0) { x = *data; if(x == 0xae) { write(xio_fd, esc_ae, 2); } else if(x == 0xad){ write(xio_fd, esc_ad, 2); } else { write(xio_fd, data, 1); } data++; } write(xio_fd, framec + 1, 1); } static int xcmd_debug(xframe *f) { debug_msg((const char *) f->u.b, f->len - 8); return 0; } static int xcmd_ack(xframe *f) { if(waitframe == 0) { //msg("OOPS ACK %08x %02x %01x %01x\n",f->a32, f->len, f->seq, f->cmd); return 0; } if(f->seq == waitframe->seq){ memcpy(waitframe, f, f->len); waitframe = 0; } //printf("ACK %08x %02x %01x %01x\n",f->a32, f->len, f->seq, f->cmd); return 0; } static int xcmd_err(xframe *f) { if(waitframe == 0) { //msg("OOPS ERR %08x %02x %01x %01x\n",f->a32, f->len, f->seq, f->cmd); return 0; } if(f->seq == waitframe->seq){ memcpy(waitframe, f, f->len); waitframe = 0; } msg("ERR %08x %02x %01x %01x\n",f->a32, f->len, f->seq, f->cmd); return 0; } xcmdmap xcommands[] = { { XCMD_ACK, xcmd_ack }, { XCMD_ERR, xcmd_err }, { XCMD_DEBUG, xcmd_debug }, { 0, 0 } }; int main(int argc, char *argv[]) { const char *device = DEVICE; int fd; u1 x[3] = { '\r', '\r', '\r' }; xio_init(xio); if(argc == 2) device = argv[1]; if((fd = openserial(device)) < 0) { fprintf(stderr,"cannot open serial port '%s'\n",device); return -1; } xio_fd = fd; write(fd, x, 3); ui_init(); xio_wait(xio,0); close(fd); return 0; } int xio_wait(XIO *xio, xframe *f) { fd_set fds; u1 c; int s; int xtimeout; struct timeval tv; if(waitframe != 0) { fprintf(stderr,"OH SHIT!!!"); } else { waitframe = f; } xtimeout = 30; for(;;) { if(f != 0) { if((f->cmd == XCMD_ACK) || (f->cmd == XCMD_ERR)){ if(f->cmd == XCMD_ERR) { waitframe = 0; return -1; } else { waitframe = 0; return f->len; } } else { if(xtimeout == 0) { msg("TIMEOUT!\n"); waitframe = 0; return -1; } } } FD_ZERO(&fds); if(waitframe == 0) FD_SET(0, &fds); FD_SET(xio_fd, &fds); tv.tv_sec = 0; tv.tv_usec = 100000; if(select(xio_fd + 1, &fds, 0, 0, &tv) > 0){ if(FD_ISSET(xio_fd, &fds)){ s = read(xio_fd, &c, 1); if(s == 1) xio_in(xio, c); } if(FD_ISSET(0, &fds)) { ui_run(); #if 0 s = read(0, &c, 1); if(s == 1) ui_run(c); #endif } } else { xio_out(framec, 1); if(f != 0) xtimeout--; } } return 0; }