nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include "dev.h" nuclear@2: #include "timer.h" nuclear@2: nuclear@2: int customer, ticket; nuclear@2: static int report_inputs, cmd_echo; nuclear@2: static long last_ticket_msec = LONG_MIN; nuclear@2: nuclear@2: static void runcmd(const char *cmd); nuclear@2: nuclear@2: static int fd = -1; nuclear@2: static FILE *fp; nuclear@2: static std::string cur_line; nuclear@2: nuclear@2: int start_dev(const char *devpath) nuclear@2: { nuclear@2: if((fd = open(devpath, O_RDWR | O_NONBLOCK)) == -1) { nuclear@2: fprintf(stderr, "failed to open device: %s: %s\n", devpath, strerror(errno)); nuclear@2: return -1; nuclear@2: } nuclear@2: if(isatty(fd)) { nuclear@2: struct termios term; nuclear@2: nuclear@2: if(tcgetattr(fd, &term) == -1) { nuclear@2: perror("failed to retrieve terminal attributes"); nuclear@2: stop_dev(); nuclear@2: return -1; nuclear@2: } nuclear@2: term.c_cflag = CS8 | CLOCAL; nuclear@2: term.c_iflag &= ~(IXON | IXOFF); nuclear@2: term.c_lflag = 0; nuclear@2: nuclear@2: cfsetispeed(&term, B38400); nuclear@2: cfsetospeed(&term, B38400); nuclear@2: nuclear@2: if(tcsetattr(fd, TCSANOW, &term) == -1) { nuclear@2: perror("failed to set terminal attributes"); nuclear@2: stop_dev(); nuclear@2: return -1; nuclear@2: } nuclear@2: } nuclear@2: nuclear@2: if(!(fp = fdopen(fd, "r+"))) { nuclear@2: perror("failed to attach an I/O stream to the device file\n"); nuclear@2: stop_dev(); nuclear@2: return -1; nuclear@2: } nuclear@2: setvbuf(fp, 0, _IONBF, 0); nuclear@2: nuclear@2: return fd; nuclear@2: } nuclear@2: nuclear@2: void stop_dev() nuclear@2: { nuclear@2: if(fp) nuclear@2: fclose(fp); nuclear@2: else if(fd >= 0) nuclear@2: close(fd); nuclear@2: } nuclear@2: nuclear@2: nuclear@2: void proc_dev_input() nuclear@2: { nuclear@2: int rdbytes; nuclear@2: char buf[256]; nuclear@2: static bool skip_line; nuclear@2: nuclear@2: while((rdbytes = read(fd, buf, sizeof buf - 1)) > 0) { nuclear@2: buf[rdbytes] = 0; nuclear@2: nuclear@2: /* ignore our own crap */ nuclear@2: if(memcmp(buf, "OK,", 3) == 0 || memcmp(buf, "ERR,", 4) == 0) { nuclear@2: skip_line = true; nuclear@2: } nuclear@2: nuclear@2: for(int i=0; i" nuclear@2: nuclear@2: static void runcmd(const char *cmd) nuclear@2: { nuclear@2: printf("DBG: runcmd(\"%s\")\n", cmd); nuclear@2: nuclear@2: switch(cmd[0]) { nuclear@2: case 'e': nuclear@2: cmd_echo = !cmd_echo; nuclear@2: fprintf(fp, "OK,turning echo %s\n", cmd_echo ? "on" : "off"); nuclear@2: break; nuclear@2: nuclear@2: case 'i': nuclear@2: report_inputs = !report_inputs; nuclear@2: fprintf(fp, "OK,turning input reports %s\n", report_inputs ? "on" : "off"); nuclear@2: break; nuclear@2: nuclear@2: case 'v': nuclear@2: fprintf(fp, "OK,%s\n", VERSTR); nuclear@2: break; nuclear@2: nuclear@2: case 'r': nuclear@2: fprintf(fp, "OK,reseting queues\n"); nuclear@2: customer = 0; nuclear@2: ticket = 0; nuclear@2: last_ticket_msec = LONG_MIN; nuclear@2: break; nuclear@2: nuclear@2: case 't': nuclear@2: fprintf(fp, "OK,ticket: %d\r\n", ticket); nuclear@2: break; nuclear@2: nuclear@2: case 'c': nuclear@2: fprintf(fp, "OK,customer: %d\r\n", customer); nuclear@2: break; nuclear@2: nuclear@2: case 'q': nuclear@2: fprintf(fp, "OK,issuing queue ticket\n"); nuclear@2: issue_ticket(); nuclear@2: break; nuclear@2: nuclear@2: case 'n': nuclear@2: fprintf(fp, "OK,next customer\n"); nuclear@2: next_customer(); nuclear@2: break; nuclear@2: nuclear@2: case 'h': nuclear@2: fprintf(fp, "OK,commands: (e)cho, (v)ersion, (t)icket, (c)ustomer, " nuclear@2: "(n)ext, (q)ueue, (r)eset, (i)nput-reports, (h)elp.\n"); nuclear@2: break; nuclear@2: nuclear@2: default: nuclear@2: fprintf(fp, "ERR,unknown command: %s\n", cmd); nuclear@2: } nuclear@2: }