]> git.itanic.dy.fi Git - glucose/blob - contour-protocol.c
Replace existing printf functions with trace(...)
[glucose] / contour-protocol.c
1 /*
2  * Copyright (C) 2012 Timo Kokkonen <timo.t.kokkonen@iki.fi>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17  * USA
18  */
19
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <linux/types.h>
23 #include <linux/hiddev.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <time.h>
27
28 #include "hiddev.h"
29 #include "contour-protocol.h"
30 #include "utils.h"
31
32 #define MAX_MSGS        103
33
34 static int send_msg(const struct msg *msg, int fd, int usage_code)
35 {
36         int ret;
37         if (msg->direction != OUT) {
38                 trace(0, "Message direction is not OUT\n");
39                 exit(1);
40         }
41
42         usleep(30 * 1000);
43
44         trace(1, "Sending: ");
45         print_hex(3, msg->data + 1, datalen(msg->data) - 1);
46         print_ascii(2, msg->data + 1, datalen(msg->data) - 1);
47
48         ret = hiddev_write(msg->data, fd, usage_code);
49         if (ret)
50                 exit(1);
51
52         return 0;
53 }
54
55 static int send_msg_with_proggress_note(const struct msg *msg, int fd,
56                                         int usage_code)
57 {
58         static int msg_count;
59
60         if (trace_level < 1 && msg_count <= MAX_MSGS) {
61                 trace(0, "\r%d%%", msg_count * 100 / MAX_MSGS);
62                 fflush(stdout);
63         }
64
65         msg_count++;
66
67         return send_msg(msg, fd, usage_code);
68 }
69
70 static int read_and_verify(struct msg *msg, int fd)
71 {
72         unsigned char buf[64];
73         int ret, offset = 0;
74
75         while (offset < 64) {
76                 ret = hiddev_read(buf + offset, sizeof(buf) - offset, fd);
77
78                 if (ret < 0)
79                         goto err;
80
81                 offset += ret;
82         }
83
84         memcpy(msg->data, buf, sizeof(buf));
85         memset(&msg->data[sizeof(buf)], 0, sizeof(msg->data)-sizeof(buf));
86
87         trace(2, "Got data %d: ", datalen(buf));
88         print_hex(3, buf, datalen(buf));
89         print_ascii(2, buf, datalen(buf));
90 err:
91         return 0;
92 }
93
94 static int read_msgs(int fd)
95 {
96         struct msg msg;
97         while (1) {
98                 read_and_verify(&msg, fd);
99                 if (datalen(msg.data) <= 36)
100                         break;
101         }
102
103         return 0;
104 }
105
106 static void set_first_msg_byte(struct msg *msg, int *idx, char byte)
107 {
108         memset(msg->data, 0, sizeof(msg->data));
109         msg->data[4] = (byte);
110
111         *idx = 5;
112 }
113
114 static void set_msg_byte(struct msg *msg, int *idx, int where, char byte)
115 {
116         msg->data[where + 4] = byte;
117         *idx = where + 1;
118 }
119
120 #define SET_BYTES(byte) msg.data[j++] = (byte)
121
122 static int send_pattern(int fd, int uc, unsigned char byte1, unsigned char byte2)
123 {
124         int j;
125         struct msg msg;
126         msg.direction = OUT;
127
128         usleep(100 * 1000);
129         set_first_msg_byte(&msg, &j, 0x01);
130         SET_BYTES(0x04);
131         send_msg_with_proggress_note(&msg, fd, uc);
132         read_msgs(fd);
133
134         usleep(250 * 1000);
135         set_msg_byte(&msg, &j, 1, 0x15);
136         send_msg_with_proggress_note(&msg, fd, uc);
137         read_msgs(fd);
138
139         usleep(100 * 1000);
140         set_msg_byte(&msg, &j, 1, 0x05);
141         send_msg_with_proggress_note(&msg, fd, uc);
142         read_msgs(fd);
143
144         set_first_msg_byte(&msg, &j, 0x02);
145         SET_BYTES(byte1);
146         SET_BYTES('|');
147         send_msg_with_proggress_note(&msg, fd, uc);
148         read_msgs(fd);
149
150         usleep(100 * 1000);
151         set_msg_byte(&msg, &j, 1, byte2);
152         send_msg_with_proggress_note(&msg, fd, uc);
153         read_msgs(fd);
154
155         return 0;
156 }
157
158 int contour_initialize(int fd, int uc)
159 {
160         int i, j;
161         struct msg msg;
162         msg.direction = OUT;
163
164         read_msgs(fd);
165         set_first_msg_byte(&msg, &j, 0x01);
166         SET_BYTES(0x04);
167         send_msg_with_proggress_note(&msg, fd, uc);
168
169         usleep(100 * 1000);
170         set_msg_byte(&msg, &j, 1, 0x06);
171         send_msg_with_proggress_note(&msg, fd, uc);
172         read_msgs(fd);
173
174         set_msg_byte(&msg, &j, 1, 0x15);
175         for (i = 0; i < 6; i++) {
176                 usleep(100 * 1000);
177                 send_msg_with_proggress_note(&msg, fd, uc);
178                 read_msgs(fd);
179         }
180         usleep(1000 * 1000);
181         read_msgs(fd);
182         send_msg_with_proggress_note(&msg, fd, uc);
183         read_msgs(fd);
184
185         usleep(100 * 1000);
186         set_msg_byte(&msg, &j, 1, 0x05);
187         send_msg_with_proggress_note(&msg, fd, uc);
188         read_msgs(fd);
189
190         send_pattern(fd, uc, 'R', 'A');
191         send_pattern(fd, uc, 'R', 'C');
192         send_pattern(fd, uc, 'R', 'D');
193         send_pattern(fd, uc, 'R', 'G');
194         send_pattern(fd, uc, 'R', 'I');
195         send_pattern(fd, uc, 'R', 'M');
196         send_pattern(fd, uc, 'R', 'P');
197         send_pattern(fd, uc, 'R', 'R');
198         send_pattern(fd, uc, 'R', 'S');
199         send_pattern(fd, uc, 'R', 'T');
200         send_pattern(fd, uc, 'R', 'U');
201         send_pattern(fd, uc, 'R', 'V');
202         send_pattern(fd, uc, 'R', 'W');
203         send_pattern(fd, uc, 'R', 'X');
204         send_pattern(fd, uc, 'W', 'K');
205
206         usleep(100 * 1000);
207         set_first_msg_byte(&msg, &j, 0x08);
208         SET_BYTES('O');
209         SET_BYTES('b');
210         SET_BYTES('p');
211         SET_BYTES('s');
212         SET_BYTES('e');
213         SET_BYTES('c');
214         SET_BYTES('3');
215         SET_BYTES('|');
216         send_msg_with_proggress_note(&msg, fd, uc);
217         read_msgs(fd);
218
219         usleep(410 * 1000);
220         set_first_msg_byte(&msg, &j, 0x02);
221         SET_BYTES('R');
222         SET_BYTES('|');
223         send_msg_with_proggress_note(&msg, fd, uc);
224         read_msgs(fd);
225
226         usleep(100 * 1000);
227         set_msg_byte(&msg, &j, 1, 'Y');
228         send_msg_with_proggress_note(&msg, fd, uc);
229         read_msgs(fd);
230
231         usleep(100 * 1000);
232         set_msg_byte(&msg, &j, 1, 'W');
233         send_msg_with_proggress_note(&msg, fd, uc);
234         read_msgs(fd);
235
236         usleep(100 * 1000);
237         set_msg_byte(&msg, &j, 1, 'K');
238         send_msg_with_proggress_note(&msg, fd, uc);
239         read_msgs(fd);
240
241         usleep(100 * 1000);
242         set_msg_byte(&msg, &j, 1, 'C');
243         send_msg_with_proggress_note(&msg, fd, uc);
244         read_msgs(fd);
245
246         send_pattern(fd, uc, 'R', 'Z');
247
248         usleep(100 * 1000);
249         set_first_msg_byte(&msg, &j, 0x01);
250         SET_BYTES(0x04);
251         send_msg_with_proggress_note(&msg, fd, uc);
252         read_msgs(fd);
253
254         usleep(100 * 1000);
255         set_msg_byte(&msg, &j, 1, 0x15);
256         send_msg_with_proggress_note(&msg, fd, uc);
257         read_msgs(fd);
258
259         usleep(100 * 1000);
260         set_msg_byte(&msg, &j, 1, 0x05);
261         send_msg_with_proggress_note(&msg, fd, uc);
262         read_msgs(fd);
263
264         usleep(100 * 1000);
265         set_msg_byte(&msg, &j, 1, 0x04);
266         send_msg_with_proggress_note(&msg, fd, uc);
267         read_msgs(fd);
268
269         usleep(100 * 1000);
270         send_msg_with_proggress_note(&msg, fd, uc);
271         read_msgs(fd);
272
273         usleep(100 * 1000);
274         set_msg_byte(&msg, &j, 1, 0x06);
275         send_msg_with_proggress_note(&msg, fd, uc);
276         read_msgs(fd);
277
278         usleep(100 * 1000);
279         send_msg_with_proggress_note(&msg, fd, uc);
280         read_msgs(fd);
281
282         usleep(100 * 1000);
283         send_msg_with_proggress_note(&msg, fd, uc);
284         read_msgs(fd);
285
286         usleep(100 * 1000);
287
288         trace(0, "\n");
289         return 0;
290 }
291
292 int contour_read_entry(int fd, int uc, struct msg *in)
293 {
294         struct msg msg;
295         int j;
296
297         msg.direction = OUT;
298         set_first_msg_byte(&msg, &j, 0x01);
299         set_msg_byte(&msg, &j, 1, 0x06);
300         send_msg(&msg, fd, uc);
301
302         read_and_verify(in, fd);
303         return datalen(in->data);
304 }
305
306 int wait_for_device(int vendor, int product, int *usage_code)
307 {
308         int fd;
309
310         fd = hiddev_open_by_id(vendor, product, usage_code);
311
312         if (fd > 0)
313                 return fd;
314
315         trace(0,
316                "No suitable device found. Please plug in your glucose meter\n");
317         do {
318                 usleep(500 * 1000);
319                 fd = hiddev_open_by_id(vendor, product, usage_code);
320         } while(fd < 0);
321
322         usleep(2000 * 1000);
323
324         return fd;
325 }
326