]> git.itanic.dy.fi Git - glucose/blob - contour-protocol.c
contour-protocol: Do not explicitly print out the proggress note
[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 communicate(int fd, int uc)
140 {
141         int i, j;
142         struct msg msg, in;
143         msg.direction = OUT;
144         trace(0, "Initializing..\n");
145
146         read_msgs(fd);
147         SET_FIRST_BYTE(0x01);
148         SET_BYTES(0x04);
149         send_msg_with_proggress_note(&msg, fd, uc);
150
151         usleep(100 * 1000);
152         SET_BYTE(1, 0x06);
153         send_msg_with_proggress_note(&msg, fd, uc);
154         read_msgs(fd);
155
156         SET_BYTE(1, 0x15);
157         for (i = 0; i < 6; i++) {
158                 usleep(100 * 1000);
159                 send_msg_with_proggress_note(&msg, fd, uc);
160                 read_msgs(fd);
161         }
162         usleep(1000 * 1000);
163         read_msgs(fd);
164         send_msg_with_proggress_note(&msg, fd, uc);
165         read_msgs(fd);
166
167         usleep(100 * 1000);
168         SET_BYTE(1, 0x05);
169         send_msg_with_proggress_note(&msg, fd, uc);
170         read_msgs(fd);
171
172         send_pattern(fd, uc, 'R', 'A');
173         send_pattern(fd, uc, 'R', 'C');
174         send_pattern(fd, uc, 'R', 'D');
175         send_pattern(fd, uc, 'R', 'G');
176         send_pattern(fd, uc, 'R', 'I');
177         send_pattern(fd, uc, 'R', 'M');
178         send_pattern(fd, uc, 'R', 'P');
179         send_pattern(fd, uc, 'R', 'R');
180         send_pattern(fd, uc, 'R', 'S');
181         send_pattern(fd, uc, 'R', 'T');
182         send_pattern(fd, uc, 'R', 'U');
183         send_pattern(fd, uc, 'R', 'V');
184         send_pattern(fd, uc, 'R', 'W');
185         send_pattern(fd, uc, 'R', 'X');
186         send_pattern(fd, uc, 'W', 'K');
187
188         usleep(100 * 1000);
189         SET_FIRST_BYTE(0x08);
190         SET_BYTES('O');
191         SET_BYTES('b');
192         SET_BYTES('p');
193         SET_BYTES('s');
194         SET_BYTES('e');
195         SET_BYTES('c');
196         SET_BYTES('3');
197         SET_BYTES('|');
198         send_msg_with_proggress_note(&msg, fd, uc);
199         read_msgs(fd);
200
201         usleep(410 * 1000);
202         SET_FIRST_BYTE(0x02);
203         SET_BYTES('R');
204         SET_BYTES('|');
205         send_msg_with_proggress_note(&msg, fd, uc);
206         read_msgs(fd);
207
208         usleep(100 * 1000);
209         SET_BYTE(1, 'Y');
210         send_msg_with_proggress_note(&msg, fd, uc);
211         read_msgs(fd);
212
213         usleep(100 * 1000);
214         SET_BYTE(1, 'W');
215         send_msg_with_proggress_note(&msg, fd, uc);
216         read_msgs(fd);
217
218         usleep(100 * 1000);
219         SET_BYTE(1, 'K');
220         send_msg_with_proggress_note(&msg, fd, uc);
221         read_msgs(fd);
222
223         usleep(100 * 1000);
224         SET_BYTE(1, 'C');
225         send_msg_with_proggress_note(&msg, fd, uc);
226         read_msgs(fd);
227
228         send_pattern(fd, uc, 'R', 'Z');
229
230         usleep(100 * 1000);
231         SET_FIRST_BYTE(0x01);
232         SET_BYTES(0x04);
233         send_msg_with_proggress_note(&msg, fd, uc);
234         read_msgs(fd);
235
236         usleep(100 * 1000);
237         SET_BYTE(1, 0x15);
238         send_msg_with_proggress_note(&msg, fd, uc);
239         read_msgs(fd);
240
241         usleep(100 * 1000);
242         SET_BYTE(1, 0x05);
243         send_msg_with_proggress_note(&msg, fd, uc);
244         read_msgs(fd);
245
246         usleep(100 * 1000);
247         SET_BYTE(1, 0x04);
248         send_msg_with_proggress_note(&msg, fd, uc);
249         read_msgs(fd);
250
251         usleep(100 * 1000);
252         send_msg_with_proggress_note(&msg, fd, uc);
253         read_msgs(fd);
254
255         usleep(100 * 1000);
256         SET_BYTE(1, 0x06);
257         send_msg_with_proggress_note(&msg, fd, uc);
258         read_msgs(fd);
259
260         usleep(100 * 1000);
261         send_msg_with_proggress_note(&msg, fd, uc);
262         read_msgs(fd);
263
264         usleep(100 * 1000);
265         send_msg_with_proggress_note(&msg, fd, uc);
266         read_msgs(fd);
267
268         trace(0, "\nGlucose readings:\n");
269         usleep(100 * 1000);
270         do {
271                 send_msg(&msg, fd, uc);
272                 read_and_verify(&in, fd);
273                 print_ascii(in.data, datalen(in.data));
274         } while (datalen(in.data) > 45);
275
276         return 0;
277 }
278
279 int wait_for_device(int vendor, int product, int *usage_code)
280 {
281         int fd;
282
283         fd = hiddev_open_by_id(vendor, product, usage_code);
284
285         if (fd > 0)
286                 return fd;
287
288         trace(0,
289                "No suitable device found. Please plug in your glucose meter\n");
290         do {
291                 usleep(500 * 1000);
292                 fd = hiddev_open_by_id(vendor, product, usage_code);
293         } while(fd < 0);
294
295         usleep(2000 * 1000);
296
297         return fd;
298 }
299