Various improvement

This commit is contained in:
rob 2022-06-04 17:16:28 +10:00
parent 564a8942d7
commit 6a8ef052da
6 changed files with 1045 additions and 316 deletions

View File

@ -1,10 +1,15 @@
CFLAGS=-g -Wall `pkg-config --cflags hidapi` CFLAGS=-c -D_LINUX -g -Wall -I/usr/include/hidapi -I/usr/include/libusb-1.0
LDFLAGS=`pkg-config --libs hidapi` LDFLAGS=-L/usr/lib/x86_64-linux-gnu/ -lhidapi-hidraw -lusb-1.0
all: lsusb howard all: lsusb howard
lsusb: lsusb.c lsusb: lsusb.c
gcc -olsusb $(CFLAGS) $(LDFLAGS) lsusb.c gcc $(CFLAGS) lsusb.c -olsusb.o
gcc lsusb.o $(LDFLAGS) -o lsusb
howard: howard.c howard.h howard: howard.c howard.h
gcc -ohoward $(CFLAGS) $(LDFLAGS) howard.c gcc $(CFLAGS) howard.c -ohoward.o
gcc howard.o $(LDFLAGS) -o howard
install: howard
cp -af howard /usr/local/bin/howard

1055
howard.c

File diff suppressed because it is too large Load Diff

137
howard.h
View File

@ -1,18 +1,137 @@
// booleans
#define TRUE (-1)
#define FALSE (0)
#define BADFD (-1)
// buffer lengths
#define BUFLEN 8196
#define BUFLENSMALL 255
#define BUFLENTINY 32
// Benestar sound meter
#define MIC_VID "64bd"
#define MIC_PID "74e3"
// mic constants
#define FLAG_DBCMODE (0b00010000) // use dBc (not dBa)
#define FLAG_MAXMODE (0b00100000) // get max db over interval
// fast = 125ms exp time avg
// slow = 1000ms exp time avg
#define FLAG_FASTMODE (0b01000000)
// ranges supported by sonometer
#define FLAG_RANGE_30_130 (0b00000000)
#define FLAG_RANGE_30_80 (0b00000001)
#define FLAG_RANGE_50_100 (0b00000010)
#define FLAG_RANGE_60_110 (0b00000011)
#define FLAG_RANGE_80_130 (0b00000100)
// ANSI stuff
char BOLD[BUFLENTINY];
char ITALIC[BUFLENTINY];
char STRIKE[BUFLENTINY];
char PLAIN[BUFLENTINY];
char UNDERLINE[BUFLENTINY];
char RED[BUFLENTINY];
char MAGENTA[BUFLENTINY];
char GREEN[BUFLENTINY];
char YELLOW[BUFLENTINY];
char BLUE[BUFLENTINY];
char CYAN[BUFLENTINY];
char GREY[BUFLENTINY];
// Output modes
#define OM_SHORT (1) // Print to stdout in one line
#define OM_LONG (2) // Print to stdout over multiple lines
#define OM_DB (4) // Write to influxdb
// Control strings
#define CMD_CAPTURE (0xb3) // take a reading
#define CMD_CONFIGURE (0x56) // apply settings
#define RES_ACK (0xc4) // ack for command
// what to do
enum run_mode {
M_PROBE, // measure noise level
M_TEST, // just check for sononeter then exit
M_TESTDB // just check influxdb access then exit
};
// how to measure sound
enum math_mode {
M_MAX,
M_AVG
};
// where to log
#define LOGFILE "/var/log/howard.log"
#define PIDFILE "/var/run/howard.pid"
// return codes for read_single_result()
enum read_status {
E_NOERROR=0, // all good
E_TIMEOUT=-1, // didn't receive all data in time
E_BADREAD=-2 // received too much or too little data
};
typedef struct {
int dirty;
time_t unixtime;
uint8_t flags;
double decibels_last;
double decibels_max;
double decibels_avg;
double decibels_tot;
int count;
int rangeidx;
char range[BUFLENSMALL];
char dbunits[BUFLENSMALL];
char checkmode[BUFLENSMALL];
char timenice[BUFLENSMALL];
} result_t;
enum influxcmdtype { I_READ, I_WRITE, I_PING }; enum influxcmdtype { I_READ, I_WRITE, I_PING };
// prototypes
int add_output_mode(char *m);
char *append(char *orig, char *new, int maxlen);
void cleanup(void);
void clear_results(result_t *data);
void colprintf( char *prefix, const char *col, char* format, va_list *args ); void colprintf( char *prefix, const char *col, char* format, va_list *args );
void info( char* format, ... ); int configure_mic(void);
int daemonize(void);
struct hostent *dnslookup(char *hname);
void err( char* format, ... ); void err( char* format, ... );
void warn( char* format, ... ); double extract_decibels(uint8_t *buf);
void generate_commands(void);
char *getprocfspath(int vid, int pid, char *retvar);
void handle_signal(int signum);
int hextoint(char *hex); int hextoint(char *hex);
int readresult(hid_device *dev, uint8_t *retbuf); int hook_exits(void);
void showlevel(uint8_t *buf);
int tcpconnect(char *hname, int port);
int dohttp(char *hname, int port, char *header, char *body, char *retbuf);
struct hostent *resolve(char *hname);
int influx_init(char *hname, char *db, char *user, char *pass);
int influx_cmd(enum influxcmdtype cmdtype, char *cmd, char *retbuf); int influx_cmd(enum influxcmdtype cmdtype, char *cmd, char *retbuf);
int influx_httppost(char *hname, int port, char *header, char *body, char *retbuf);
int influx_init(char *hname, char *db, char *user, char *pass);
int influx_insert(char *cmd, char *retbuf); int influx_insert(char *cmd, char *retbuf);
int influx_query(char *cmd, char *retbuf);
int influx_ping(char *retbuf); int influx_ping(char *retbuf);
int influx_query(char *cmd, char *retbuf);
int influx_write_decibels(double decibels); int influx_write_decibels(double decibels);
void info( char* format, ... );
int init_influxdb(void);
int init_mic(void);
int init_output(void);
int mic_docmd(hid_device *dev, uint8_t *cmd, int cmdlen, uint8_t *buf);
int output_results(result_t *data);
int parse_results(uint8_t *buf, result_t *data);
void pr(char *col, char* format, ... );
enum read_status read_single_result(hid_device *dev, uint8_t *retbuf);
void reopen_logfile(int signum);
int resetusb(char *path);
void set_ansi(int wantansi);
int tcpconnect(char *hname, int port);
void usage(void);
int validateargs(void);
void vinfo( char* format, ... );
void warn( char* format, ... );

View File

@ -15,21 +15,22 @@ CONFIG=/etc/howard.conf
PIDFILE="/var/run/howard.pid" PIDFILE="/var/run/howard.pid"
rv=0 function do_start() {
# Carry out specific functions when asked to by the system local rv opts
case "$1" in
start)
if [[ ! -e $CONFIG ]]; then if [[ ! -e $CONFIG ]]; then
echo "Config file '$CONFIG' is missing" echo "Config file '$CONFIG' is missing"
exit 1 exit 1
fi fi
echo -n "Starting howard... " echo -n "Starting howard... "
OPTS=$(cat $CONFIG | tr '\n' ' ') opts=$(cat $CONFIG | tr '\n' ' ')
$BINARY $OPTS $BINARY $opts
rv=$? rv=$?
[[ $rv -eq 0 ]] && echo "ok" || echo "failed" [[ $rv -eq 0 ]] && echo "ok" || echo "failed"
;; return $rv
stop) }
function do_stop() {
local rv
echo -n "Stopping howard... " echo -n "Stopping howard... "
if [[ -e $PIDFILE ]]; then if [[ -e $PIDFILE ]]; then
kill $(cat "$PIDFILE") kill $(cat "$PIDFILE")
@ -39,36 +40,85 @@ case "$1" in
rv=$? rv=$?
fi fi
[[ $rv -eq 0 ]] && echo "ok" || echo "failed" [[ $rv -eq 0 ]] && echo "ok" || echo "failed"
;; return $rv
status) }
function getpid() {
local realpid pid rv=1
local retvar msg=""
retvar="$1"
realpid="-1"
if [[ -e $PIDFILE ]]; then if [[ -e $PIDFILE ]]; then
pid=$(cat "$PIDFILE") pid=$(cat "$PIDFILE")
if ps -p $pid >/dev/null 2>&1; then if ps -p $pid >/dev/null 2>&1; then
echo "howard is running (PID $pid)" realpid=$pid
msg="howard is running (PID $pid)"
rv=0 rv=0
else else
realpid=$(pgrep howard) pid=$(pgrep howard)
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
echo "howard is running (PID $realpid) but pidfile has pid $pid" realpid=$pid
rv=0
msg="howard is running (PID $realpid) but pidfile has pid $pid"
else
msg="howard pidfile exists but pid $pid isn't running."
fi
fi
else
pid=$(pgrep -f $BINARY)
if [[ $? -eq 0 ]]; then
realpid=$pid
msg="howard is running (PID $realpid) but pidfile is missing."
rv=0 rv=0
else else
echo "howard pidfile exists but pid $pid isn't running." msg="howard is not running."
fi
fi
[[ -n $retvar ]] && eval "$retvar='$msg'"
echo "$realpid"
}
function do_reload() {
local pid rv=0
echo -n "Reloading howard... "
pid=$(getpid)
if [[ $? -eq 0 ]]; then
kill -HUP $pid
echo "ok"
else
echo "failed - howard is not running"
rv=1 rv=1
fi fi
fi return $rv
else }
realpid=$(pgrep -f $BINARY)
if [[ $? -eq 0 ]]; then
echo "howard is running (PID $realpid) but pidfile is missing."
rv=0 rv=0
else # Carry out specific functions when asked to by the system
echo "howard is not running." case "$1" in
rv=1 start)
fi do_start
fi rv=$?
;;
stop)
do_stop
rv=$?
;;
restart)
do_stop && do_start
rv=$?
;;
reload)
do_reload
;;
status)
getpid retmsg >/dev/null
rv=$?
echo "$retmsg"
;; ;;
*) *)
echo "Usage: /etc/init.d/howard {start|stop|status}" echo "Usage: /etc/init.d/howard {start|stop|status|reload|restart}"
exit 1 exit 1
;; ;;
esac esac

14
lsusb.c
View File

@ -2,6 +2,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <wchar.h> #include <wchar.h>
#ifdef _LINUX
#include <stdarg.h>
#include <ctype.h>
#endif
#include <hidapi.h> #include <hidapi.h>
@ -38,6 +42,7 @@ int main(int argc, char *argv[])
} }
alldevs = hid_enumerate(wantvendorid, wantproductid); alldevs = hid_enumerate(wantvendorid, wantproductid);
for (dev=alldevs; dev; dev = dev->next) { for (dev=alldevs; dev; dev = dev->next) {
hid_device *dev2 = NULL;
printf("%s\n", dev->path); printf("%s\n", dev->path);
printf(" Manufacturer: %ls\n", dev->manufacturer_string); printf(" Manufacturer: %ls\n", dev->manufacturer_string);
printf(" Vendor ID: 0x%04hx\n", dev->vendor_id); printf(" Vendor ID: 0x%04hx\n", dev->vendor_id);
@ -47,6 +52,15 @@ int main(int argc, char *argv[])
printf(" Interface: %d\n", dev->interface_number); printf(" Interface: %d\n", dev->interface_number);
printf(" Usage (page): 0x%hx (0x%hx)\n", dev->usage, dev->usage_page); printf(" Usage (page): 0x%hx (0x%hx)\n", dev->usage, dev->usage_page);
printf("\n"); printf("\n");
dev2 = hid_open(dev->vendor_id, dev->product_id, NULL);
if (dev2) {
printf("device open ok\n");
hid_close(dev2);
hid_exit();
} else {
printf("device open FAILED\n");
}
printf("\n");
} }
hid_exit(); hid_exit();
return 0; return 0;

40
usbreset.c Normal file
View File

@ -0,0 +1,40 @@
/* usbreset -- send a USB port reset to a USB device */
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>
int main(int argc, char **argv)
{
const char *filename;
int fd;
int rc;
if (argc != 2) {
fprintf(stderr, "Usage: usbreset device-filename\n");
return 1;
}
filename = argv[1];
fd = open(filename, O_WRONLY);
if (fd < 0) {
perror("Error opening output file");
return 1;
}
printf("Resetting USB device %s\n", filename);
rc = ioctl(fd, USBDEVFS_RESET, 0);
if (rc < 0) {
perror("Error in ioctl");
return 1;
}
printf("Reset successful\n");
close(fd);
return 0;
}