1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
#!/bin/bash
# Utilities for HID++ accesses.
#
# Author: Peter Wu <lekensteyn@gmail.com>
hidw() {
local hiddev arg bytes fillchar length oIFS actualArgs
hiddev=$1; shift
bytes=()
case $hiddev in
''|-h|--help|-?)
cat <<HELP
Usage: hidw /dev/hidrawX [data]
data are hexadecimal numbers in the range 0x0-0xff ('0x' prefix is
optional). Missing bytes for HID++ reports (0x10 and 0x11) and DJ
reports (0x20 and 0x21) will be padded by zeroes unless you end with ..
as in the following (non-meaningful) example:
hidw /dev/hidraw0 10 ff 81 ff..
In this case, the message is padded with '0xff'.
The data can also be interleaved with chars by starting an argument
with a underscore (_). For example, "_foo" is equivalent to "66 6f 6f".
A colon can also be used as separator, the previous hidw example is
equivalent to:
hidw /dev/hidraw0 10:ff 81:ff..
This function does not show replies, use the 'read-dev-usbmon' program
instead.
HELP
return 1 ;;
esac
if [ ! -c "$hiddev" ]; then
echo "$hiddev: not a block special"
return 1
fi
# Support ":" as separator, but ignore string arguments (_...).
actualArgs=()
for arg; do
if [[ $arg != _* ]] && [[ $arg == *:* ]]; then
# Strip leading+trailing such that "11:02: 83 01" is still valid.
arg="${arg##:}"
arg="${arg%%:}"
oIFS="$IFS"; IFS=:; actualArgs+=( $arg ); IFS="$oIFS"
else
actualArgs+=( "$arg" )
fi
done
set -- "${actualArgs[@]}"
for arg; do
# clear the fill char, makes only sense as last argument
fillchar=
if [[ $arg =~ ^(0[xX])?[0-9a-fA-F]{1,2}(\.\.)?$ ]]; then
byte=${arg#0[Xx]}
byte=${byte%..}
[ ${#byte} = 2 ] || byte=0$byte
bytes+=($byte)
# extend with last byte
[[ $arg != *.. ]] || fillchar=$byte
elif [[ $arg =~ ^_ ]]; then
# Literal string
bytes+=( $(echo -n "${arg#_}" | xxd -ps | fold -w2) )
else
echo "Invalid argument: $arg"
return 1
fi
done
case ${bytes[0]} in
10) length=7 ;;
11) length=20 ;;
20) length=15 ;;
21) length=32 ;;
*) echo "Unknown report type ${bytes[0]}, not padding " ;;
esac
if [ $length ]; then
[ -n "$fillchar" ] || fillchar=00
while [ ${#bytes[@]} -lt $length ]; do
bytes+=($fillchar)
done
if [ ${#bytes[@]} -gt $length ]; then
echo "Too many arguments: ${#bytes[@]} > $length"
return 1
fi
fi
echo "${bytes[@]}" | xxd -ps -r > "$hiddev"
}
_hidpp_main() {
local cmd
local cmds=(hidw)
cmd=$1; shift
for c in "${cmds[@]}"; do
if [[ $cmd == $c ]]; then
$cmd "$@"
return
fi
done
case $cmd in
''|-h|--help|-?)
cat <<HELP
Usage: $0 command [command args]
Available commands:
${cmds[*]}
You can also source this file to export those functions.
HELP
;;
*)
echo "Unknown command, invoke with no arguments for help."
;;
esac
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
_hidpp_main "$@"
fi
# vim: set syntax=sh:
|