eqemu

view src/dev.cc @ 12:2656099aff12

added copyright notices and license
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 18 Jul 2014 07:04:21 +0300
parents 2b559dc24c7b
children
line source
1 /*
2 eqemu - electronic queue system emulator
3 Copyright (C) 2014 John Tsiombikas <nuclear@member.fsf.org>,
4 Eleni-Maria Stea <eleni@mutantstargoat.com>
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #include <stdio.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <signal.h>
23 #include <limits.h>
24 #include <string>
25 #include <unistd.h>
26 #include <sys/stat.h>
27 #include <sys/wait.h>
28 #include <fcntl.h>
29 #include <termios.h>
30 #include "dev.h"
31 #include "timer.h"
33 void post_redisplay(); // defined in main.cc
35 int customer, ticket;
36 static int report_inputs, cmd_echo;
37 static long last_ticket_msec = LONG_MIN;
39 static void runcmd(const char *cmd);
41 static int fd = -1;
42 static FILE *fp;
43 static std::string cur_line;
45 int start_dev(const char *devpath)
46 {
47 if((fd = open(devpath, O_RDWR | O_NONBLOCK)) == -1) {
48 fprintf(stderr, "failed to open device: %s: %s\n", devpath, strerror(errno));
49 return -1;
50 }
51 if(isatty(fd)) {
52 struct termios term;
54 if(tcgetattr(fd, &term) == -1) {
55 perror("failed to retrieve terminal attributes");
56 stop_dev();
57 return -1;
58 }
59 term.c_cflag = CS8 | CLOCAL;
60 term.c_iflag &= ~(IXON | IXOFF);
61 term.c_lflag = 0;
63 cfsetispeed(&term, B38400);
64 cfsetospeed(&term, B38400);
66 if(tcsetattr(fd, TCSANOW, &term) == -1) {
67 perror("failed to set terminal attributes");
68 stop_dev();
69 return -1;
70 }
71 }
73 if(!(fp = fdopen(fd, "r+"))) {
74 perror("failed to attach an I/O stream to the device file\n");
75 stop_dev();
76 return -1;
77 }
78 setvbuf(fp, 0, _IONBF, 0);
80 return fd;
81 }
83 void stop_dev()
84 {
85 if(fp)
86 fclose(fp);
87 else if(fd >= 0)
88 close(fd);
89 }
92 void proc_dev_input()
93 {
94 int rdbytes;
95 char buf[256];
96 static bool skip_line;
98 while((rdbytes = read(fd, buf, sizeof buf - 1)) > 0) {
99 buf[rdbytes] = 0;
101 /* ignore our own crap */
102 if(memcmp(buf, "OK,", 3) == 0 || memcmp(buf, "ERR,", 4) == 0) {
103 skip_line = true;
104 }
106 for(int i=0; i<rdbytes; i++) {
107 if(buf[i] == '\n' || buf[i] == '\r') {
108 if(!cur_line.empty()) {
109 runcmd(cur_line.c_str());
110 cur_line.clear();
111 }
112 skip_line = false;
113 } else {
114 if(!skip_line) {
115 cur_line.push_back(buf[i]);
116 }
117 }
118 }
119 }
120 }
122 void issue_ticket()
123 {
124 ticket++;
125 last_ticket_msec = get_msec();
126 if(report_inputs) {
127 fprintf(fp, "ticket: %d\n", ticket);
128 }
130 post_redisplay();
131 }
133 void next_customer()
134 {
135 if(customer < ticket) {
136 customer++;
137 last_ticket_msec = LONG_MIN;
138 if(report_inputs) {
139 fprintf(fp, "customer: %d\n", customer);
140 }
142 post_redisplay();
143 }
144 }
146 #define TICKET_SHOW_DUR 1000
148 int get_display_number()
149 {
150 if(get_msec() - last_ticket_msec < TICKET_SHOW_DUR) {
151 return ticket;
152 }
153 return customer;
154 }
156 int get_led_state(int led)
157 {
158 int ledon = get_msec() - last_ticket_msec < TICKET_SHOW_DUR ? 0 : 1;
159 return led == ledon ? 1 : 0;
160 }
162 #define VERSTR \
163 "Queue system emulator v0.1"
165 static void runcmd(const char *cmd)
166 {
167 printf("DBG: runcmd(\"%s\")\n", cmd);
169 switch(cmd[0]) {
170 case 'e':
171 cmd_echo = !cmd_echo;
172 fprintf(fp, "OK,turning echo %s\n", cmd_echo ? "on" : "off");
173 break;
175 case 'i':
176 report_inputs = !report_inputs;
177 fprintf(fp, "OK,turning input reports %s\n", report_inputs ? "on" : "off");
178 break;
180 case 'v':
181 fprintf(fp, "OK,%s\n", VERSTR);
182 break;
184 case 'r':
185 fprintf(fp, "OK,reseting queues\n");
186 customer = 0;
187 ticket = 0;
188 last_ticket_msec = LONG_MIN;
189 post_redisplay();
190 break;
192 case 't':
193 fprintf(fp, "OK,ticket: %d\r\n", ticket);
194 break;
196 case 'c':
197 fprintf(fp, "OK,customer: %d\r\n", customer);
198 break;
200 case 'q':
201 fprintf(fp, "OK,issuing queue ticket\n");
202 issue_ticket();
203 break;
205 case 'n':
206 fprintf(fp, "OK,next customer\n");
207 next_customer();
208 break;
210 case 'h':
211 fprintf(fp, "OK,commands: (e)cho, (v)ersion, (t)icket, (c)ustomer, "
212 "(n)ext, (q)ueue, (r)eset, (i)nput-reports, (h)elp.\n");
213 break;
215 default:
216 fprintf(fp, "ERR,unknown command: %s\n", cmd);
217 }
218 }