#!/bin/sh
###############################################################################
# udev helper script for UVC devices to support dynamic controls.
#
# Version: 0.1
###############################################################################

xmlpath=/etc/udev/data
logfile=/var/log/uvcdynctrl-udev.log
#logfile=/dev/null
uvcdynctrlpath=uvcdynctrl

echo -e "\n==============================================================================" >> $logfile
echo -e "Triggered at `date`\n" >> $logfile
set >> $logfile
echo >> $logfile

# Extract interface and device paths
PHYSDEVPATH=${PHYSDEVPATH:-$DEVPATH/device}
ifacepath="/sys$PHYSDEVPATH"
if [ -e "$ifacepath/idVendor" ]; then
	devpath="$ifacepath"
	unset ifacepath
	driverpath="$devpath/driver"
else
	devpath="$ifacepath/.."
	driverpath="$ifacepath/driver"
fi

# Extract the VID and PID
vid=`cat "$devpath/idVendor" | tr "[:upper:]" "[:lower:]"`
pid=`cat "$devpath/idProduct" | tr "[:upper:]" "[:lower:]"`
echo "VID of new device: '$vid'" >> $logfile
echo "PID of new device: '$pid'" >> $logfile
if [ -z $vid ]; then
	echo "ERROR: Unable to extract USB VID from '$devpath/idVendor'." >> $logfile
	exit 2
fi

# Check whether the device is managed by the UVC driver
drivername=`readlink $driverpath`
drivername=`basename $drivername`
if [ "$drivername" != "uvcvideo" ]; then
	echo "ERROR: Device is not handled by uvcvideo but by '$drivername'." >> $logfile
	if [ "$drivername" = "usb" ]; then
		echo "Note: There is a known problem for older versions of the UVC driver where the physical device path reported by udev ('/sys$PHYSDEVPATH' in this case) points to the USB device instead of the USB interface. For these versions of the UVC driver dynamic controls are not supported anyway. Please update your uvcvideo driver to the latest version if you know that this device is a UVC device." >> $logfile
	fi
	exit 3
fi
if [ -z $ifacepath ]; then
	echo "ERROR: Interface path not available." >> $logfile
	exit 4
fi

# Make sure the vendor directory ($xmlpath/VID) exists
vendordir="$xmlpath/$vid"
if [ ! -d "$vendordir" ]; then
	echo "ERROR: Vendor directory '$vendordir' not found." >> $logfile
	exit 5
fi

# Look for device specific XML files ($xmlpath/VID/PID/*.xml)
if [ ! -z $pid ]; then
	productdir="$xmlpath/$vid/$pid"
	if [ -d "$productdir" ]; then
		for file in $productdir/*.xml; do
			if [ -f "$file" ]; then
				echo "Found product XML file: $file" >> $logfile
				cmd="$uvcdynctrlpath -d $DEVNAME -i $file"
				echo "Executing command: '$cmd'" >> $logfile
				$cmd >> $logfile 2>&1
			fi
		done
	fi
fi

# Look for vendor specific XML files ($xmlpath/VID/*.xml)
for file in $vendordir/*.xml; do
	if [ -f "$file" ]; then
		echo "Found vendor XML file: $file" >> $logfile
		cmd="$uvcdynctrlpath -d $DEVNAME -i $file"
		echo "Executing command: '$cmd'" >> $logfile
		$cmd >> $logfile 2>&1
	fi
done

# Put defaults here, like e.g.
if [ -r /etc/uvc-defaults ]; then
	VDEV="-d ${DEVNAME#/dev/}"
	while read ctrl arg; do
		if [ -z "$ctrl" -o -z "$arg" -o "${ctrl:0:1}" = "#" ]; then continue; fi
		cln=${#ctrl}
		if [ "${ctrl:0:1}" = "'" -a "${ctrl:$((cln-1)):1}" != "'" ]; then
			ctrl="$ctrl ${arg%%\'*}'"; arg="${arg#*\'}"
		fi
		echo "uvcdynctrl $VDEV -s $ctrl -- $arg" >>$logfile
		eval uvcdynctrl $VDEV -s "$ctrl" -- $arg
	done </etc/uvc-defaults
fi


echo -e "==============================================================================\n" >> $logfile
