Add init framework and automatic start-stop

This commit is contained in:
hirsch 2016-07-09 14:28:13 -04:00
parent f84fceb767
commit ae5b425bf2
7 changed files with 208 additions and 14 deletions

View file

@ -1,11 +1,7 @@
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0004", GROUP="plugdev" # Mustang III (original)
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0005", GROUP="plugdev" ACTION=="add|change", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0005", GROUP="plugdev", RUN+="/bin/bash -c '/bin/echo /usr/local/bin/mustang_bridge_start | /usr/bin/at now'"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0006", GROUP="plugdev" ACTION=="remove", ENV{ID_VENDOR_ID}=="1ed8", ENV{ID_MODEL_ID}=="0005", ENV{DEVTYPE}=="usb_device", RUN+="/usr/local/bin/mustang_bridge_stop"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0007", GROUP="plugdev"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0010", GROUP="plugdev" # Mustang III v2
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0011", GROUP="plugdev" ACTION=="add|change", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0016", GROUP="plugdev", RUN+="/bin/bash -c '/bin/echo /usr/local/bin/mustang_bridge_start | /usr/bin/at now'"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0012", GROUP="plugdev" ACTION=="remove", ENV{ID_VENDOR_ID}=="1ed8", ENV{ID_MODEL_ID}=="0016", ENV{DEVTYPE}=="usb_device", RUN+="/usr/local/bin/mustang_bridge_stop"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0013", GROUP="plugdev"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0014", GROUP="plugdev"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0015", GROUP="plugdev"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0016", GROUP="plugdev"

2
60-midi.rules Normal file
View file

@ -0,0 +1,2 @@
ACTION=="add|change", SUBSYSTEM=="usb", ATTRS{idVendor}=="0763", ATTRS{idProduct}=="0160", RUN+="/bin/bash -c '/bin/echo /usr/local/bin/mustang_bridge_start | /usr/bin/at now'"
ACTION=="remove", ENV{ID_VENDOR_ID}=="0763", ENV{ID_MODEL_ID}=="0160", ENV{DEVTYPE}=="usb_device", RUN+="/usr/local/bin/mustang_bridge_stop"

50
install.sh Executable file
View file

@ -0,0 +1,50 @@
#!/bin/bash
BINDIR=/usr/local/bin
INITDIR=/etc/init.d
UDEVDIR=/etc/udev/rules.d
if [ ! -f "mustang_midi" ]; then
echo "Must build mustang_midi first!"
exit 1
fi
echo "Create non-privileged user for MIDI bridge"
useradd -M -s /bin/false mustang-user
echo "Copy program and support scripts to $BINDIR"
cp -f mustang_bridge_start $BINDIR
chmod 0755 $BINDIR/mustang_bridge_start
chown root:root $BINDIR/mustang_bridge_start
cp -f mustang_bridge_stop $BINDIR
chmod 0755 $BINDIR/mustang_bridge_stop
chown root:root $BINDIR/mustang_bridge_stop
cp -f mustang_midi $BINDIR
chmod 0755 $BINDIR/mustang_midi
chown root:root $BINDIR/mustang_midi
echo "Copy init script to $INITDIR and register"
cp -f mustang_bridge $INITDIR
chmod 0755 $INITDIR/mustang_bridge
chown root:root $INITDIR/mustang_bridge
update-rc.d mustang_bridge defaults
echo "Copy udev rules to $UDEVDIR and refresh system"
cp -f 50-mustang.rules $UDEVDIR
chmod 0644 $UDEVDIR/50-mustang.rules
chown root:root $UDEVDIR/50-mustang.rules
cp -f 60-midi.rules $UDEVDIR
chmod 0644 $UDEVDIR/60-midi.rules
chown root:root $UDEVDIR/60-midi.rules
udevadm control --reload
echo "Done!"

40
mustang_bridge Executable file
View file

@ -0,0 +1,40 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: mustang_bridge
# Required-Start: mountkernfs
# Required-Stop:
# Default-Start: S
# Default-Stop:
# Short-Description: Setup /var/run/mustang directory
### END INIT INFO
PATH=/sbin:/usr/sbin:/bin:/usr/bin
. /lib/init/vars.sh
. /lib/lsb/init-functions
do_start() {
[ -d /var/run/mustang ] || mkdir /var/run/mustang
if [ -z "$(ls -A -- "/var/run/mustang")" ]; then
touch /var/run/mustang/mustang_0000
fi
}
case "$1" in
start)
do_start
;;
restart|reload|force-reload)
echo "Error: argument '$1' not supported" >&2
exit 3
;;
stop|status)
# No-op
exit 0
;;
*)
echo "Usage: $0 start|stop" >&2
exit 3
;;
esac

72
mustang_bridge_start Executable file
View file

@ -0,0 +1,72 @@
#!/usr/bin/python
import os
from os.path import expanduser
from pwd import getpwnam
from grp import getgrnam
import glob
import syslog
from string import split
import usb.core
####### Start User Edits #########
# Controller USB parms
control_vid = 0x0763
control_pid = 0x0160
# Mustang USB parms
mustang_vid = 0x1ed8
mustang_pid = 0x0016
# Controller MIDI device
midi_device = 2
# MIDI listen channel
midi_channel = 1
######## End User Edits ##########
rundir = "/var/run/mustang/"
# Look for devices
controller = usb.core.find( idVendor=control_vid, idProduct=control_pid )
mustang = usb.core.find( idVendor=mustang_vid, idProduct=mustang_pid )
pid = os.getpid()
# syslog.syslog( "%d: Starting" % pid )
# was it found?
if controller and mustang:
os.chdir( rundir )
filelist = glob.glob( 'mustang_*' )
if len( filelist ) == 1:
lockfile = filelist[0]
oldpid = split( lockfile, '_' )[1]
# syslog.syslog( "%d: Check for path /proc/%s" % (pid, oldpid) )
if not os.path.exists( "/proc/%s" % oldpid ):
# No such process, ok to start ours
# syslog.syslog( "%d: Renaming %s to mustang_%d" % (pid, lockfile, pid) )
try:
os.rename( lockfile, "mustang_%d" % os.getpid() )
except Exception, e:
pass
# syslog.syslog( "%d: Unable to rename file" % pid )
else:
# syslog.syslog( "%d: About to exec" % pid )
# Drop privileges and start the program
pwObj = getpwnam('mustang-user')
os.setgid( pwObj.pw_gid )
# Need secondary groups to access MIDI and USB devices
sec_gids = ( getgrnam('plugdev').gr_gid, getgrnam('audio').gr_gid )
os.setgroups( sec_gids )
os.setuid( pwObj.pw_uid )
os.execl( "/usr/local/bin/mustang_midi", "mustang_midi", "%s" % midi_device, "%s" % midi_channel )
else:
syslog.syslog( "%d: /var/run/mustang is not properly setup" % pid )

35
mustang_bridge_stop Executable file
View file

@ -0,0 +1,35 @@
#!/usr/bin/python
import os
from glob import glob
from syslog import syslog
from string import split
import signal
pid = os.getpid()
# syslog( "%d: Starting" % pid )
rundir = "/var/run/mustang/"
# Check for pid file
os.chdir( rundir )
filelist = glob( 'mustang_*' )
if len( filelist ) == 1:
lockfile = filelist[0]
oldpid = split( lockfile, '_' )[1]
# See if the process still exists
# syslog( "%d: Check for path /proc/%s" % (pid, oldpid) )
if os.path.exists( "/proc/%s" % oldpid ):
# syslog( "%d: Sending sigint to pid %s" % (pid, oldpid) )
try:
os.kill( int(oldpid), signal.SIGINT )
except Exception, e:
syslog( "%d: Signal failed: %s" % (pid, e) )
pass
else:
# syslog( "%d: Signal sent" % pid )
pass
else:
syslog( "%d: /var/run/mustang is not properly setup" % pid )

View file

@ -172,9 +172,8 @@ int main( int argc, const char **argv ) {
// Don't want sysex, timing, active sense // Don't want sysex, timing, active sense
input_handler->ignoreTypes( true, true, true ); input_handler->ignoreTypes( true, true, true );
std::cout << "\nTranslating MIDI input - press <enter> to quit.\n"; // Block and wait for signal
char input; pause();
std::cin.get(input);
delete input_handler; delete input_handler;
return 0; return 0;