eqemu

annotate src/dev.cc @ 11:2b559dc24c7b

done
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 18 Jul 2014 05:44:37 +0300
parents 977bc1cb055b
children 2656099aff12
rev   line source
nuclear@2 1 #include <stdio.h>
nuclear@2 2 #include <string.h>
nuclear@2 3 #include <errno.h>
nuclear@2 4 #include <signal.h>
nuclear@2 5 #include <limits.h>
nuclear@2 6 #include <string>
nuclear@2 7 #include <unistd.h>
nuclear@2 8 #include <sys/stat.h>
nuclear@2 9 #include <sys/wait.h>
nuclear@2 10 #include <fcntl.h>
nuclear@2 11 #include <termios.h>
nuclear@2 12 #include "dev.h"
nuclear@2 13 #include "timer.h"
nuclear@2 14
nuclear@11 15 void post_redisplay(); // defined in main.cc
nuclear@11 16
nuclear@2 17 int customer, ticket;
nuclear@2 18 static int report_inputs, cmd_echo;
nuclear@2 19 static long last_ticket_msec = LONG_MIN;
nuclear@2 20
nuclear@2 21 static void runcmd(const char *cmd);
nuclear@2 22
nuclear@2 23 static int fd = -1;
nuclear@2 24 static FILE *fp;
nuclear@2 25 static std::string cur_line;
nuclear@2 26
nuclear@2 27 int start_dev(const char *devpath)
nuclear@2 28 {
nuclear@2 29 if((fd = open(devpath, O_RDWR | O_NONBLOCK)) == -1) {
nuclear@2 30 fprintf(stderr, "failed to open device: %s: %s\n", devpath, strerror(errno));
nuclear@2 31 return -1;
nuclear@2 32 }
nuclear@2 33 if(isatty(fd)) {
nuclear@2 34 struct termios term;
nuclear@2 35
nuclear@2 36 if(tcgetattr(fd, &term) == -1) {
nuclear@2 37 perror("failed to retrieve terminal attributes");
nuclear@2 38 stop_dev();
nuclear@2 39 return -1;
nuclear@2 40 }
nuclear@2 41 term.c_cflag = CS8 | CLOCAL;
nuclear@2 42 term.c_iflag &= ~(IXON | IXOFF);
nuclear@2 43 term.c_lflag = 0;
nuclear@2 44
nuclear@2 45 cfsetispeed(&term, B38400);
nuclear@2 46 cfsetospeed(&term, B38400);
nuclear@2 47
nuclear@2 48 if(tcsetattr(fd, TCSANOW, &term) == -1) {
nuclear@2 49 perror("failed to set terminal attributes");
nuclear@2 50 stop_dev();
nuclear@2 51 return -1;
nuclear@2 52 }
nuclear@2 53 }
nuclear@2 54
nuclear@2 55 if(!(fp = fdopen(fd, "r+"))) {
nuclear@2 56 perror("failed to attach an I/O stream to the device file\n");
nuclear@2 57 stop_dev();
nuclear@2 58 return -1;
nuclear@2 59 }
nuclear@2 60 setvbuf(fp, 0, _IONBF, 0);
nuclear@2 61
nuclear@2 62 return fd;
nuclear@2 63 }
nuclear@2 64
nuclear@2 65 void stop_dev()
nuclear@2 66 {
nuclear@2 67 if(fp)
nuclear@2 68 fclose(fp);
nuclear@2 69 else if(fd >= 0)
nuclear@2 70 close(fd);
nuclear@2 71 }
nuclear@2 72
nuclear@2 73
nuclear@2 74 void proc_dev_input()
nuclear@2 75 {
nuclear@2 76 int rdbytes;
nuclear@2 77 char buf[256];
nuclear@2 78 static bool skip_line;
nuclear@2 79
nuclear@2 80 while((rdbytes = read(fd, buf, sizeof buf - 1)) > 0) {
nuclear@2 81 buf[rdbytes] = 0;
nuclear@2 82
nuclear@2 83 /* ignore our own crap */
nuclear@2 84 if(memcmp(buf, "OK,", 3) == 0 || memcmp(buf, "ERR,", 4) == 0) {
nuclear@2 85 skip_line = true;
nuclear@2 86 }
nuclear@2 87
nuclear@2 88 for(int i=0; i<rdbytes; i++) {
nuclear@2 89 if(buf[i] == '\n' || buf[i] == '\r') {
nuclear@2 90 if(!cur_line.empty()) {
nuclear@2 91 runcmd(cur_line.c_str());
nuclear@2 92 cur_line.clear();
nuclear@2 93 }
nuclear@2 94 skip_line = false;
nuclear@2 95 } else {
nuclear@2 96 if(!skip_line) {
nuclear@2 97 cur_line.push_back(buf[i]);
nuclear@2 98 }
nuclear@2 99 }
nuclear@2 100 }
nuclear@2 101 }
nuclear@2 102 }
nuclear@2 103
nuclear@2 104 void issue_ticket()
nuclear@2 105 {
nuclear@2 106 ticket++;
nuclear@2 107 last_ticket_msec = get_msec();
nuclear@2 108 if(report_inputs) {
nuclear@2 109 fprintf(fp, "ticket: %d\n", ticket);
nuclear@2 110 }
nuclear@11 111
nuclear@11 112 post_redisplay();
nuclear@2 113 }
nuclear@2 114
nuclear@2 115 void next_customer()
nuclear@2 116 {
nuclear@2 117 if(customer < ticket) {
nuclear@2 118 customer++;
nuclear@2 119 last_ticket_msec = LONG_MIN;
nuclear@2 120 if(report_inputs) {
nuclear@2 121 fprintf(fp, "customer: %d\n", customer);
nuclear@2 122 }
nuclear@11 123
nuclear@11 124 post_redisplay();
nuclear@2 125 }
nuclear@2 126 }
nuclear@2 127
nuclear@6 128 #define TICKET_SHOW_DUR 1000
nuclear@6 129
nuclear@6 130 int get_display_number()
nuclear@6 131 {
nuclear@6 132 if(get_msec() - last_ticket_msec < TICKET_SHOW_DUR) {
nuclear@6 133 return ticket;
nuclear@6 134 }
nuclear@6 135 return customer;
nuclear@6 136 }
nuclear@6 137
nuclear@6 138 int get_led_state(int led)
nuclear@6 139 {
nuclear@6 140 int ledon = get_msec() - last_ticket_msec < TICKET_SHOW_DUR ? 0 : 1;
nuclear@6 141 return led == ledon ? 1 : 0;
nuclear@6 142 }
nuclear@6 143
nuclear@2 144 #define VERSTR \
nuclear@2 145 "Queue system emulator v0.1 by John Tsiombikas <nuclear@member.fsf.org>"
nuclear@2 146
nuclear@2 147 static void runcmd(const char *cmd)
nuclear@2 148 {
nuclear@2 149 printf("DBG: runcmd(\"%s\")\n", cmd);
nuclear@2 150
nuclear@2 151 switch(cmd[0]) {
nuclear@2 152 case 'e':
nuclear@2 153 cmd_echo = !cmd_echo;
nuclear@2 154 fprintf(fp, "OK,turning echo %s\n", cmd_echo ? "on" : "off");
nuclear@2 155 break;
nuclear@2 156
nuclear@2 157 case 'i':
nuclear@2 158 report_inputs = !report_inputs;
nuclear@2 159 fprintf(fp, "OK,turning input reports %s\n", report_inputs ? "on" : "off");
nuclear@2 160 break;
nuclear@2 161
nuclear@2 162 case 'v':
nuclear@2 163 fprintf(fp, "OK,%s\n", VERSTR);
nuclear@2 164 break;
nuclear@2 165
nuclear@2 166 case 'r':
nuclear@2 167 fprintf(fp, "OK,reseting queues\n");
nuclear@2 168 customer = 0;
nuclear@2 169 ticket = 0;
nuclear@2 170 last_ticket_msec = LONG_MIN;
nuclear@11 171 post_redisplay();
nuclear@2 172 break;
nuclear@2 173
nuclear@2 174 case 't':
nuclear@2 175 fprintf(fp, "OK,ticket: %d\r\n", ticket);
nuclear@2 176 break;
nuclear@2 177
nuclear@2 178 case 'c':
nuclear@2 179 fprintf(fp, "OK,customer: %d\r\n", customer);
nuclear@2 180 break;
nuclear@2 181
nuclear@2 182 case 'q':
nuclear@2 183 fprintf(fp, "OK,issuing queue ticket\n");
nuclear@2 184 issue_ticket();
nuclear@2 185 break;
nuclear@2 186
nuclear@2 187 case 'n':
nuclear@2 188 fprintf(fp, "OK,next customer\n");
nuclear@2 189 next_customer();
nuclear@2 190 break;
nuclear@2 191
nuclear@2 192 case 'h':
nuclear@2 193 fprintf(fp, "OK,commands: (e)cho, (v)ersion, (t)icket, (c)ustomer, "
nuclear@2 194 "(n)ext, (q)ueue, (r)eset, (i)nput-reports, (h)elp.\n");
nuclear@2 195 break;
nuclear@2 196
nuclear@2 197 default:
nuclear@2 198 fprintf(fp, "ERR,unknown command: %s\n", cmd);
nuclear@2 199 }
nuclear@2 200 }