diff --git a/blink1raw/Makefile b/blink1raw/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..e3fddc560ab2b0f689dd87e49ef584c561705631 --- /dev/null +++ b/blink1raw/Makefile @@ -0,0 +1,8 @@ + + +CC=gcc + +blink1raw: + $(CC) -o blink1raw blink1raw.c + +all: blink1raw diff --git a/blink1raw/README.txt b/blink1raw/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..a4c648f49bd5f504978e007bd3dea400d46fd543 --- /dev/null +++ b/blink1raw/README.txt @@ -0,0 +1,53 @@ + + +blink1raw -- use HIDRAW to talk to blink(1) +-------------------------------------------- +2012 - Frederick Roeber + +This tiny program is great for restricted environments like during machine installs + + +Some sample command lines: +% blink1 /dev/hidraw* % _ @1:255,0,0,1 @2:255,0,0,50 @3:255,100,0,1 +@4:255,100,0,50 +1 + +Arguments, in order: + /dev/hidraw* -- this gets shell-expanded into a list of devices. + The program will open each in turn, check if it's a blink(1), and + if so, it becomes the new target. If you have one such device, + this is an easy way of finding it. If you have multiple, whichever + is last will be the device. + + % -- clear all steps + @1: set step 1 to be "fade to red in 1 cs" 1/100 of a second is +short, so it flips to red. + @2: set step 2 to be "fade to red in 50 cs" which, since it's +already red, is "hold red for 50 cs" + @3: set step 3 to be "fade to yellow in 1 cs" i.e. flip to yellow + @4: set step 4 to be "fade to yellow in 50 cs" i.e. hold yellow for +another half second. + +1 -- begin playing at step 1 + +This is the pattern used when a machine need its key inserted. (I +haven't assigned others yet, but I'm imagining that every problem will +have its own pattern, so I can tell at a glance what's going on.) + + +% blink1 /dev/hidraw* =255,0,255,50 + +This just sets the found device to be green. It does this when the +boot key has been detected and accepted. + + +% blink1 /dev/hidraw* _ % @1:0,255,0,100 @2:0,0,0,100 @3:0,255,0,100 +@4:0,0,0,100 @5:0,255,0,100 @6:0,0,0,100 @7:0,0,0,1000 +1 + +This throbs its green three times (100 cs, i.e. 1 second, per fade-up +or -down), then holds black for 10 seconds. This happens when the +machine is happy and the key can be removed. The driver script waits +six seconds, then issues a + +% blink1 /dev/hidraw* _100 % + +which fades it off over 1 second, and clears the program. + diff --git a/blink1raw/blink1raw.c b/blink1raw/blink1raw.c new file mode 100644 index 0000000000000000000000000000000000000000..07a40d4e307183f78b6922d7d7b0fd7d1ee0e15f --- /dev/null +++ b/blink1raw/blink1raw.c @@ -0,0 +1,214 @@ +/* + * blinkraw.c + * + * fgmr 2012-09-22 + * + * playing with the hidraw interface to blink(1) + * + * Thank you Alan Ott for + * http://lxr.free-electrons.com/source/samples/hidraw/hid-example.c + */ + +#include <linux/types.h> +#include <linux/input.h> +#include <linux/hidraw.h> + +#ifndef HIDIOCSFEATURE +#define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len) +#define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len) +#endif /* HIDIOCSFEATURE */ + +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <stdarg.h> +#include <ctype.h> + +static void +usage(const char* hunh) { + if (NULL != hunh) { + fprintf(stderr, "Can't understand %s\n", hunh); + } + + fprintf(stderr, + "Usage: blinkraw {arg, ...}\n" + " /dev/whatever -- open device\n" + " ./whatever -- open device\n" + " =R,G,B,t -- fade to color\n" + " :R,G,B -- set color (now)\n" + " @step:R,G,B,t -- set step\n" + " +step -- start playing at step\n" + " -[step] -- stop playing at step (default zero)\n" + " %% -- clear all steps\n" + " _ -- turn off\n" + " _t -- fade off\n" + "\n" + " step is on [0,15]\n", + " R, G, B are on [0, 255]\n" + " t is time in centiseconds\n" + "\n" + " Arguments are applied in order. A new device, which is\n" + " a valid blink(1) device, will become the new target.\n" + "\n" + " Example:\n" + " # blinkraw /dev/hidraw* % =255,0,0,100\n" + ); + exit(1); +} + +static void +color(int fd, char action, int R, int G, int B, int T, int step) { + char buf[16]; + int rc; + + if (-1 == fd) return; + + memset(buf, 0, sizeof(buf)); + + if (R<0) R=0; + if (G<0) G=0; + if (B<0) B=0; + if (T<0) T=0; + if (step<0) step=0; + + if (R>255) R=255; + if (G>255) G=255; + if (B>255) B=255; + if (T>65535) T=65535; + if (step>15) step=15; + + buf[0] = 1; + buf[1] = action; + buf[2] = R; /* R */ + buf[3] = G; /* G */ + buf[4] = B; /* B */ + buf[5] = (T >>8); /* time/cs high */ + buf[6] = (T & 0xff); /* time/cs low */ + buf[7] = step; + buf[8] = 0; + + rc = ioctl(fd, HIDIOCSFEATURE(9), buf); + if (rc < 0) perror("HIDIOCSFEATURE"); +} + +static void +play(int fd, char action, int play, int step) { + char buf[16]; + int rc; + + if (-1 == fd) return; + + memset(buf, 0, sizeof(buf)); + + buf[0] = 1; + buf[1] = action; + buf[2] = play; + buf[3] = step; + + rc = ioctl(fd, HIDIOCSFEATURE(9), buf); + if (rc < 0) perror("HIDIOCSFEATURE"); +} + +static int +isblink1(int fd) { + int rc; + struct hidraw_devinfo info; + memset(&info, 0, sizeof(info)); + + rc = ioctl(fd, HIDIOCGRAWINFO, &info); + if (rc < 0) { + perror("HIDIOCGRAWINFO"); + return 0; + } + + if ((info.vendor == 0x27b8) && (info.product == 0x01ed)) { + return 1; + } else { + return 0; + } +} + +int +main(int argc, char *argv[]) { + int fd = -1; + + if (argc < 2) usage(NULL); + + while(++argv, --argc) { + int rc = -1; + int step = 0; + int R = 0; + int G = 0; + int B = 0; + int T = 0; + char buf[16]; + + memset(buf, 0, sizeof(buf)); + + switch(**argv) { + case '/': case '.': + rc = open(*argv, O_RDWR|O_NONBLOCK); + if (rc < 0) { + perror(*argv); + continue; + } + + if (isblink1(rc)) { + if (fd >= 0) close(fd); + fd = rc; + } + + break; + case '=': + rc = sscanf(*argv, "=%d,%d,%d,%d", &R, &G, &B, &T); + if (rc != 4) usage(*argv); + color(fd, 'c', R, G, B, T, 0); + break; + case ':': + rc = sscanf(*argv, ":%d,%d,%d", &R, &G, &B); + if (rc != 3) usage(*argv); + color(fd, 'n', R, G, B, 0, 0); + break; + case '@': + rc = sscanf(*argv, "@%d:%d,%d,%d,%d", &step, &R, &G, &B, &T); + if (rc != 5) usage(*argv); + if ((step < 0) || step > 15) usage(*argv); + color(fd, 'P', R, G, B, T, step); + break; + case '_': + rc = sscanf(*argv, "_%d", &T); + if (rc == 1) color(fd, 'c', 0, 0, 0, T, 0); + else color(fd, 'n', 0, 0, 0, 0, 0); + break; + case '+': + rc = sscanf(*argv, "+%d", &step); + if (rc != 1) usage(*argv); + if ((step < 0) || step > 15) usage(*argv); + play(fd, 'p', 1, step); + break; + case '-': + rc = sscanf(*argv, "-%d", &step); + if (rc != 1) step = 0; + if ((step < 0) || step > 15) step = 0; + play(fd, 'p', 0, step); + break; + case '%': + for(step = 0; step < 16; ++step) { + color(fd, 'P', 0, 0, 0, 0, step); + } + break; + default: + usage(*argv); + } + } + + close(fd); + return 0; +}