From f6d105d68b46ab635628b2d799085537146d762c Mon Sep 17 00:00:00 2001 From: Michael Gernoth Date: Sun, 19 May 2013 10:29:39 +0000 Subject: [PATCH] parse time in extensionbyte --- Makefile | 2 +- fs20pcs.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 107 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 14f37d5..fbbbf8b 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CFLAGS=-O2 -Wall -I/opt/local/include -g -LDFLAGS=-L/opt/local/lib -lusb-1.0 +LDFLAGS=-L/opt/local/lib -lusb-1.0 -lm CC=gcc all: fs20pcs diff --git a/fs20pcs.c b/fs20pcs.c index d74d5b0..3f64a41 100644 --- a/fs20pcs.c +++ b/fs20pcs.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #define USB_TIMEOUT 10000 @@ -10,6 +11,8 @@ #define ID_VENDOR 0x18ef #define ID_PRODUCT 0xe015 +#define EXT_TO_SEC(ext) ((1 << ((ext & 0xf0) >> 4)) * (ext & 0x0f) * 0.25) + extern char *optarg; /* Not in all libusb-1.0 versions, so we have to roll our own :-( */ @@ -108,13 +111,13 @@ int fs20pcs_send(libusb_device_handle *devh, unsigned char* send_data) int i; int ret; - err = libusb_interrupt_transfer(devh, 0x01, send_data, 11, &cnt, 5000); + err = libusb_interrupt_transfer(devh, 0x01, send_data, 11, &cnt, USB_TIMEOUT); if (err) { fprintf(stderr, "Can't send data: %s\n", usb_strerror(err)); return 0; } - err = libusb_interrupt_transfer(devh, 0x81, recv_data, sizeof(recv_data), &cnt, 5000); + err = libusb_interrupt_transfer(devh, 0x81, recv_data, sizeof(recv_data), &cnt, USB_TIMEOUT); if (err) { fprintf(stderr, "Can't receive data: %s\n", usb_strerror(err)); return 0; @@ -303,6 +306,99 @@ int parse_command(char *cmd) return command; } +int parse_extension(char *ext) +{ + int extension = -1; + char *ep; + + if (ext == NULL) + return -1; + + if ((ext[strlen(ext)-1] == 's') || + (ext[strlen(ext)-1] == 'S')) { + double t; + double diff = 1; + uint8_t high = 0; + uint8_t low = 0; + uint8_t i; + + t = strtoul(ext, &ep, 10); + if ((*ep != 's') && (*ep != 'S')) { + fprintf(stderr, "Not a valid time in seconds: %s\n", ext); + return -1; + } + + /* time = 2^(high nibble) * (low nibble) * 0.25 , high may only be 12 */ + t /= 0.25; +#ifdef DEBUG + printf("t: %f\n", t); +#endif + + for(i = 1; i <= 0xf; i++) { + double h; + double l; + uint8_t i_l; + double d; + +#ifdef DEBUG + printf("i: 0x%01x\n", i); +#endif + + h = t / i; +#ifdef DEBUG + printf("h: %f\n", h); +#endif + + l = log2(h); +#ifdef DEBUG + printf("l: %f\n", l); +#endif + + i_l = l; + if (i_l > 12) + i_l = 12; + + d = l - i_l; + +#ifdef DEBUG + printf("d: %f\n", d); +#endif + + if (d < diff) { +#ifdef DEBUG + printf("Current best match!\n"); +#endif + diff = d; + high = l; + low = i; + } + } + +#ifdef DEBUG + printf("Got: %f, high: %01x, low: %01x\n", t, high, low); +#endif + + if ((high == 0) && (low == 0)) { + fprintf(stderr, "Can't find extension byte for %s!\n", ext); + return -1; + } + + extension = ((high & 0xf) << 4) | (low & 0xf); + } else { + unsigned long val; + + val = strtoul(ext, &ep, 16); + if (*ep != '\0') { + fprintf(stderr, "Not a 1 byte hexstring or time: %s\n", ext); + return -1; + } + + extension = val & 0xff; + } + + return extension; +} + void syntax(char *prog) { fprintf(stderr, "Syntax: %s options\n\n", prog); @@ -313,7 +409,7 @@ void syntax(char *prog) fprintf(stderr, "The following options need an housecode:\n"); fprintf(stderr, "\t-a [ELV|hex]\tdestination address\n"); fprintf(stderr, "\t-s [hex|alias]\tsend command byte\n"); - fprintf(stderr, "\t-e hex\t\textension byte for command\n"); + fprintf(stderr, "\t-e [hex|time]\textension byte for command or time in seconds (e.g. 10s)\n"); fprintf(stderr, "\t-r n\t\trepeat sending n times\n"); fprintf(stderr, "\nCommand bytes (without extension byte):\n"); fprintf(stderr, "hex\t\talias\tdescription\n"); @@ -372,7 +468,7 @@ int main(int argc, char **argv) int opt; int action = NO_ACTION; int command = -1; - uint8_t extension = 0x00; + int extension = 0; uint8_t repeat = 0; int addr = -1; @@ -434,8 +530,8 @@ int main(int argc, char **argv) #endif break; case 'e': - extension = strtoul(optarg, &ep, 16); - if (*ep != '\0') { + extension = parse_extension(optarg); + if (extension == -1) { fprintf(stderr, "Can't parse extension!\n"); exit(EXIT_FAILURE); } @@ -479,15 +575,15 @@ int main(int argc, char **argv) send_data[1] = 0x07; send_data[2] = 0xf2; send_data[8] = repeat; - printf("Sending 0x%02x 0x%02x to address %d (hc: 0x%02x%02x) (repeated %d times)\n", - command, extension, addr, + printf("Sending 0x%02x 0x%02x (%.2fs) to address %d (hc: 0x%02x%02x) (repeated %d times)\n", + command, extension, EXT_TO_SEC(extension), addr, housecode[0], housecode[1], repeat); } else { send_data[1] = 0x06; send_data[2] = 0xf1; - printf("Sending 0x%02x 0x%02x to address %d (hc: 0x%02x%02x)\n", - command, extension, addr, + printf("Sending 0x%02x 0x%02x (%.2fs) to address %d (hc: 0x%02x%02x)\n", + command, extension, EXT_TO_SEC(extension), addr, housecode[0], housecode[1]); } send_data[3] = housecode[0]; -- 2.39.2