[WIP] usb_modeswitch
This commit is contained in:
parent
dd641f7f8b
commit
178f455494
4 changed files with 337 additions and 13 deletions
|
@ -21,6 +21,19 @@ with lib;
|
|||
###### implementation
|
||||
|
||||
config = mkIf config.hardware.usbWwan.enable {
|
||||
# Attaches device specific handlers.
|
||||
services.udev.packages = with pkgs; [ usb-modeswitch-data ];
|
||||
|
||||
# Triggered by udev, usb-modeswitch creates systemd services via a
|
||||
# template unit in the usb-modeswitch package.
|
||||
systemd.packages = with pkgs; [ usb-modeswitch ];
|
||||
|
||||
# The systemd service requires the usb-modeswitch-data. The
|
||||
# usb-modeswitch package intends to discover this via the
|
||||
# filesystem at /usr/share/usb_modeswitch, and merge it with user
|
||||
# configuration in /etc/usb_modeswitch.d. Configuring the correct
|
||||
# path in the package is difficult, as it would cause a cyclic
|
||||
# dependency.
|
||||
environment.etc."usb_modeswitch.d".source = "${pkgs.usb-modeswitch-data}/share/usb_modeswitch";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,294 @@
|
|||
diff --git a/Makefile b/Makefile
|
||||
index 463a11f..f20072c 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -5,11 +5,11 @@ CFLAGS += -Wall
|
||||
LIBS = `pkg-config --libs --cflags libusb-1.0`
|
||||
RM = /bin/rm -f
|
||||
OBJS = usb_modeswitch.c
|
||||
-PREFIX = $(DESTDIR)/usr
|
||||
-ETCDIR = $(DESTDIR)/etc
|
||||
+PREFIX = /usr/local
|
||||
+ETCDIR = $(PREFIX)/etc
|
||||
SYSDIR = $(ETCDIR)/systemd/system
|
||||
UPSDIR = $(ETCDIR)/init
|
||||
-UDEVDIR = $(DESTDIR)/lib/udev
|
||||
+UDEVDIR = $(PREFIX)/lib/udev
|
||||
SBINDIR = $(PREFIX)/sbin
|
||||
MANDIR = $(PREFIX)/share/man/man1
|
||||
VPATH = jimtcl
|
||||
@@ -22,10 +22,17 @@ endif
|
||||
JIM_CONFIGURE_OPTS = --disable-lineedit \
|
||||
--with-out-jim-ext="stdlib posix load signal syslog" --prefix=/usr
|
||||
|
||||
+USE_UPSTART=$(shell if command -v initctl > /dev/null; then echo "true"; fi)
|
||||
+USE_SYSTEMD=$(shell if command -v systemctl > /dev/null; then echo "true"; fi)
|
||||
+
|
||||
.PHONY: clean install install-common uninstall \
|
||||
script shared static \
|
||||
dispatcher-script dispatcher-shared dispatcher-static \
|
||||
- install-script install-shared install-static
|
||||
+ install-script install-shared install-static \
|
||||
+ install-upstart install-systemd \
|
||||
+ configure-dispatcher configure-script \
|
||||
+ configure-upstart configure-systemd \
|
||||
+ configure
|
||||
|
||||
all: script
|
||||
|
||||
@@ -46,7 +53,25 @@ jim/libjim.a:
|
||||
cd jim && CFLAGS="$(CFLAGS)" CC="$(CC)" ./configure $(JIM_CONFIGURE_OPTS)
|
||||
$(MAKE) -C jim lib
|
||||
|
||||
-dispatcher-script: usb_modeswitch.tcl
|
||||
+configure-dispatcher:
|
||||
+ sed -i \
|
||||
+ -e 's,^\(set setup(sbindir) \).*$$,\1$(SBINDIR),' \
|
||||
+ -e 's,^\(set setup(etcdir) \).*$$,\1$(ETCDIR),' \
|
||||
+ usb_modeswitch.tcl
|
||||
+
|
||||
+configure-script:
|
||||
+ sed -i -e 's,^\(SBINDIR=\).*$$,\1$(SBINDIR),' usb_modeswitch.sh
|
||||
+
|
||||
+configure-systemd:
|
||||
+ sed -i -e 's,@sbindir@,$(SBINDIR),' usb_modeswitch@.service
|
||||
+
|
||||
+configure-upstart:
|
||||
+ sed -i -e 's,@sbindir@,$(SBINDIR),' usb-modeswitch-upstart.conf
|
||||
+
|
||||
+configure: configure-dispatcher configure-script \
|
||||
+ configure-systemd configure-upstart
|
||||
+
|
||||
+dispatcher-script: configure-dispatcher usb_modeswitch.tcl
|
||||
sed 's_!/usr/bin/tclsh_!'"$(TCL)"'_' < usb_modeswitch.tcl > usb_modeswitch_dispatcher
|
||||
|
||||
dispatcher-shared: jim/libjim.so dispatcher.c usb_modeswitch.string
|
||||
@@ -55,7 +80,7 @@ dispatcher-shared: jim/libjim.so dispatcher.c usb_modeswitch.string
|
||||
dispatcher-static: jim/libjim.a dispatcher.c usb_modeswitch.string
|
||||
$(CC) dispatcher.c $(LDFLAGS) jim/libjim.a -Ijim -o usb_modeswitch_dispatcher $(CFLAGS)
|
||||
|
||||
-usb_modeswitch.string: usb_modeswitch.tcl
|
||||
+usb_modeswitch.string: configure-dispatcher usb_modeswitch.tcl
|
||||
$(HOST_TCL) make_string.tcl usb_modeswitch.tcl > $@
|
||||
|
||||
clean:
|
||||
@@ -76,16 +101,28 @@ ums-clean:
|
||||
# If the systemd folder is present, install the service for starting the dispatcher
|
||||
# If not, use the dispatcher directly from the udev rule as in previous versions
|
||||
|
||||
-install-common: $(PROG) usb_modeswitch_dispatcher
|
||||
- install -D --mode=755 usb_modeswitch $(SBINDIR)/usb_modeswitch
|
||||
- install -D --mode=755 usb_modeswitch.sh $(UDEVDIR)/usb_modeswitch
|
||||
- install -D --mode=644 usb_modeswitch.conf $(ETCDIR)/usb_modeswitch.conf
|
||||
- install -D --mode=644 usb_modeswitch.1 $(MANDIR)/usb_modeswitch.1
|
||||
- install -D --mode=644 usb_modeswitch_dispatcher.1 $(MANDIR)/usb_modeswitch_dispatcher.1
|
||||
- install -D --mode=755 usb_modeswitch_dispatcher $(SBINDIR)/usb_modeswitch_dispatcher
|
||||
+install-common: $(PROG) configure usb_modeswitch_dispatcher
|
||||
+ install -D --mode=755 usb_modeswitch $(DESTDIR)$(SBINDIR)/usb_modeswitch
|
||||
+ install -D --mode=755 usb_modeswitch.sh $(DESTDIR)$(UDEVDIR)/usb_modeswitch
|
||||
+ install -D --mode=644 usb_modeswitch.conf $(DESTDIR)$(ETCDIR)/usb_modeswitch.conf
|
||||
+ install -D --mode=644 usb_modeswitch.1 $(DESTDIR)$(MANDIR)/usb_modeswitch.1
|
||||
+ install -D --mode=644 usb_modeswitch_dispatcher.1 $(DESTDIR)$(MANDIR)/usb_modeswitch_dispatcher.1
|
||||
+ install -D --mode=755 usb_modeswitch_dispatcher $(DESTDIR)$(SBINDIR)/usb_modeswitch_dispatcher
|
||||
install -d $(DESTDIR)/var/lib/usb_modeswitch
|
||||
- test -d $(UPSDIR) -a -e /sbin/initctl && install --mode=644 usb-modeswitch-upstart.conf $(UPSDIR) || test 1
|
||||
- test -d $(SYSDIR) -a \( -e /usr/bin/systemctl -o -e /bin/systemctl \) && install --mode=644 usb_modeswitch@.service $(SYSDIR) || test 1
|
||||
+
|
||||
+install-upstart:
|
||||
+ install -D --mode=644 usb-modeswitch-upstart.conf $(DESTDIR)$(UPSDIR)/usb-modeswitch-upstart.conf
|
||||
+
|
||||
+install-systemd:
|
||||
+ install -D --mode=644 usb_modeswitch@.service $(DESTDIR)$(SYSDIR)/usb_modeswitch@.service
|
||||
+
|
||||
+ifeq ($(USE_UPSTART),true)
|
||||
+install-common: install-upstart
|
||||
+endif
|
||||
+
|
||||
+ifeq ($(USE_SYSTEMD),true)
|
||||
+install-common: install-systemd
|
||||
+endif
|
||||
|
||||
install: install-script
|
||||
|
||||
@@ -96,10 +133,10 @@ install-shared: dispatcher-shared install-common
|
||||
install-static: dispatcher-static install-common
|
||||
|
||||
uninstall:
|
||||
- $(RM) $(SBINDIR)/usb_modeswitch
|
||||
- $(RM) $(SBINDIR)/usb_modeswitch_dispatcher
|
||||
- $(RM) $(UDEVDIR)/usb_modeswitch
|
||||
- $(RM) $(ETCDIR)/usb_modeswitch.conf
|
||||
- $(RM) $(MANDIR)/usb_modeswitch.1
|
||||
+ $(RM) $(DESTDIR)$(SBINDIR)/usb_modeswitch
|
||||
+ $(RM) $(DESTDIR)$(SBINDIR)/usb_modeswitch_dispatcher
|
||||
+ $(RM) $(DESTDIR)$(UDEVDIR)/usb_modeswitch
|
||||
+ $(RM) $(DESTDIR)$(ETCDIR)/usb_modeswitch.conf
|
||||
+ $(RM) $(DESTDIR)$(MANDIR)/usb_modeswitch.1
|
||||
$(RM) -R $(DESTDIR)/var/lib/usb_modeswitch
|
||||
- $(RM) $(SYSDIR)/usb_modeswitch@.service
|
||||
+ $(RM) $(DESTDIR)$(SYSDIR)/usb_modeswitch@.service
|
||||
diff --git a/usb-modeswitch-upstart.conf b/usb-modeswitch-upstart.conf
|
||||
index 0d82b69..1c177b4 100644
|
||||
--- a/usb-modeswitch-upstart.conf
|
||||
+++ b/usb-modeswitch-upstart.conf
|
||||
@@ -1,5 +1,5 @@
|
||||
start on usb-modeswitch-upstart
|
||||
task
|
||||
script
|
||||
- exec /usr/sbin/usb_modeswitch_dispatcher --switch-mode $UMS_PARAM
|
||||
+ exec @sbindir@/usb_modeswitch_dispatcher --switch-mode $UMS_PARAM
|
||||
end script
|
||||
diff --git a/usb_modeswitch.sh b/usb_modeswitch.sh
|
||||
index eb3fa3e..0e93166 100755
|
||||
--- a/usb_modeswitch.sh
|
||||
+++ b/usb_modeswitch.sh
|
||||
@@ -1,5 +1,9 @@
|
||||
#!/bin/sh
|
||||
# part of usb_modeswitch 2.5.2
|
||||
+
|
||||
+# Compile time configuration, injected by the Makefile
|
||||
+SBINDIR=/usr/sbin
|
||||
+
|
||||
device_in()
|
||||
{
|
||||
if [ ! -e /var/lib/usb_modeswitch/$1 ]; then
|
||||
@@ -37,7 +41,7 @@ if [ $(expr "$1" : "--.*") ]; then
|
||||
v_id=$3
|
||||
fi
|
||||
fi
|
||||
-PATH=/sbin:/usr/sbin:$PATH
|
||||
+
|
||||
case "$1" in
|
||||
--driver-bind)
|
||||
# driver binding code removed
|
||||
@@ -46,9 +50,7 @@ case "$1" in
|
||||
--symlink-name)
|
||||
device_in "link_list" $v_id $p_id
|
||||
if [ "$?" = "1" ]; then
|
||||
- if [ -e "/usr/sbin/usb_modeswitch_dispatcher" ]; then
|
||||
- exec usb_modeswitch_dispatcher $1 $2 2>>/dev/null
|
||||
- fi
|
||||
+ exec $SBINDIR/usb_modeswitch_dispatcher $1 $2 2>>/dev/null
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
@@ -61,15 +63,13 @@ if [ "$p2" = "" -a "$p1" != "" ]; then
|
||||
p2=$p1
|
||||
fi
|
||||
|
||||
-PATH=/bin:/sbin:/usr/bin:/usr/sbin
|
||||
-init_path=`readlink -f /sbin/init`
|
||||
-if [ `basename $init_path` = "systemd" ]; then
|
||||
+if command -v systemctl > /dev/null; then
|
||||
systemctl --no-block start usb_modeswitch@$p2.service
|
||||
-elif [ -e "/etc/init/usb-modeswitch-upstart.conf" ]; then
|
||||
+elif command -v initctl > /dev/null; then
|
||||
initctl emit --no-wait usb-modeswitch-upstart UMS_PARAM=$p2
|
||||
else
|
||||
# only old distros, new udev will kill all subprocesses
|
||||
exec 1<&- 2<&- 5<&- 7<&-
|
||||
- exec usb_modeswitch_dispatcher --switch-mode $p2 &
|
||||
+ exec $SBINDIR/usb_modeswitch_dispatcher --switch-mode $p2 &
|
||||
fi
|
||||
exit 0
|
||||
diff --git a/usb_modeswitch.tcl b/usb_modeswitch.tcl
|
||||
index d2ee50c..8a48751 100755
|
||||
--- a/usb_modeswitch.tcl
|
||||
+++ b/usb_modeswitch.tcl
|
||||
@@ -12,6 +12,16 @@
|
||||
# Part of usb-modeswitch-2.5.2 package
|
||||
# (C) Josua Dietze 2009-2017
|
||||
|
||||
+# Compile-time configuration, injected by the Makefile.
|
||||
+set setup(sbindir) /usr/sbin
|
||||
+set setup(etcdir) /etc
|
||||
+
|
||||
+# External dependency default location
|
||||
+set setup(dbdir) /usr/share/usb_modeswitch
|
||||
+
|
||||
+# Derived configuration
|
||||
+set setup(dbdir_etc) $setup(etcdir)/usb_modeswitch.d
|
||||
+
|
||||
set arg0 [lindex $argv 0]
|
||||
if [regexp {\.tcl$} $arg0] {
|
||||
if [file exists $arg0] {
|
||||
@@ -91,10 +101,8 @@ if {![regexp {(.*?):.*$} $arg1 d device]} {
|
||||
}
|
||||
set flags(logwrite) 1
|
||||
|
||||
-set setup(dbdir) /usr/share/usb_modeswitch
|
||||
-set setup(dbdir_etc) /etc/usb_modeswitch.d
|
||||
if {![file exists $setup(dbdir)] && ![file exists $setup(dbdir_etc)]} {
|
||||
- Log "\nError: no config database found in /usr/share or /etc. Exit"
|
||||
+ Log "\nError: no config database found in $setup(dbdir) or $setup(dbdir_etc). Exit"
|
||||
SafeExit
|
||||
}
|
||||
|
||||
@@ -261,7 +269,7 @@ if {$config(NoMBIMCheck)==0 && $usb(bNumConfigurations) > 1} {
|
||||
if [CheckMBIM] {
|
||||
Log " driver for MBIM devices is available"
|
||||
Log "Find MBIM configuration number ..."
|
||||
- if [catch {set cfgno [exec /usr/sbin/usb_modeswitch -j -Q $busParam $devParam -v $usb(idVendor) -p $usb(idProduct)]} err] {
|
||||
+ if [catch {set cfgno [exec $setup(sbindir)/usb_modeswitch -j -Q $busParam $devParam -v $usb(idVendor) -p $usb(idProduct)]} err] {
|
||||
Log "Error when trying to find MBIM configuration, switch to legacy modem mode"
|
||||
} else {
|
||||
set cfgno [string trim $cfgno]
|
||||
@@ -297,7 +305,7 @@ if {$report == ""} {
|
||||
# Now we are actually switching
|
||||
if $flags(logging) {
|
||||
Log "Command line:\nusb_modeswitch -W -D $configParam $busParam $devParam -v $usb(idVendor) -p $usb(idProduct) -f \$flags(config)"
|
||||
- catch {set report [exec /usr/sbin/usb_modeswitch -W -D $configParam $busParam $devParam -v $usb(idVendor) -p $usb(idProduct) -f "$flags(config)" 2>@1]} report
|
||||
+ catch {set report [exec $setup(sbindir)/usb_modeswitch -W -D $configParam $busParam $devParam -v $usb(idVendor) -p $usb(idProduct) -f "$flags(config)" 2>@1]} report
|
||||
Log "\nVerbose debug output of usb_modeswitch and libusb follows"
|
||||
Log "(Note that some USB errors are to be expected in the process)"
|
||||
Log "--------------------------------"
|
||||
@@ -305,7 +313,7 @@ if {$report == ""} {
|
||||
Log "--------------------------------"
|
||||
Log "(end of usb_modeswitch output)\n"
|
||||
} else {
|
||||
- catch {set report [exec /usr/sbin/usb_modeswitch -Q -D $configParam $busParam $devParam -v $usb(idVendor) -p $usb(idProduct) -f "$flags(config)" 2>@1]} report
|
||||
+ catch {set report [exec $setup(sbindir)/usb_modeswitch -Q -D $configParam $busParam $devParam -v $usb(idVendor) -p $usb(idProduct) -f "$flags(config)" 2>@1]} report
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,9 +506,9 @@ return 1
|
||||
|
||||
proc {ParseGlobalConfig} {} {
|
||||
|
||||
-global flags
|
||||
+global flags setup
|
||||
set configFile ""
|
||||
-set places [list /etc/usb_modeswitch.conf /etc/sysconfig/usb_modeswitch /etc/default/usb_modeswitch]
|
||||
+set places [list $setup(etcdir)/usb_modeswitch.conf $setup(etcdir)/sysconfig/usb_modeswitch $setup(etcdir)/default/usb_modeswitch]
|
||||
foreach cfg $places {
|
||||
if [file exists $cfg] {
|
||||
set configFile $cfg
|
||||
@@ -897,10 +905,12 @@ proc {SysLog} {msg} {
|
||||
|
||||
global flags
|
||||
if {![info exists flags(logger)]} {
|
||||
- set flags(logger) ""
|
||||
- foreach fn {/bin/logger /usr/bin/logger} {
|
||||
- if [file exists $fn] {
|
||||
- set flags(logger) $fn
|
||||
+ set flags(logger) [exec sh -c "command -v logger || true"]
|
||||
+ if {$flags(logger) == ""} {
|
||||
+ foreach fn {/bin/logger /usr/bin/logger} {
|
||||
+ if [file exists $fn] {
|
||||
+ set flags(logger) $fn
|
||||
+ }
|
||||
}
|
||||
}
|
||||
Log "Logger is $flags(logger)"
|
||||
diff --git a/usb_modeswitch@.service b/usb_modeswitch@.service
|
||||
index f74a8bf..90cb96a 100644
|
||||
--- a/usb_modeswitch@.service
|
||||
+++ b/usb_modeswitch@.service
|
||||
@@ -3,6 +3,6 @@ Description=USB_ModeSwitch_%i
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
-ExecStart=/usr/sbin/usb_modeswitch_dispatcher --switch-mode %i
|
||||
+ExecStart=@sbindir@/usb_modeswitch_dispatcher --switch-mode %i
|
||||
#ExecStart=/bin/echo %i
|
||||
|
|
@ -9,10 +9,13 @@ stdenv.mkDerivation rec {
|
|||
sha256 = "0b1wari3aza6qjggqd0hk2zsh93k1q8scgmwh6f8wr0flpr3whff";
|
||||
};
|
||||
|
||||
inherit (usb-modeswitch) makeFlags;
|
||||
makeFlags = [
|
||||
"PREFIX=$(out)"
|
||||
"DESTDIR=$(out)"
|
||||
];
|
||||
|
||||
prePatch = ''
|
||||
sed -i 's@usb_modeswitch@${usb-modeswitch}/bin/usb_modeswitch@g' 40-usb_modeswitch.rules
|
||||
sed -i 's@usb_modeswitch@${usb-modeswitch}/lib/udev/usb_modeswitch@g' 40-usb_modeswitch.rules
|
||||
'';
|
||||
|
||||
# we add tcl here so we can patch in support for new devices by dropping config into
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{ stdenv, fetchurl, pkgconfig, libusb1 }:
|
||||
{ stdenv, lib, fetchurl, pkgconfig, makeWrapper
|
||||
, libusb1, tcl, utillinux, coreutils, bash }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
name = "usb-modeswitch-${version}";
|
||||
|
@ -9,19 +10,32 @@ stdenv.mkDerivation rec {
|
|||
sha256 = "19ifi80g9ns5dmspchjvfj4ykxssq9yrci8m227dgb3yr04srzxb";
|
||||
};
|
||||
|
||||
makeFlags = [
|
||||
"DESTDIR=$(out)"
|
||||
"PREFIX=$(out)"
|
||||
];
|
||||
patches = [ ./configurable-usb-modeswitch.patch ];
|
||||
|
||||
# make clean: we always build from source. It should be necessary on x86_64 only
|
||||
preConfigure = ''
|
||||
find -type f | xargs sed 's@/bin/rm@rm@g' -i
|
||||
make clean
|
||||
# Remove attempts to write to /etc and /var/lib.
|
||||
postPatch = ''
|
||||
sed -i \
|
||||
-e '/^\tinstall .* usb_modeswitch.conf/s,$(ETCDIR),$(out)/etc,' \
|
||||
-e '\,^\tinstall -d .*/var/lib/usb_modeswitch,d' \
|
||||
Makefile
|
||||
'';
|
||||
|
||||
buildInputs = [ libusb1 ];
|
||||
nativeBuildInputs = [ pkgconfig ];
|
||||
makeFlags = [
|
||||
"PREFIX=$(out)"
|
||||
"ETCDIR=/etc"
|
||||
"USE_UPSTART=false"
|
||||
"USE_SYSTEMD=true"
|
||||
"SYSDIR=$(out)/lib/systemd/system"
|
||||
"UDEVDIR=$(out)/lib/udev"
|
||||
];
|
||||
|
||||
postFixup = ''
|
||||
wrapProgram $out/bin/usb_modeswitch_dispatcher \
|
||||
--set PATH ${lib.makeBinPath [ utillinux coreutils bash ]}
|
||||
'';
|
||||
|
||||
buildInputs = [ libusb1 tcl ];
|
||||
nativeBuildInputs = [ pkgconfig makeWrapper ];
|
||||
|
||||
meta = with stdenv.lib; {
|
||||
description = "A mode switching tool for controlling 'multi-mode' USB devices";
|
||||
|
|
Loading…
Reference in a new issue