]> git.itanic.dy.fi Git - glucose/blob - main.c
Refactor hiddev functions out from main.c
[glucose] / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <linux/types.h>
5 #include <linux/hiddev.h>
6 #include <string.h>
7 #include <errno.h>
8 #include <time.h>
9
10 #include "hiddev.h"
11
12 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
13
14 struct msg {
15         int direction;
16         unsigned char data[64];
17 };
18
19 enum direction {
20         IN = 666,
21         OUT,
22 };
23
24 static int is_printable(const unsigned char c)
25 {
26         return c >= 0x20 && c < 0x80;
27 }
28
29 static int datalen(const unsigned char *data)
30 {
31         int i, len;
32
33         for (i = 0, len = 0; i < 64; i++)
34                 if (data[i])
35                         len = i;
36
37         return len + 1;
38 }
39
40 static void print_hex(const unsigned char *data, int len)
41 {
42         int i;
43
44         for (i = 0; i < len; i++)
45                 printf("0x%02x ", data[i]);
46
47         printf("\n");
48 }
49
50 static void print_ascii(const unsigned char *data, int len)
51 {
52         int i;
53
54         for (i = 0; i < len; i++)
55                 printf("%c", is_printable(data[i]) ? data[i] : '.');
56
57         printf("\n");
58 }
59
60 int send_msg(const struct msg *msg, int fd, int usage_code)
61 {
62         int ret;
63
64         if (msg->direction != OUT) {
65                 printf("Message direction is not OUT\n");
66                 exit(1);
67         }
68
69         usleep(30 * 1000);
70         printf("Sending: ");
71         print_hex(msg->data + 1, datalen(msg->data) - 1);
72         print_ascii(msg->data + 1, datalen(msg->data) - 1);
73
74         ret = hiddev_write(msg->data, fd, usage_code);
75         if (ret)
76                 exit(1);
77
78         return 0;
79 }
80
81 int read_and_verify(struct msg *msg, int fd)
82 {
83         unsigned char buf[64];
84         int ret, offset = 0;
85
86         while (offset < 64) {
87                 ret = hiddev_read(buf + offset, sizeof(buf) - offset, fd);
88
89                 if (ret < 0)
90                         goto err;
91
92                 offset += ret;
93         }
94
95         memcpy(msg->data, buf, sizeof(buf));
96         printf("Got data %d: ", datalen(buf));
97 //      print_hex(buf, datalen(buf));
98         print_ascii(buf, datalen(buf));
99 err:
100         return 0;
101 }
102
103 int read_msgs(int fd)
104 {
105         struct msg msg;
106         while (1) {
107                 read_and_verify(&msg, fd);
108                 if (datalen(msg.data) <= 36)
109                         break;
110         }
111
112         return 0;
113 }
114
115 #define SET_FIRST_BYTE(byte)                                    \
116         do {                                                    \
117                 memset(&msg.data, 0, sizeof(msg.data));         \
118                 msg.data[4] = (byte);                           \
119                 j = 5;                                          \
120         } while (0)
121
122 #define SET_BYTE(idx, byte)                     \
123         do {                                    \
124                 msg.data[(idx) + 4] = (byte);   \
125                 j = (idx) + 1;                  \
126         } while (0)
127
128 #define SET_BYTES(byte) msg.data[j++] = (byte)
129
130 int send_pattern(int fd, int uc, unsigned char byte1, unsigned char byte2)
131 {
132         int j;
133         struct msg msg;
134         msg.direction = OUT;
135
136         usleep(100 * 1000);
137         SET_FIRST_BYTE(0x01);
138         SET_BYTES(0x04);
139         send_msg(&msg, fd, uc);
140         read_msgs(fd);
141
142         usleep(250 * 1000);
143         SET_BYTE(1, 0x15);
144         send_msg(&msg, fd, uc);
145         read_msgs(fd);
146
147         usleep(100 * 1000);
148         SET_BYTE(1, 0x05);
149         send_msg(&msg, fd, uc);
150         read_msgs(fd);
151
152         SET_FIRST_BYTE(0x02);
153         SET_BYTES(byte1);
154         SET_BYTES('|');
155         send_msg(&msg, fd, uc);
156         read_msgs(fd);
157
158         usleep(100 * 1000);
159         SET_BYTE(1, byte2);
160         send_msg(&msg, fd, uc);
161         read_msgs(fd);
162
163         return 0;
164 }
165
166 int communicate(int fd, int uc)
167 {
168         int i, j;
169         struct msg msg, in;
170         msg.direction = OUT;
171
172         read_msgs(fd);
173         SET_FIRST_BYTE(0x01);
174         SET_BYTES(0x04);
175         send_msg(&msg, fd, uc);
176
177         usleep(100 * 1000);
178         SET_BYTE(1, 0x06);
179         send_msg(&msg, fd, uc);
180         read_msgs(fd);
181
182         SET_BYTE(1, 0x15);
183         for (i = 0; i < 6; i++) {
184                 usleep(100 * 1000);
185                 send_msg(&msg, fd, uc);
186                 read_msgs(fd);
187         }
188         usleep(1000 * 1000);
189         read_msgs(fd);
190         send_msg(&msg, fd, uc);
191         read_msgs(fd);
192
193         usleep(100 * 1000);
194         SET_BYTE(1, 0x05);
195         send_msg(&msg, fd, uc);
196         read_msgs(fd);
197
198         send_pattern(fd, uc, 'R', 'A');
199         send_pattern(fd, uc, 'R', 'C');
200         send_pattern(fd, uc, 'R', 'D');
201         send_pattern(fd, uc, 'R', 'G');
202         send_pattern(fd, uc, 'R', 'I');
203         send_pattern(fd, uc, 'R', 'M');
204         send_pattern(fd, uc, 'R', 'P');
205         send_pattern(fd, uc, 'R', 'R');
206         send_pattern(fd, uc, 'R', 'S');
207         send_pattern(fd, uc, 'R', 'T');
208         send_pattern(fd, uc, 'R', 'U');
209         send_pattern(fd, uc, 'R', 'V');
210         send_pattern(fd, uc, 'R', 'W');
211         send_pattern(fd, uc, 'R', 'X');
212         send_pattern(fd, uc, 'W', 'K');
213
214         usleep(100 * 1000);
215         SET_FIRST_BYTE(0x08);
216         SET_BYTES('O');
217         SET_BYTES('b');
218         SET_BYTES('p');
219         SET_BYTES('s');
220         SET_BYTES('e');
221         SET_BYTES('c');
222         SET_BYTES('3');
223         SET_BYTES('|');
224         send_msg(&msg, fd, uc);
225         read_msgs(fd);
226
227         usleep(410 * 1000);
228         SET_FIRST_BYTE(0x02);
229         SET_BYTES('R');
230         SET_BYTES('|');
231         send_msg(&msg, fd, uc);
232         read_msgs(fd);
233
234         usleep(100 * 1000);
235         SET_BYTE(1, 'Y');
236         send_msg(&msg, fd, uc);
237         read_msgs(fd);
238
239         usleep(100 * 1000);
240         SET_BYTE(1, 'W');
241         send_msg(&msg, fd, uc);
242         read_msgs(fd);
243
244         usleep(100 * 1000);
245         SET_BYTE(1, 'K');
246         send_msg(&msg, fd, uc);
247         read_msgs(fd);
248
249         usleep(100 * 1000);
250         SET_BYTE(1, 'C');
251         send_msg(&msg, fd, uc);
252         read_msgs(fd);
253
254         send_pattern(fd, uc, 'R', 'Z');
255
256         usleep(100 * 1000);
257         SET_FIRST_BYTE(0x01);
258         SET_BYTES(0x04);
259         send_msg(&msg, fd, uc);
260         read_msgs(fd);
261
262         usleep(100 * 1000);
263         SET_BYTE(1, 0x15);
264         send_msg(&msg, fd, uc);
265         read_msgs(fd);
266
267         usleep(100 * 1000);
268         SET_BYTE(1, 0x05);
269         send_msg(&msg, fd, uc);
270         read_msgs(fd);
271
272         usleep(100 * 1000);
273         SET_BYTE(1, 0x04);
274         send_msg(&msg, fd, uc);
275         read_msgs(fd);
276
277         usleep(100 * 1000);
278         send_msg(&msg, fd, uc);
279         read_msgs(fd);
280
281         usleep(100 * 1000);
282         SET_BYTE(1, 0x06);
283         send_msg(&msg, fd, uc);
284         read_msgs(fd);
285
286         usleep(100 * 1000);
287         send_msg(&msg, fd, uc);
288         read_msgs(fd);
289
290         usleep(100 * 1000);
291         send_msg(&msg, fd, uc);
292         read_msgs(fd);
293
294         usleep(100 * 1000);
295         do {
296                 send_msg(&msg, fd, uc);
297                 read_and_verify(&in, fd);
298         } while (datalen(in.data) > 45);
299
300         return 0;
301 }
302
303 int main(int argc, char *argv[])
304 {
305         int fd, usage_code;
306
307         fd = hiddev_open(argv[1], &usage_code);
308         if (fd < 0)
309                 return 1;
310
311         communicate(fd, usage_code);
312
313         return 0;
314 }