]> git.itanic.dy.fi Git - glucose/commitdiff
Contour Next protocol, work in progress contour-next-testing
authorTimo Kokkonen <timo.t.kokkonen@iki.fi>
Wed, 1 Oct 2014 19:16:01 +0000 (22:16 +0300)
committerTimo Kokkonen <timo.t.kokkonen@iki.fi>
Wed, 1 Oct 2014 19:16:01 +0000 (22:16 +0300)
It dumps out the data now.

Signed-off-by: Timo Kokkonen <timo.t.kokkonen@iki.fi>
Makefile
contour-next-protocol.c [new file with mode: 0644]
contour-next-protocol.h [new file with mode: 0644]
main.c

index ea4f30ce5d68f629ff4a5b5c2a7118fad28d72fa..780535474847774521e0167e4317f775996e433f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 CC = gcc
 LD = ld
-CFLAGS = -Wall -O2 -g
+CFLAGS = -Wall -O2 -g $(shell pkg-config --libs --cflags libusb-1.0)
 
-GLUCOSE_OBJS = main.o hiddev.o utils.o options.o contour-protocol.o
+GLUCOSE_OBJS = main.o hiddev.o utils.o options.o contour-next-protocol.o
 
 ALL_OBJS = $(GLUCOSE_OBJS)
 ALL_DEBS = $(shell echo " "$(ALL_OBJS) | sed -e "s,[^ ]*\.a,,g" -e     \
@@ -22,7 +22,7 @@ endif
 all: glucose
 
 glucose: $(GLUCOSE_OBJS)
-       $(QUIET_LINK)$(CC) -lusb $(CFLAGS) -o $@ $^
+       $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $^
 
 clean:
        rm -vf glucose *~ *.o .*.d
diff --git a/contour-next-protocol.c b/contour-next-protocol.c
new file mode 100644 (file)
index 0000000..5b5cb6b
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2014 Timo Kokkonen <timo.t.kokkonen@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include <libusb.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "contour-next-protocol.h"
+#include "utils.h"
+
+#define OUT_EP (4 | LIBUSB_ENDPOINT_OUT)
+#define IN_EP  (3 | LIBUSB_ENDPOINT_IN)
+
+static int send_msg(libusb_device_handle *dev_handle, unsigned char *msg)
+{
+       int ret, actual;
+
+       trace(2, "Sending message ");
+       print_hex(2, msg, MSG_LEN);
+
+       ret = libusb_interrupt_transfer(dev_handle, OUT_EP, msg,
+                                       MSG_LEN, &actual, 0);
+       if (ret || actual != MSG_LEN) {
+               trace(0, "Error sending msg: %d, actual %d\n", ret, actual);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int read_msg(libusb_device_handle *dev_handle, unsigned char *msg)
+{
+       int ret, actual;
+
+       ret = libusb_interrupt_transfer(dev_handle, IN_EP , msg,
+                                       MSG_LEN, &actual, 0);
+       if (ret || actual != MSG_LEN) {
+               trace(0, "Error reading message: %d, actual %d\n",
+                       ret, actual);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int send_init_msg(libusb_device_handle *dev_handle,
+                       unsigned char b0, unsigned char b1, unsigned char b2,
+                       int read_msgs)
+{
+       unsigned char msg[MSG_LEN];
+       int ret, i;
+       bzero(msg, sizeof(msg));
+       msg[3] = b0;
+       msg[4] = b1;
+       msg[5] = b2;
+
+       ret = send_msg(dev_handle, msg);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < read_msgs; i++) {
+               ret = read_msg(dev_handle, msg);
+               if (ret)
+                       return ret;
+
+               trace(1, "Reading intermediate msg %d of %d\n", i, read_msgs);
+               print_hex(3, msg, sizeof(msg));
+               print_ascii(2, msg, sizeof(msg));
+       }
+
+       return 0;
+}
+
+struct contour_next_init_sequence {
+       unsigned char b0, b1, b2;
+       int response_msgs;
+};
+
+static int send_init_messages(libusb_device_handle *dev_handle,
+                       struct contour_next_init_sequence *seq, int messages)
+{
+       int i, ret;
+
+       for (i = 0; i < messages; i++) {
+               if (!trace_level)
+                       trace(0, "\rInitializing %d/%d...", i, messages);
+
+               ret = send_init_msg(dev_handle,
+                               seq[i].b0, seq[i].b1, seq[i].b2,
+                               seq[i].response_msgs);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static struct contour_next_init_sequence seq[] = {
+       { 0x01, 0x04, 0x00, 6, },
+       { 0x01, 0x06, 0x00, 5, },
+       { 0x01, 0x15, 0x00, 5, },
+       { 0x01, 0x15, 0x00, 5, },
+       { 0x01, 0x15, 0x00, 5, },
+       { 0x01, 0x15, 0x00, 5, },
+       { 0x01, 0x15, 0x00, 5, },
+       { 0x01, 0x15, 0x00, 2, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x02, 0x52, 0x7C, 1, },
+       { 0x02, 0x41, 0x7C, 2, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x02, 0x52, 0x7C, 1, },
+       { 0x02, 0x43, 0x7C, 2, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x02, 0x52, 0x7C, 1, },
+       { 0x02, 0x44, 0x7C, 2, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x02, 0x52, 0x7C, 1, },
+       { 0x02, 0x47, 0x7C, 2, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x02, 0x52, 0x7C, 1, },
+       { 0x02, 0x49, 0x7C, 1, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x02, 0x52, 0x7C, 1, },
+       { 0x02, 0x4D, 0x7C, 2, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x02, 0x52, 0x7C, 1, },
+       { 0x02, 0x50, 0x7C, 2, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x02, 0x52, 0x7C, 1, },
+       { 0x02, 0x53, 0x7C, 2, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x02, 0x52, 0x7C, 1, },
+       { 0x02, 0x54, 0x7C, 2, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x02, 0x52, 0x7C, 1, },
+       { 0x02, 0x56, 0x7C, 2, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x02, 0x52, 0x7C, 1, },
+       { 0x02, 0x57, 0x7C, 2, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x02, 0x52, 0x7C, 1, },
+       { 0x02, 0x58, 0x7C, 2, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x02, 0x52, 0x7C, 1, },
+       { 0x02, 0x5A, 0x7C, 2, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x15, 0x00, 1, },
+       { 0x01, 0x05, 0x00, 1, },
+       { 0x01, 0x04, 0x00, 1, },
+       { 0x01, 0x04, 0x00, 6, },
+       { 0x01, 0x06, 0x00, 5, },
+       { 0x01, 0x06, 0x00, 1, },
+};
+
+static libusb_device_handle *dev_handle;
+
+int contour_next_initialize(void)
+{
+       libusb_device **devs;
+       int ret;
+
+       ret = libusb_init(NULL);
+       if (ret) {
+               printf("Failed to init libusb: %d\n", ret);
+               return 1;
+       }
+
+       ret = libusb_get_device_list(NULL, &devs);
+       if (ret < 0) {
+               printf("Failed to get device list: %d\n", ret);
+               return 1;
+       }
+
+       dev_handle = libusb_open_device_with_vid_pid(NULL, 0x1a79, 0x7410);
+       if (dev_handle == NULL) {
+               printf("Failed to open device\n");
+               return 1;
+       }
+
+       ret = libusb_kernel_driver_active(dev_handle, 0);
+       if (ret == 1) {
+               printf("Kernel Driver Active\n");
+
+               ret = libusb_detach_kernel_driver(dev_handle, 0);
+               if (ret == 0)
+                       printf("Kernel Driver Detached!\n");
+       }
+
+       ret = libusb_claim_interface(dev_handle, 0);
+       if (ret) {
+               printf("Failed to claim the interface: %d\n", ret);
+               return 1;
+       }
+
+       send_init_messages(dev_handle, seq, sizeof(seq)/sizeof(seq[0]));
+
+       return 0;
+
+       while (1) {
+               unsigned char msg[MSG_LEN];
+
+               bzero(msg, sizeof(msg));
+               msg[3] = 0x01;
+               msg[4] = 0x06;
+               msg[5] = 0x00;
+
+               ret = send_msg(dev_handle, msg);
+               if (ret)
+                       return ret;
+
+               ret = read_msg(dev_handle, msg);
+               if (ret)
+                       return ret;
+
+               print_ascii(0, msg, sizeof(msg));
+       }
+
+       return 0;
+}
+
+int contour_next_read_entry(unsigned char *msg)
+{
+       int ret;
+       bzero(msg, MSG_LEN);
+       msg[3] = 0x01;
+       msg[4] = 0x06;
+       msg[5] = 0x00;
+
+       ret = send_msg(dev_handle, msg);
+       if (ret)
+               return ret;
+
+       ret = read_msg(dev_handle, msg);
+       if (ret)
+               return ret;
+
+       return datalen(msg);
+}
diff --git a/contour-next-protocol.h b/contour-next-protocol.h
new file mode 100644 (file)
index 0000000..ec3d63b
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef CONTOUR_NEXT_PROTOCOL
+#define CONTOUR_NEXT_PROTOCOL
+
+#define MSG_LEN 64
+
+int contour_next_initialize(void);
+int contour_next_read_entry(unsigned char *msg);
+
+#endif
diff --git a/main.c b/main.c
index 442154b17022a31cbbada5ee10d2865d7174e64f..04247aeccbf858d5c8a19406dcead8c61898a396 100644 (file)
--- a/main.c
+++ b/main.c
@@ -30,7 +30,7 @@
 #include "hiddev.h"
 #include "utils.h"
 #include "options.h"
-#include "contour-protocol.h"
+#include "contour-next-protocol.h"
 
 static char *token(char **str, char sep)
 {
@@ -40,14 +40,14 @@ static char *token(char **str, char sep)
        for (cur = start; *cur && (*cur != sep); ++cur);
 
        *cur = 0;
-       *str = cur+1;
+       *str = cur + 1;
 
        return start;
 }
 
-static void format_csv(struct user_options *opts, struct msg *msg)
+static void format_csv(struct user_options *opts, unsigned char *msg)
 {
-       char *tok = (char *) msg->data;
+       char *tok = (char *)msg;
                          token(&tok, '|');  // unknown
        char *seq       = token(&tok, '|');
        char *type      = token(&tok, '|');
@@ -58,7 +58,7 @@ static void format_csv(struct user_options *opts, struct msg *msg)
                          token(&tok, '|');// unknown
        char *time      = token(&tok, '\r');
 
-       unit[strlen(unit)-2] = 0;
+       unit[strlen(unit) - 2] = 0;
        fprintf(opts->outf,
                "%s,\"%.4s-%.2s-%.2s %.2s:%.2s\",\"%s\",\"%s\",\"%s\","
                "%s,%s,%s,%s,%s,%s,%s\n",
@@ -74,7 +74,8 @@ static void format_csv(struct user_options *opts, struct msg *msg)
                );
 }
 
-static int format_message(struct user_options *opts, struct msg *msg, int len)
+static int format_message(struct user_options *opts,
+                       unsigned char *msg, int len)
 {
        switch (opts->output_format)
        {
@@ -83,12 +84,12 @@ static int format_message(struct user_options *opts, struct msg *msg, int len)
                break;
 
        case CLEAN:
-               sanitize_ascii(msg->data, len);
-               fprintf(opts->outf, "%s\n", msg->data);
+               sanitize_ascii(msg, len);
+               fprintf(opts->outf, "%s\n", msg);
                break;
 
        case RAW:
-               fprintf(opts->outf, "%s", msg->data);
+               fprintf(opts->outf, "%s", msg);
                break;
 
        default:
@@ -102,12 +103,11 @@ static int format_message(struct user_options *opts, struct msg *msg, int len)
        return 0;
 }
 
-static int dump_entries(struct user_options *opts, int fd, int usage_code)
+static int dump_entries(struct user_options *opts)
 {
-       struct msg msg;
+       unsigned char msg[64 + 1];
        int ret;
        int entries = 0;
-       int extra_delay = 0;
 
        trace(0, "Reading data ...\n");
        if (opts->output_format == CSV)
@@ -116,28 +116,17 @@ static int dump_entries(struct user_options *opts, int fd, int usage_code)
                        "Activity,\"Control test\"\n");
 
        while (1) {
-               ret = contour_read_entry(fd, usage_code, &msg, extra_delay);
+               ret = contour_next_read_entry(msg);
+               msg[MSG_LEN] = 0;
                if (ret < 45)
                        break;
 
-               ret = format_message(opts, &msg, ret);
+               ret = format_message(opts, msg, ret);
                if (ret < 0)
                        return ret;
 
                entries++;
 
-               /*
-                * Add 20ms magic sleep. This is needed especially for
-                * meters that have reached the internal limit of 2000
-                * glucose readings. We don't want to delay any other
-                * reads as it appears to be needed only for every
-                * 16th read.
-                */
-               if (!(entries % 16))
-                       extra_delay = 20;
-               else
-                       extra_delay = 0;
-
                if ((opts->outf != stdout) || !isatty(fileno(stdout))) {
                        trace(0, "\r%d entries", entries);
                        fflush(stdout);
@@ -151,12 +140,12 @@ static int dump_entries(struct user_options *opts, int fd, int usage_code)
 int main(int argc, char *argv[])
 {
        struct user_options opts;
-       int fd, usage_code, ret;
+       int ret;
 
        bzero(&opts, sizeof(opts));
        opts.output_format = CLEAN;
 
-       if ( read_args(argc, argv, &opts) )
+       if (read_args(argc, argv, &opts))
                return -1;
 
        trace_level = opts.trace_level;
@@ -172,18 +161,10 @@ int main(int argc, char *argv[])
                opts.outf = stdout;
        }
 
-       if (opts.usbdev == NULL)
-               fd = wait_for_device(CONTOUR_USB_VENDOR_ID,
-                               CONTOUR_USB_PRODUCT_ID, &usage_code);
-       else
-               fd = hiddev_open(opts.usbdev, &usage_code);
-       if (fd < 0)
-               return 1;
-
        trace(0, "Initializing ...\n");
-       contour_initialize(fd, usage_code);
+       contour_next_initialize();
 
-       ret = dump_entries(&opts, fd, usage_code);
+       ret = dump_entries(&opts);
 
        return ret ? 1 : 0;
 }