eqemu

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