#include #include #include #include #include #include #include #include #include #include #include #include #include #include "howard.h" #define TRUE (-1) #define FALSE (0) #define BUFLEN 8196 #define BUFLENSMALL 255 // Benestar sound meter //#define MIC_VID (0x1630) //#define MIC_PID (0x05dc) #define MIC_VID (0x8817) #define MIC_PID (0x2109) #define CMD_CAPTURE (0xb3) const char *rangestr[] = { "30-130", "30-80", "50-100", "60-110", "80-130", }; char influxhost[BUFLENSMALL]; char influxdb[BUFLENSMALL]; char influxuser[BUFLENSMALL]; char influxpass[BUFLENSMALL]; #define FLAG_DBCMODE (0x10) #define FLAG_FASTMODE (0x40) #define E_TIMEOUT -1 #define E_BADREAD -2 // ANSI stuff #define BOLD "\x1b[1m" #define ITALIC "\x1b[3m" #define STRIKE "\x1b[9m" #define PLAIN "\x1b[0m" #define UNDERLINE "\x1b[4m" #define RED "\x1b[31m" #define MAGENTA "\x1b[35m" #define GREEN "\x1b[32m" #define YELLOW "\x1b[33m" #define BLUE "\x1b[34m" #define CYAN "\x1b[36m" #define GREY "\x1b[2;37m" void colprintf( char *prefix, const char *col, char *format, va_list *args ) { printf("%s%s%s %s%s",col,BOLD,prefix,PLAIN,col); vprintf(format, *args); printf("%s\n",PLAIN); } void info( char* format, ... ) { va_list args; va_start(args, format); colprintf( "*", CYAN, format, &args); va_end( args ); } void err( char* format, ... ) { va_list args; va_start(args, format); colprintf( "ERROR:", RED, format, &args); va_end( args ); } void warn( char* format, ... ) { va_list args; va_start(args, format); colprintf( "WARNING:", YELLOW, format, &args); va_end( args ); } int hextoint(char *hex) { int base=16; if (strstr(hex, "0x") == hex) { base=0; } return strtol(hex, NULL, base); } int readresult(hid_device *dev, uint8_t *retbuf) { int totbytes = 0; int wantbytes = 8; time_t starttime; int timeoutms = 2000; starttime = time(NULL); while (totbytes != wantbytes) { int thisbytes = 0; thisbytes = hid_read_timeout(dev, &retbuf[totbytes], wantbytes + 1 - totbytes, timeoutms); if (thisbytes < 0) { err("Incomplete read from usb (got %d bytes, want %d bytes): %ls",totbytes,wantbytes, hid_error(dev)); return E_BADREAD; } totbytes += thisbytes; if (time(NULL) - starttime > (timeoutms*1000)) { warn("Timeout reading from usb"); return E_TIMEOUT; } } return 0; } void showlevel(uint8_t *buf) { uint16_t decibels; uint8_t flags, rangeidx; time_t now; char *longformat = "%12s: %ld\n"; char *strformat = "%12s: %s\n"; char *dbformat = "%12s: %4.2f %s\n"; decibels = buf[0] << 8 | buf[1]; flags = buf[2]; rangeidx = buf[2] & 0xf; now = time(NULL); printf(longformat, "Time", now); printf(dbformat, "Level", (double)decibels/10.0, flags & FLAG_DBCMODE ? "dBC" : "dBA"); printf(strformat, "Mode", flags & FLAG_FASTMODE ? "Fast" : "Slow"); printf(strformat, "Range", rangeidx > 0x4 ? "unknown" : rangestr[rangeidx]); } int tcpconnect(char *hname, int port) { int sockfd; struct sockaddr_in servaddr; struct hostent *hptr; hptr = resolve(hname); if (!hptr) return TRUE; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket()"); return -1; } servaddr.sin_family = hptr->h_addrtype; servaddr.sin_port = htons(8086); memcpy(&servaddr.sin_addr, hptr->h_addr_list[0], hptr->h_length); bzero(servaddr.sin_zero, sizeof(servaddr.sin_zero)); if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) { printf("errno is %d\n", errno); perror("tcpconnect()"); return -1; } return sockfd; } int dohttp(char *hname, int port, char *header, char *body, char *retbuf) { char response[BUFLEN]; char *p,*dp,retcode_str[BUFLENSMALL]; ssize_t n; int sockfd,retcode_int = -1; sockfd = tcpconnect(hname,port); if (sockfd < 0) { err("TCP connect to %s:%d failed", hname, port); return TRUE; } if (write(sockfd, header, strlen(header)) < 0) { err("POST failed during header send"); close(sockfd); return -1; } if (write(sockfd, body, strlen(body)) < 0) { err("POST failed during body send"); close(sockfd); return -1; } // get response n = read(sockfd, response, sizeof(response)); if (n < 0) { err("POST failed during response read"); close(sockfd); return -1; } response[n] = 0; // NUL-terminate close(sockfd); if (retbuf) strncpy(retbuf, response, BUFLEN); // HTTP/1.x 204 retcode_int = -1; p = strstr(response, "HTTP/1"); if (p) { p += 9; // should now be at start of return code dp = retcode_str; for ( ; (p + 3 < (response + strlen(response))) && *p && isdigit(*p); p++,dp++) { *dp = *p; } *dp = 0; retcode_int = atoi(retcode_str); } else { retcode_int = -1; } return retcode_int; } struct hostent *resolve(char *hname) { struct hostent *hptr; hptr = gethostbyname(hname); if (hptr == NULL) { err("Failed to resolve %s (%s)",hname,hstrerror(h_errno)); return NULL; } if (hptr->h_addrtype != AF_INET) { err("No IN records for %s.",hname); return NULL; } if (hptr->h_addr_list == NULL) { err("No A records for %s.",hname); return NULL; } return hptr; } int influx_init(char *hname, char *db, char *user, char *pass) { strncpy(influxhost, hname, BUFLENSMALL); strncpy(influxdb, db, BUFLENSMALL); strncpy(influxuser, user, BUFLENSMALL); strncpy(influxpass, pass, BUFLENSMALL); return FALSE; } int influx_cmd(enum influxcmdtype cmdtype, char *cmd, char *retbuf) { char header[BUFLEN]; char newcmd[BUFLEN+2]; int rc = -1; if (cmdtype == I_WRITE) { snprintf(header, BUFLEN, "POST /write?db=%s&u=%s&p=%s HTTP/1.1\r\nHost: influx:8086\r\nContent-Length: %ld\r\n\r\n", influxdb, influxuser, influxpass, strlen(cmd)); snprintf(newcmd,BUFLEN,"%s",cmd); } else if (cmdtype == I_READ) { snprintf(header, BUFLEN, "GET /query?db=%s&u=%s&p=%s HTTP/1.1\r\nHost: influx:8086\r\nContent-Length: %ld\r\n\r\n", influxdb, influxuser, influxpass, strlen(cmd)+2); snprintf(newcmd,BUFLEN,"q=%s",cmd); } else if (cmdtype == I_PING) { snprintf(header, BUFLEN, "GET /ping HTTP/1.1\r\nHost: influx:8086\r\n\r\n"); strncpy(newcmd,"",BUFLEN); } else { err("Invalid influx command type (%d)", cmdtype); return TRUE; } rc = dohttp(influxhost, 8086, header, newcmd, retbuf); if (rc != 204) { err("Influx write to %s/%s failed (HTTP %d)",influxhost,influxdb,rc); return TRUE; } return FALSE; } int influx_insert(char *cmd, char *retbuf) { return influx_cmd(I_WRITE, cmd, retbuf); } int influx_query(char *cmd, char *retbuf ) { return influx_cmd(I_READ, cmd, retbuf); } int influx_ping(char *retbuf) { int rv; rv = influx_cmd(I_PING, "", retbuf); if (!rv) { info("Ping success:\n%s\n", retbuf); } return rv; } int influx_write_decibels(double decibels) { char cmd[BUFLEN]; snprintf(cmd, BUFLEN, "volume decibels=%0.1f\n", decibels); influx_insert(cmd, NULL); return 0; } int main(int argc, char *argv[]) { //unsigned char buf[65]; //hid_device *handle; uint8_t capture_cmd[8] = { CMD_CAPTURE }; uint8_t buf[8]; char retbuf[BUFLEN]; int res; int i; enum mode_enum { M_PROBE, M_TEST } mode = M_PROBE; hid_device *dev = NULL; // handle args for (i=1; i