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