1#!/bin/bash 2 3# an auxiliary script to produce a "stub" usbhid-ups subdriver from 4# the output of 5# 6# drivers/usbhid-ups -DD -u root -x generic -x vendorid=XXXX auto 7# 8# Usage: cat debuginfo | gen-usbhid-subdriver.sh 9# 10# See also: docs/hid-subdrivers.txt 11 12usage() { 13 echo "Usage: $0 [options] [file]" 14 echo "Options:" 15 echo " -h, --help -- show this message and quit" 16 echo " -n name -- driver name (use natural capitalization)" 17 echo " -v XXXX -- vendor id" 18 echo " -p XXXX -- product id" 19 echo " -k -- keep temporary files (for debugging)" 20 echo " file -- read from file instead of stdin" 21} 22 23DRIVER="" 24VENDORID="" 25PRODUCTID="" 26KEEP="" 27 28while [ $# -gt 0 ]; do 29 if [ $# -gt 1 -a "$1" = "-n" ]; then 30 DRIVER="$2" 31 shift 2 32 elif [ $# -gt 1 -a "$1" = "-v" ]; then 33 VENDORID="$2" 34 shift 2 35 elif [ $# -gt 1 -a "$1" = "-p" ]; then 36 PRODUCTID="$2" 37 shift 2 38 elif [ "$1" = "-k" ]; then 39 KEEP=yes 40 shift 41 elif echo "$1" | grep -qv '^-'; then 42 FILE="$1" 43 shift 44 elif [ "$1" = "--help" -o "$1" = "-h" ]; then 45 usage 46 exit 0 47 else 48 echo "Illegal option $1. Try --help for more info." >&2 49 exit 1 50 fi 51done 52 53# delete temporary files: this is called just before exiting. 54cleanup () { 55 rm -f "$DEBUG" "$UTABLE" "$USAGES" "$SUBST" "$SEDFILE" "$NEWUTABLE" 56} 57if [ -z "$KEEP" ]; then 58 trap cleanup EXIT 59fi 60 61NAME=gen-usbhid-subdriver 62TMPDIR="${TEMPDIR:-/tmp}" 63DEBUG=`mktemp "$TMPDIR/$NAME-DEBUG.XXXXXX"` 64UTABLE=`mktemp "$TMPDIR/$NAME-UTABLE.XXXXXX"` 65USAGES=`mktemp "$TMPDIR/$NAME-USAGES.XXXXXX"` 66SUBST=`mktemp "$TMPDIR/$NAME-SUBST.XXXXXX"` 67SEDFILE=`mktemp "$TMPDIR/$NAME-SEDFILE.XXXXXX"` 68NEWUTABLE=`mktemp "$TMPDIR/$NAME-NEWUTABLE.XXXXXX"` 69 70# save standard input to a file 71if [ -z "$FILE" ]; then 72 FILE="$DEBUG" 73 cat > "$DEBUG" 74fi 75 76# prompt use for name of driver 77while [ -z "$DRIVER" ]; do 78 echo " 79Please enter a name for this driver. Use only letters and numbers. Use 80natural (upper- and lowercase) capitalization, e.g., 'Belkin', 'APC'." 81 read -p "Name of subdriver: " DRIVER < /dev/tty 82 if echo $DRIVER | egrep -q '[^a-zA-Z0-9]'; then 83 echo "Please use only letters and digits" 84 DRIVER="" 85 fi 86done 87 88# try to determine product and vendor id 89VENDORID=`cat "$FILE" | sed -n 's/.*- VendorID: \([0-9a-fA-F]*\).*/\1/p' | tail -1` 90PRODUCTID=`cat "$FILE" | sed -n 's/.*- ProductID: \([0-9a-fA-F]*\).*/\1/p' | tail -1` 91 92# prompt for productid, vendorid if necessary 93if [ -z "$VENDORID" ]; then 94 read -p "Vendor ID: " VENDORID < /dev/tty 95fi 96if [ -z "$PRODUCTID" ]; then 97 read -p "Product ID: " PRODUCTID < /dev/tty 98fi 99 100LDRIVER=`echo $DRIVER | tr A-Z a-z` 101UDRIVER=`echo $DRIVER | tr a-z A-Z` 102CFILE="$LDRIVER-hid.c" 103HFILE="$LDRIVER-hid.h" 104 105# extract Usage Table 106cat "$FILE" | sed -n 's/.*Path: \([^,][^,]*\), Type:.*/\1/p' > "$UTABLE" 107 108# extract Usage codes 109cat "$UTABLE" | tr '.' $'\n' | sort -u > "$USAGES" 110 111# make up dummy names for unknown usages 112count=0 113cat "$USAGES" | egrep '[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]' |\ 114while read U; do 115 count=`expr $count + 1` 116 echo "$U $UDRIVER$count" 117done > "$SUBST" 118 119# create an sed script for substitutions 120cat "$SUBST" | sed 's/\(.*\) \(.*\)/s!\1!\2!g;/' > "$SEDFILE" 121 122# create modified usage table 123sed -f "$SEDFILE" < "$UTABLE" > "$NEWUTABLE" 124 125# generate header file 126echo "Creating $HFILE" 127cat > "$HFILE" <<EOF 128/* ${HFILE} - subdriver to monitor ${DRIVER} USB/HID devices with NUT 129 * 130 * Copyright (C) 131 * 2003 - 2009 Arnaud Quette <ArnaudQuette@Eaton.com> 132 * 2005 - 2006 Peter Selinger <selinger@users.sourceforge.net> 133 * 2008 - 2009 Arjen de Korte <adkorte-guest@alioth.debian.org> 134 * 135 * This program is free software; you can redistribute it and/or modify 136 * it under the terms of the GNU General Public License as published by 137 * the Free Software Foundation; either version 2 of the License, or 138 * (at your option) any later version. 139 * 140 * This program is distributed in the hope that it will be useful, 141 * but WITHOUT ANY WARRANTY; without even the implied warranty of 142 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 143 * GNU General Public License for more details. 144 * 145 * You should have received a copy of the GNU General Public License 146 * along with this program; if not, write to the Free Software 147 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 148 */ 149 150#ifndef ${UDRIVER}_HID_H 151#define ${UDRIVER}_HID_H 152 153#include "usbhid-ups.h" 154 155extern subdriver_t ${LDRIVER}_subdriver; 156 157#endif /* ${UDRIVER}_HID_H */ 158EOF 159 160# generate source file 161echo "Creating $CFILE" 162cat > "$CFILE" <<EOF 163/* ${CFILE} - subdriver to monitor ${DRIVER} USB/HID devices with NUT 164 * 165 * Copyright (C) 166 * 2003 - 2012 Arnaud Quette <ArnaudQuette@Eaton.com> 167 * 2005 - 2006 Peter Selinger <selinger@users.sourceforge.net> 168 * 2008 - 2009 Arjen de Korte <adkorte-guest@alioth.debian.org> 169 * 2013 Charles Lepple <clepple+nut@gmail.com> 170 * 171 * TODO: Add year and name for new subdriver author (contributor) 172 * Mention in docs/acknowledgements.txt if this is a vendor contribution 173 * 174 * Note: this subdriver was initially generated as a "stub" by the 175 * gen-usbhid-subdriver script. It must be customized. 176 * 177 * This program is free software; you can redistribute it and/or modify 178 * it under the terms of the GNU General Public License as published by 179 * the Free Software Foundation; either version 2 of the License, or 180 * (at your option) any later version. 181 * 182 * This program is distributed in the hope that it will be useful, 183 * but WITHOUT ANY WARRANTY; without even the implied warranty of 184 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 185 * GNU General Public License for more details. 186 * 187 * You should have received a copy of the GNU General Public License 188 * along with this program; if not, write to the Free Software 189 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 190 */ 191 192#include "usbhid-ups.h" 193#include "${HFILE}" 194#include "main.h" /* for getval() */ 195#include "usb-common.h" 196 197#define ${UDRIVER}_HID_VERSION "${DRIVER} HID 0.1" 198/* FIXME: experimental flag to be put in upsdrv_info */ 199 200/* ${DRIVER} */ 201#define ${UDRIVER}_VENDORID 0x${VENDORID} 202 203/* USB IDs device table */ 204static usb_device_id_t ${LDRIVER}_usb_device_table[] = { 205 /* ${DRIVER} */ 206 { USB_DEVICE(${UDRIVER}_VENDORID, 0x${PRODUCTID}), NULL }, 207 208 /* Terminating entry */ 209 { 0, 0, NULL } 210}; 211 212 213/* --------------------------------------------------------------- */ 214/* Vendor-specific usage table */ 215/* --------------------------------------------------------------- */ 216 217/* ${UDRIVER} usage table */ 218static usage_lkp_t ${LDRIVER}_usage_lkp[] = { 219EOF 220 221cat "$SUBST" | sed 's/\(.*\) \(.*\)/\t{ "\2",\t0x\1 },/' >> "$CFILE" 222 223cat >> "$CFILE" <<EOF 224 { NULL, 0 } 225}; 226 227static usage_tables_t ${LDRIVER}_utab[] = { 228 ${LDRIVER}_usage_lkp, 229 hid_usage_lkp, 230 NULL, 231}; 232 233/* --------------------------------------------------------------- */ 234/* HID2NUT lookup table */ 235/* --------------------------------------------------------------- */ 236 237static hid_info_t ${LDRIVER}_hid2nut[] = { 238 239EOF 240 241cat "$NEWUTABLE" | sort -u | while read U; do 242 UL=`echo $U | tr A-Z a-z` 243 cat >> "$CFILE" <<EOF 244 { "unmapped.${UL}", 0, 0, "${U}", NULL, "%.0f", 0, NULL }, 245EOF 246done 247 248cat >> "$CFILE" <<EOF 249 250 /* end of structure. */ 251 { NULL, 0, 0, NULL, NULL, NULL, 0, NULL } 252}; 253 254static const char *${LDRIVER}_format_model(HIDDevice_t *hd) { 255 return hd->Product; 256} 257 258static const char *${LDRIVER}_format_mfr(HIDDevice_t *hd) { 259 return hd->Vendor ? hd->Vendor : "${DRIVER}"; 260} 261 262static const char *${LDRIVER}_format_serial(HIDDevice_t *hd) { 263 return hd->Serial; 264} 265 266/* this function allows the subdriver to "claim" a device: return 1 if 267 * the device is supported by this subdriver, else 0. */ 268static int ${LDRIVER}_claim(HIDDevice_t *hd) 269{ 270 int status = is_usb_device_supported(${LDRIVER}_usb_device_table, hd); 271 272 switch (status) 273 { 274 case POSSIBLY_SUPPORTED: 275 /* by default, reject, unless the productid option is given */ 276 if (getval("productid")) { 277 return 1; 278 } 279 possibly_supported("${DRIVER}", hd); 280 return 0; 281 282 case SUPPORTED: 283 return 1; 284 285 case NOT_SUPPORTED: 286 default: 287 return 0; 288 } 289} 290 291subdriver_t ${LDRIVER}_subdriver = { 292 ${UDRIVER}_HID_VERSION, 293 ${LDRIVER}_claim, 294 ${LDRIVER}_utab, 295 ${LDRIVER}_hid2nut, 296 ${LDRIVER}_format_model, 297 ${LDRIVER}_format_mfr, 298 ${LDRIVER}_format_serial, 299}; 300EOF 301 302cat <<EOF 303Done. 304 305Do not forget to: 306* add #include "${HFILE}" to drivers/usbhid-ups.c, 307* add &${LDRIVER}_subdriver to drivers/usbhid-ups.c:subdriver_list, 308* add ${LDRIVER}-hid.c to USBHID_UPS_SUBDRIVERS in drivers/Makefile.am 309* add ${LDRIVER}-hid.h to dist_noinst_HEADERS in drivers/Makefile.am 310* "autoreconf" from the top level directory 311EOF 312