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