]> git.itanic.dy.fi Git - glucose/blob - contour-next-protocol.c
Contour Next protocol, work in progress
[glucose] / contour-next-protocol.c
1 /*
2  * Copyright (C) 2014 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 <libusb.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <unistd.h>
24
25 #include "contour-next-protocol.h"
26 #include "utils.h"
27
28 #define OUT_EP  (4 | LIBUSB_ENDPOINT_OUT)
29 #define IN_EP   (3 | LIBUSB_ENDPOINT_IN)
30
31 static int send_msg(libusb_device_handle *dev_handle, unsigned char *msg)
32 {
33         int ret, actual;
34
35         trace(2, "Sending message ");
36         print_hex(2, msg, MSG_LEN);
37
38         ret = libusb_interrupt_transfer(dev_handle, OUT_EP, msg,
39                                         MSG_LEN, &actual, 0);
40         if (ret || actual != MSG_LEN) {
41                 trace(0, "Error sending msg: %d, actual %d\n", ret, actual);
42                 return -1;
43         }
44
45         return 0;
46 }
47
48 static int read_msg(libusb_device_handle *dev_handle, unsigned char *msg)
49 {
50         int ret, actual;
51
52         ret = libusb_interrupt_transfer(dev_handle, IN_EP , msg,
53                                         MSG_LEN, &actual, 0);
54         if (ret || actual != MSG_LEN) {
55                 trace(0, "Error reading message: %d, actual %d\n",
56                         ret, actual);
57                 return -1;
58         }
59
60         return 0;
61 }
62
63 static int send_init_msg(libusb_device_handle *dev_handle,
64                         unsigned char b0, unsigned char b1, unsigned char b2,
65                         int read_msgs)
66 {
67         unsigned char msg[MSG_LEN];
68         int ret, i;
69         bzero(msg, sizeof(msg));
70         msg[3] = b0;
71         msg[4] = b1;
72         msg[5] = b2;
73
74         ret = send_msg(dev_handle, msg);
75         if (ret)
76                 return ret;
77
78         for (i = 0; i < read_msgs; i++) {
79                 ret = read_msg(dev_handle, msg);
80                 if (ret)
81                         return ret;
82
83                 trace(1, "Reading intermediate msg %d of %d\n", i, read_msgs);
84                 print_hex(3, msg, sizeof(msg));
85                 print_ascii(2, msg, sizeof(msg));
86         }
87
88         return 0;
89 }
90
91 struct contour_next_init_sequence {
92         unsigned char b0, b1, b2;
93         int response_msgs;
94 };
95
96 static int send_init_messages(libusb_device_handle *dev_handle,
97                         struct contour_next_init_sequence *seq, int messages)
98 {
99         int i, ret;
100
101         for (i = 0; i < messages; i++) {
102                 if (!trace_level)
103                         trace(0, "\rInitializing %d/%d...", i, messages);
104
105                 ret = send_init_msg(dev_handle,
106                                 seq[i].b0, seq[i].b1, seq[i].b2,
107                                 seq[i].response_msgs);
108                 if (ret)
109                         return ret;
110         }
111
112         return 0;
113 }
114
115 static struct contour_next_init_sequence seq[] = {
116         { 0x01, 0x04, 0x00, 6, },
117         { 0x01, 0x06, 0x00, 5, },
118         { 0x01, 0x15, 0x00, 5, },
119         { 0x01, 0x15, 0x00, 5, },
120         { 0x01, 0x15, 0x00, 5, },
121         { 0x01, 0x15, 0x00, 5, },
122         { 0x01, 0x15, 0x00, 5, },
123         { 0x01, 0x15, 0x00, 2, },
124         { 0x01, 0x15, 0x00, 1, },
125         { 0x01, 0x05, 0x00, 1, },
126         { 0x01, 0x04, 0x00, 1, },
127         { 0x01, 0x15, 0x00, 1, },
128         { 0x01, 0x05, 0x00, 1, },
129         { 0x02, 0x52, 0x7C, 1, },
130         { 0x02, 0x41, 0x7C, 2, },
131         { 0x01, 0x04, 0x00, 1, },
132         { 0x01, 0x15, 0x00, 1, },
133         { 0x01, 0x05, 0x00, 1, },
134         { 0x02, 0x52, 0x7C, 1, },
135         { 0x02, 0x43, 0x7C, 2, },
136         { 0x01, 0x04, 0x00, 1, },
137         { 0x01, 0x15, 0x00, 1, },
138         { 0x01, 0x05, 0x00, 1, },
139         { 0x02, 0x52, 0x7C, 1, },
140         { 0x02, 0x44, 0x7C, 2, },
141         { 0x01, 0x04, 0x00, 1, },
142         { 0x01, 0x15, 0x00, 1, },
143         { 0x01, 0x05, 0x00, 1, },
144         { 0x02, 0x52, 0x7C, 1, },
145         { 0x02, 0x47, 0x7C, 2, },
146         { 0x01, 0x04, 0x00, 1, },
147         { 0x01, 0x15, 0x00, 1, },
148         { 0x01, 0x05, 0x00, 1, },
149         { 0x02, 0x52, 0x7C, 1, },
150         { 0x02, 0x49, 0x7C, 1, },
151         { 0x01, 0x04, 0x00, 1, },
152         { 0x01, 0x15, 0x00, 1, },
153         { 0x01, 0x05, 0x00, 1, },
154         { 0x02, 0x52, 0x7C, 1, },
155         { 0x02, 0x4D, 0x7C, 2, },
156         { 0x01, 0x04, 0x00, 1, },
157         { 0x01, 0x15, 0x00, 1, },
158         { 0x01, 0x05, 0x00, 1, },
159         { 0x02, 0x52, 0x7C, 1, },
160         { 0x02, 0x50, 0x7C, 2, },
161         { 0x01, 0x04, 0x00, 1, },
162         { 0x01, 0x15, 0x00, 1, },
163         { 0x01, 0x05, 0x00, 1, },
164         { 0x02, 0x52, 0x7C, 1, },
165         { 0x02, 0x53, 0x7C, 2, },
166         { 0x01, 0x04, 0x00, 1, },
167         { 0x01, 0x15, 0x00, 1, },
168         { 0x01, 0x05, 0x00, 1, },
169         { 0x02, 0x52, 0x7C, 1, },
170         { 0x02, 0x54, 0x7C, 2, },
171         { 0x01, 0x04, 0x00, 1, },
172         { 0x01, 0x15, 0x00, 1, },
173         { 0x01, 0x05, 0x00, 1, },
174         { 0x02, 0x52, 0x7C, 1, },
175         { 0x02, 0x56, 0x7C, 2, },
176         { 0x01, 0x04, 0x00, 1, },
177         { 0x01, 0x15, 0x00, 1, },
178         { 0x01, 0x05, 0x00, 1, },
179         { 0x02, 0x52, 0x7C, 1, },
180         { 0x02, 0x57, 0x7C, 2, },
181         { 0x01, 0x04, 0x00, 1, },
182         { 0x01, 0x15, 0x00, 1, },
183         { 0x01, 0x05, 0x00, 1, },
184         { 0x02, 0x52, 0x7C, 1, },
185         { 0x02, 0x58, 0x7C, 2, },
186         { 0x01, 0x04, 0x00, 1, },
187         { 0x01, 0x15, 0x00, 1, },
188         { 0x01, 0x05, 0x00, 1, },
189         { 0x02, 0x52, 0x7C, 1, },
190         { 0x02, 0x5A, 0x7C, 2, },
191         { 0x01, 0x04, 0x00, 1, },
192         { 0x01, 0x15, 0x00, 1, },
193         { 0x01, 0x05, 0x00, 1, },
194         { 0x01, 0x04, 0x00, 1, },
195         { 0x01, 0x04, 0x00, 6, },
196         { 0x01, 0x06, 0x00, 5, },
197         { 0x01, 0x06, 0x00, 1, },
198 };
199
200 static libusb_device_handle *dev_handle;
201
202 int contour_next_initialize(void)
203 {
204         libusb_device **devs;
205         int ret;
206
207         ret = libusb_init(NULL);
208         if (ret) {
209                 printf("Failed to init libusb: %d\n", ret);
210                 return 1;
211         }
212
213         ret = libusb_get_device_list(NULL, &devs);
214         if (ret < 0) {
215                 printf("Failed to get device list: %d\n", ret);
216                 return 1;
217         }
218
219         dev_handle = libusb_open_device_with_vid_pid(NULL, 0x1a79, 0x7410);
220         if (dev_handle == NULL) {
221                 printf("Failed to open device\n");
222                 return 1;
223         }
224
225         ret = libusb_kernel_driver_active(dev_handle, 0);
226         if (ret == 1) {
227                 printf("Kernel Driver Active\n");
228
229                 ret = libusb_detach_kernel_driver(dev_handle, 0);
230                 if (ret == 0)
231                         printf("Kernel Driver Detached!\n");
232         }
233
234         ret = libusb_claim_interface(dev_handle, 0);
235         if (ret) {
236                 printf("Failed to claim the interface: %d\n", ret);
237                 return 1;
238         }
239
240         send_init_messages(dev_handle, seq, sizeof(seq)/sizeof(seq[0]));
241
242         return 0;
243
244         while (1) {
245                 unsigned char msg[MSG_LEN];
246
247                 bzero(msg, sizeof(msg));
248                 msg[3] = 0x01;
249                 msg[4] = 0x06;
250                 msg[5] = 0x00;
251
252                 ret = send_msg(dev_handle, msg);
253                 if (ret)
254                         return ret;
255
256                 ret = read_msg(dev_handle, msg);
257                 if (ret)
258                         return ret;
259
260                 print_ascii(0, msg, sizeof(msg));
261         }
262
263         return 0;
264 }
265
266 int contour_next_read_entry(unsigned char *msg)
267 {
268         int ret;
269         bzero(msg, MSG_LEN);
270         msg[3] = 0x01;
271         msg[4] = 0x06;
272         msg[5] = 0x00;
273
274         ret = send_msg(dev_handle, msg);
275         if (ret)
276                 return ret;
277
278         ret = read_msg(dev_handle, msg);
279         if (ret)
280                 return ret;
281
282         return datalen(msg);
283 }