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