From 039cbd09c906d50c3595a8ea3ab3d244110387de Mon Sep 17 00:00:00 2001 From: Timo Kokkonen Date: Sun, 1 May 2011 16:36:21 +0300 Subject: [PATCH] Refactor Contour USB communication routines into separate file Signed-off-by: Timo Kokkonen --- Makefile | 2 +- contour-protocol.c | 291 ++++++++++++++++++++++++++++++++++++++++++++ contour-protocol.h | 21 ++++ main.c | 296 +-------------------------------------------- 4 files changed, 314 insertions(+), 296 deletions(-) create mode 100644 contour-protocol.c create mode 100644 contour-protocol.h diff --git a/Makefile b/Makefile index 190671e..929ac1d 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CC = gcc LD = ld CFLAGS = -Wall -O2 -g -GLUCOSE_OBJS = main.o hiddev.o utils.o options.o +GLUCOSE_OBJS = main.o hiddev.o utils.o options.o contour-protocol.o ALL_OBJS = $(GLUCOSE_OBJS) ALL_DEBS = $(shell echo " "$(ALL_OBJS) | sed -e "s,[^ ]*\.a,,g" -e \ diff --git a/contour-protocol.c b/contour-protocol.c new file mode 100644 index 0000000..87bc605 --- /dev/null +++ b/contour-protocol.c @@ -0,0 +1,291 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "hiddev.h" +#include "contour-protocol.h" +#include "utils.h" + +#define MAX_MSGS 103 + +static int send_msg(const struct msg *msg, int fd, int usage_code) +{ + int ret; + static int msg_count; + + if (msg->direction != OUT) { + trace(0, "Message direction is not OUT\n"); + exit(1); + } + if (trace_level < 1 && msg_count <= MAX_MSGS) { + trace(0, "\r%d%%", msg_count * 100 / MAX_MSGS); + fflush(stdout); + } + + usleep(30 * 1000); + trace(1, "Sending: "); + if (trace_level >= 3) + print_hex(msg->data + 1, datalen(msg->data) - 1); + if (trace_level >= 2) + print_ascii(msg->data + 1, datalen(msg->data) - 1); + + ret = hiddev_write(msg->data, fd, usage_code); + if (ret) + exit(1); + + msg_count++; + return 0; +} + +static int read_and_verify(struct msg *msg, int fd) +{ + unsigned char buf[64]; + int ret, offset = 0; + + while (offset < 64) { + ret = hiddev_read(buf + offset, sizeof(buf) - offset, fd); + + if (ret < 0) + goto err; + + offset += ret; + } + + memcpy(msg->data, buf, sizeof(buf)); + trace(2, "Got data %d: ", datalen(buf)); + if (trace_level >= 3) + print_hex(buf, datalen(buf)); + if (trace_level >= 2) + print_ascii(buf, datalen(buf)); +err: + return 0; +} + +static int read_msgs(int fd) +{ + struct msg msg; + while (1) { + read_and_verify(&msg, fd); + if (datalen(msg.data) <= 36) + break; + } + + return 0; +} + +#define SET_FIRST_BYTE(byte) \ + do { \ + memset(&msg.data, 0, sizeof(msg.data)); \ + msg.data[4] = (byte); \ + j = 5; \ + } while (0) + +#define SET_BYTE(idx, byte) \ + do { \ + msg.data[(idx) + 4] = (byte); \ + j = (idx) + 1; \ + } while (0) + +#define SET_BYTES(byte) msg.data[j++] = (byte) + +static int send_pattern(int fd, int uc, unsigned char byte1, unsigned char byte2) +{ + int j; + struct msg msg; + msg.direction = OUT; + + usleep(100 * 1000); + SET_FIRST_BYTE(0x01); + SET_BYTES(0x04); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(250 * 1000); + SET_BYTE(1, 0x15); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(100 * 1000); + SET_BYTE(1, 0x05); + send_msg(&msg, fd, uc); + read_msgs(fd); + + SET_FIRST_BYTE(0x02); + SET_BYTES(byte1); + SET_BYTES('|'); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(100 * 1000); + SET_BYTE(1, byte2); + send_msg(&msg, fd, uc); + read_msgs(fd); + + return 0; +} + +int communicate(int fd, int uc) +{ + int i, j; + struct msg msg, in; + msg.direction = OUT; + trace(0, "Initializing..\n"); + + read_msgs(fd); + SET_FIRST_BYTE(0x01); + SET_BYTES(0x04); + send_msg(&msg, fd, uc); + + usleep(100 * 1000); + SET_BYTE(1, 0x06); + send_msg(&msg, fd, uc); + read_msgs(fd); + + SET_BYTE(1, 0x15); + for (i = 0; i < 6; i++) { + usleep(100 * 1000); + send_msg(&msg, fd, uc); + read_msgs(fd); + } + usleep(1000 * 1000); + read_msgs(fd); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(100 * 1000); + SET_BYTE(1, 0x05); + send_msg(&msg, fd, uc); + read_msgs(fd); + + send_pattern(fd, uc, 'R', 'A'); + send_pattern(fd, uc, 'R', 'C'); + send_pattern(fd, uc, 'R', 'D'); + send_pattern(fd, uc, 'R', 'G'); + send_pattern(fd, uc, 'R', 'I'); + send_pattern(fd, uc, 'R', 'M'); + send_pattern(fd, uc, 'R', 'P'); + send_pattern(fd, uc, 'R', 'R'); + send_pattern(fd, uc, 'R', 'S'); + send_pattern(fd, uc, 'R', 'T'); + send_pattern(fd, uc, 'R', 'U'); + send_pattern(fd, uc, 'R', 'V'); + send_pattern(fd, uc, 'R', 'W'); + send_pattern(fd, uc, 'R', 'X'); + send_pattern(fd, uc, 'W', 'K'); + + usleep(100 * 1000); + SET_FIRST_BYTE(0x08); + SET_BYTES('O'); + SET_BYTES('b'); + SET_BYTES('p'); + SET_BYTES('s'); + SET_BYTES('e'); + SET_BYTES('c'); + SET_BYTES('3'); + SET_BYTES('|'); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(410 * 1000); + SET_FIRST_BYTE(0x02); + SET_BYTES('R'); + SET_BYTES('|'); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(100 * 1000); + SET_BYTE(1, 'Y'); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(100 * 1000); + SET_BYTE(1, 'W'); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(100 * 1000); + SET_BYTE(1, 'K'); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(100 * 1000); + SET_BYTE(1, 'C'); + send_msg(&msg, fd, uc); + read_msgs(fd); + + send_pattern(fd, uc, 'R', 'Z'); + + usleep(100 * 1000); + SET_FIRST_BYTE(0x01); + SET_BYTES(0x04); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(100 * 1000); + SET_BYTE(1, 0x15); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(100 * 1000); + SET_BYTE(1, 0x05); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(100 * 1000); + SET_BYTE(1, 0x04); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(100 * 1000); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(100 * 1000); + SET_BYTE(1, 0x06); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(100 * 1000); + send_msg(&msg, fd, uc); + read_msgs(fd); + + usleep(100 * 1000); + send_msg(&msg, fd, uc); + read_msgs(fd); + + trace(0, "\nGlucose readings:\n"); + usleep(100 * 1000); + do { + send_msg(&msg, fd, uc); + read_and_verify(&in, fd); + print_ascii(in.data, datalen(in.data)); + } while (datalen(in.data) > 45); + + return 0; +} + +int wait_for_device(int vendor, int product, int *usage_code) +{ + int fd; + + fd = hiddev_open_by_id(vendor, product, usage_code); + + if (fd > 0) + return fd; + + trace(0, + "No suitable device found. Please plug in your glucose meter\n"); + do { + usleep(500 * 1000); + fd = hiddev_open_by_id(vendor, product, usage_code); + } while(fd < 0); + + usleep(2000 * 1000); + + return fd; +} + diff --git a/contour-protocol.h b/contour-protocol.h new file mode 100644 index 0000000..049ccc9 --- /dev/null +++ b/contour-protocol.h @@ -0,0 +1,21 @@ +#ifndef _CONTOUR_USB_H +#define _CONTOUR_USB_H + +#define CONTOUR_USB_VENDOR_ID 0x1a79 +#define CONTOUR_USB_PRODUCT_ID 0x6002 + +struct msg { + int direction; + unsigned char data[64]; +}; + +enum direction { + IN = 666, + OUT, +}; + +int communicate(int fd, int uc); +int wait_for_device(int vendor, int product, int *usage_code); + + +#endif diff --git a/main.c b/main.c index bfa1545..76b32d7 100644 --- a/main.c +++ b/main.c @@ -2,306 +2,12 @@ #include #include #include -#include #include -#include -#include #include "hiddev.h" #include "utils.h" #include "options.h" - -#define CONTOUR_USB_VENDOR_ID 0x1a79 -#define CONTOUR_USB_PRODUCT_ID 0x6002 - -#define MAX_MSGS 103 - -struct msg { - int direction; - unsigned char data[64]; -}; - -enum direction { - IN = 666, - OUT, -}; - -int send_msg(const struct msg *msg, int fd, int usage_code) -{ - int ret; - static int msg_count; - - if (msg->direction != OUT) { - trace(0, "Message direction is not OUT\n"); - exit(1); - } - if (trace_level < 1 && msg_count <= MAX_MSGS) { - trace(0, "\r%d%%", msg_count * 100 / MAX_MSGS); - fflush(stdout); - } - - usleep(30 * 1000); - trace(1, "Sending: "); - if (trace_level >= 3) - print_hex(msg->data + 1, datalen(msg->data) - 1); - if (trace_level >= 2) - print_ascii(msg->data + 1, datalen(msg->data) - 1); - - ret = hiddev_write(msg->data, fd, usage_code); - if (ret) - exit(1); - - msg_count++; - return 0; -} - -int read_and_verify(struct msg *msg, int fd) -{ - unsigned char buf[64]; - int ret, offset = 0; - - while (offset < 64) { - ret = hiddev_read(buf + offset, sizeof(buf) - offset, fd); - - if (ret < 0) - goto err; - - offset += ret; - } - - memcpy(msg->data, buf, sizeof(buf)); - trace(2, "Got data %d: ", datalen(buf)); - if (trace_level >= 3) - print_hex(buf, datalen(buf)); - if (trace_level >= 2) - print_ascii(buf, datalen(buf)); -err: - return 0; -} - -int read_msgs(int fd) -{ - struct msg msg; - while (1) { - read_and_verify(&msg, fd); - if (datalen(msg.data) <= 36) - break; - } - - return 0; -} - -#define SET_FIRST_BYTE(byte) \ - do { \ - memset(&msg.data, 0, sizeof(msg.data)); \ - msg.data[4] = (byte); \ - j = 5; \ - } while (0) - -#define SET_BYTE(idx, byte) \ - do { \ - msg.data[(idx) + 4] = (byte); \ - j = (idx) + 1; \ - } while (0) - -#define SET_BYTES(byte) msg.data[j++] = (byte) - -int send_pattern(int fd, int uc, unsigned char byte1, unsigned char byte2) -{ - int j; - struct msg msg; - msg.direction = OUT; - - usleep(100 * 1000); - SET_FIRST_BYTE(0x01); - SET_BYTES(0x04); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(250 * 1000); - SET_BYTE(1, 0x15); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(100 * 1000); - SET_BYTE(1, 0x05); - send_msg(&msg, fd, uc); - read_msgs(fd); - - SET_FIRST_BYTE(0x02); - SET_BYTES(byte1); - SET_BYTES('|'); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(100 * 1000); - SET_BYTE(1, byte2); - send_msg(&msg, fd, uc); - read_msgs(fd); - - return 0; -} - -int communicate(int fd, int uc) -{ - int i, j; - struct msg msg, in; - msg.direction = OUT; - trace(0, "Initializing..\n"); - - read_msgs(fd); - SET_FIRST_BYTE(0x01); - SET_BYTES(0x04); - send_msg(&msg, fd, uc); - - usleep(100 * 1000); - SET_BYTE(1, 0x06); - send_msg(&msg, fd, uc); - read_msgs(fd); - - SET_BYTE(1, 0x15); - for (i = 0; i < 6; i++) { - usleep(100 * 1000); - send_msg(&msg, fd, uc); - read_msgs(fd); - } - usleep(1000 * 1000); - read_msgs(fd); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(100 * 1000); - SET_BYTE(1, 0x05); - send_msg(&msg, fd, uc); - read_msgs(fd); - - send_pattern(fd, uc, 'R', 'A'); - send_pattern(fd, uc, 'R', 'C'); - send_pattern(fd, uc, 'R', 'D'); - send_pattern(fd, uc, 'R', 'G'); - send_pattern(fd, uc, 'R', 'I'); - send_pattern(fd, uc, 'R', 'M'); - send_pattern(fd, uc, 'R', 'P'); - send_pattern(fd, uc, 'R', 'R'); - send_pattern(fd, uc, 'R', 'S'); - send_pattern(fd, uc, 'R', 'T'); - send_pattern(fd, uc, 'R', 'U'); - send_pattern(fd, uc, 'R', 'V'); - send_pattern(fd, uc, 'R', 'W'); - send_pattern(fd, uc, 'R', 'X'); - send_pattern(fd, uc, 'W', 'K'); - - usleep(100 * 1000); - SET_FIRST_BYTE(0x08); - SET_BYTES('O'); - SET_BYTES('b'); - SET_BYTES('p'); - SET_BYTES('s'); - SET_BYTES('e'); - SET_BYTES('c'); - SET_BYTES('3'); - SET_BYTES('|'); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(410 * 1000); - SET_FIRST_BYTE(0x02); - SET_BYTES('R'); - SET_BYTES('|'); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(100 * 1000); - SET_BYTE(1, 'Y'); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(100 * 1000); - SET_BYTE(1, 'W'); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(100 * 1000); - SET_BYTE(1, 'K'); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(100 * 1000); - SET_BYTE(1, 'C'); - send_msg(&msg, fd, uc); - read_msgs(fd); - - send_pattern(fd, uc, 'R', 'Z'); - - usleep(100 * 1000); - SET_FIRST_BYTE(0x01); - SET_BYTES(0x04); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(100 * 1000); - SET_BYTE(1, 0x15); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(100 * 1000); - SET_BYTE(1, 0x05); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(100 * 1000); - SET_BYTE(1, 0x04); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(100 * 1000); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(100 * 1000); - SET_BYTE(1, 0x06); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(100 * 1000); - send_msg(&msg, fd, uc); - read_msgs(fd); - - usleep(100 * 1000); - send_msg(&msg, fd, uc); - read_msgs(fd); - - trace(0, "\nGlucose readings:\n"); - usleep(100 * 1000); - do { - send_msg(&msg, fd, uc); - read_and_verify(&in, fd); - print_ascii(in.data, datalen(in.data)); - } while (datalen(in.data) > 45); - - return 0; -} - -int wait_for_device(int vendor, int product, int *usage_code) -{ - int fd; - - fd = hiddev_open_by_id(vendor, product, usage_code); - - if (fd > 0) - return fd; - - trace(0, - "No suitable device found. Please plug in your glucose meter\n"); - do { - usleep(500 * 1000); - fd = hiddev_open_by_id(vendor, product, usage_code); - } while(fd < 0); - - usleep(2000 * 1000); - - return fd; -} +#include "contour-protocol.h" int main(int argc, char *argv[]) { -- 2.44.0