Files
ltunify/shell
Peter Wu 955b9feb9e shell: support ':' separator for multiple args
It becomes a pain to remove all colons just to add a single argument.
2014-04-05 18:41:42 +02:00

135 lines
2.8 KiB
Bash
Executable File

#!/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: