#!/bin/sh
# A script to control upmpdcli from the command line.
#
# Uses auxiliary XML files to define the commands.
#
# The way the script works is simple: the XML files contain the SOAP
# data which is sent by an UPnP call to invoke an action. If there are
# parameters for the action, the script sets their values in the data
# ('sed' call) before doing the actual POST. The Service and Action
# names are encoded in the XML file names so that you don't have to
# type them multiple times (and can use tab completion when trying
# stuff on the command line).
#
# When passing parameters through the script, you should alternate
# parameter names and values on the command line. Example uses:
#
# upcmd.sh myhost:49152 AVTransport-Play.xml
#
# upcmd.sh myhost:49152 OHVolume-SetVolume.xml Value 30
#
# 'Value' in the second example is the parameter name (or more
# concretly, the initial contents of the area which will be
# substituted by sed). It could also be something like 'NewPlayMode' or
# whatever the action XML file specifies.
#
# The script is not going to replace a real control point, but it may
# be useful for automating stuff. Also, it's not really expected to be
# used as a bare script but more probably as a building block for a
# higher level script with simpler invocation.
#
# Very few of this is actually specific to upmpdcli, other renderers
# could probably be used with very little changes. upmpdcli-specific
# elements are noted by comments in the script file.
#
# LIMITATIONS:
# - Does not work for parameter values containing whitespace (for now)
# - Does not perform discovery: you need to determine the host or IP
# address of the renderer and the port it is running on (49152 by
# default for upmpdcli), and pass them on the command line.
fatal()
{
echo $*;exit 1
}
usage()
{
fatal "Usage: upcmd.sh host:port service-action.xml [paramname value ...]\n
Examples:\n
upcmd.sh myhost:49152 AVTransport-Play.xml\n
upcmd.sh myhost:49152 OHVolume-SetVolume.xml Value 30\n
(look up the parameter names, this is not always 'Value')\n
"
}
test $# -ge 2 || usage
hostport=$1
shift
xml=$1
test -f "$xml" || fatal $xml does not exist
shift
sedcmd=''
while test $# -gt 0;do
name=$1
shift
test $# -gt 0 ||usage
value=$1
shift
sedcmd=$sedcmd" -e s/@$name@/$value/"
done
sa=`basename $xml .xml`
service=`echo $sa | awk -F- '{print $1}'`
action=`echo $sa | awk -F- '{print $2}'`
# Upmpdcli-specific: control URL computation.
#
# The XML file names are like Servicename-ActionName The servicename
# part is only used to compute the service control url (which is
# specific to upmpdcli). The OpenHome service names are special
# because upmpdcli prefixes them with OH (e.g. 'OHVolume' instead of
# 'Volume'). So the whole service control url computation would need
# changing for another renderer. Maybe get rid of the 'OH' for
# example, and use the actual control URI, which you can find in
# description.xml (which can be downloaded from the device root).
uribase=http://$hostport/ctl
ctluri=$uribase/$service
# End specific
if test "X$sedcmd" != "X"; then
postdata=`sed $sedcmd < $xml`
else
postdata=`cat $xml`
fi
#echo $postdata
serviceid=`grep xmlns:u $xml | \
awk '{print $2}' | \
sed -e 's/>//' -e 's/xmlns:u=//' -e 's/"//g'`
set -x
wget -O - \
--post-data="$postdata" \
--header 'SOAPACTION: "'$serviceid'#'$action'"' \
--header 'Content-Type: text/xml' \
$ctluri