Wie setze ich ein USB-Gerät mithilfe eines Skripts zurück?

11

Ich habe ein USB-GSM-Modem, das nicht immer funktioniert (Huawei E367u-2). Manchmal wird es zurückgesetzt (USB-Gerät wird in Protokollen getrennt / wieder verbunden), und wenn es wieder hochfährt, hat es unterschiedliche ttyUSB-Nummern. Manchmal scheint usb_modswitch beim Booten einfach nicht gefeuert zu werden. Der Computer ist ein Raspberry Pi, auf dem Raspbian ausgeführt wird.

Ich habe eine einfache Lösung dafür: Jede Minute führt CRON das folgende Skript aus:

If WVDIAL is not running:
    Run WVDIAL

Ich möchte das Skript folgendermaßen ändern:

If /dev/ttyUSB0 is not present:
    If DevicePresent(12d1:1446):
        ResetDevice(12d1:1446)
    ElseIs DevicePresemt(12d1:1506)
        ResetUSB(12d1:1506)
If WVDIAL is not running:
    Run WVDIAL

Natürlich ist dies Pseudocode, aber ich habe die folgenden Zeilen, die ich aneinanderreihen muss, aber ich kann nicht herausfinden, wie:

Dies lädt wvdial, wenn es nicht ausgeführt wird:

#! /bin/sh 
# /etc/init.d/wvdial

### BEGIN INIT INFO
# Provides:          TheInternet
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Simple script to start a program at boot
# Description:       A simple script from www.stuffaboutcode.com which will start / stop a program a boot / shutdown.
### END INIT INFO

# If you want a command to always run, put it here

# Carry out specific functions when asked to by the system
case "$1" in
  start)
    echo "Starting GPRS Internet"
    # run application you want to start
    /sbin/start-stop-daemon --start --background --quiet --exec /usr/bin/wvdial internet
    ;;
  stop)
    echo "Stopping GPRS Internet"
    # kill application you want to stop
    /sbin/start-stop-daemon --stop --exec /usr/bin/wvdial 
    ;;
  *)
    echo "Usage: /etc/init.d/noip {start|stop}"
    exit 1
    ;;
esac

exit 0

Auf diese Weise kann ich den /sysPfad zu einem bestimmten Gerät finden:

for X in /sys/bus/usb/devices/*; do
    echo "$X"
    cat "$X/idVendor" 2>/dev/null
    cat "$X/idProduct" 2>/dev/null
    echo
done

Und dies setzt ein USB-Gerät zurück, wenn Sie den richtigen / sys-Pfad kennen:

echo 0 > /sys/bus/usb/devices/1-1.2.1.1/authorized
echo 1 > /sys/bus/usb/devices/1-1.2.1.1/authorized

Daher muss ich die letzten beiden Abschnitte und einen Test /dev/ttyUSB0in einen Abschnitt einfügen, der unter dem Abschnitt "Wenn ein Befehl immer ausgeführt werden soll. Fügen Sie ihn hier ein" steht

UPDATE 1

usbreset funktioniert zwar, funktioniert aber nicht. Nur Echo 0 die 1 in authroizedsimuliert korrekt das Trennen / Wiederverbinden eines Geräts.
Dies ist der Trick, um das Gerät oder usb_modeswitch wieder zum Leben zu erwecken. Als solches habe ich es geschafft, Folgendes zusammenzubasteln:

echo "Searching for $1"
devPath=`lsusb | grep $1 | sed -r 's/Bus ([0-9]{3}) Device ([0-9]{3}).*/bus\/usb\/\1\/\2/g;'`
echo "Found $1 @ $devPath"
echo "Searching for sysPath"
for sysPath in /sys/bus/usb/devices/*; do
    echo "$sysPath/uevent"
    devName=`cat "$sysPath/uevent" | grep $devPath`
    #echo devName=$devName
    if [ ! -z $devName ] 
    then
        break
    fi
done
if [ ! -z  $devName ] 
then
    echo "Found $1 @ $sysPath, Resetting"
    echo "echo 0 > $sysPath/authorized"
    echo 0 > $sysPath/authorized
    echo "echo 1 > $sysPath/authorized"
    echo 1 > $sysPath/authorized
else
    echo "Could not find $1"
fi

Ich denke, alles was ich jetzt tun muss, ist dies in das init.d Skript zu schreiben:

if ttyUSB0 not present
    if 12d1:1446 present
        /usr/sbin/resetdevicebyauthorized 12d1:1446
    else if 12d1:1506 present
        /usr/sbin/resetdevicebyauthorized 12d1:1506
    fi
fi
RoboJ1M
quelle
1
+1 usbresetschlägt bei Huawei-Modems fehl, das Modem kann nicht wiederhergestellt werden und friert beim Neustart ein. Ich löse derzeit das gleiche Problem und habe möglicherweise bald eine voll funktionsfähige Lösung.
yo
Ich weiß, es ist nicht das, was Sie hören möchten, aber nachdem der Stick, den ich verwendet habe, dieses Problem verursacht hat, habe ich mir ein Huawei E3131 von Tesco geholt (£ 10). Es ist ein Router in einem Stick, Sie schließen ihn einfach an und Sie erhalten eth1 mit einer NAT-IP und Sie sind fertig. Es hat sogar eine Webschnittstelle für die Konfiguration. Und es kann bei Bedarf in den normalen PPP-Modus geschaltet werden. @tohecz
RoboJ1M
Sag mir, ob es ein 4G gibt, das so billig ist, und du bist mein Held! :) (Ich bin derzeit mit 4G-Tarif und 3G-Modem, ja, und mit einem 4G-Modem, das keine ARM-Treiber hat.)
yo '20.
Mögliches Duplikat des
Zurücksetzens
Schauen Sie sich diese verwandte Frage unter Unix & Linux SE an.
Dmitry Grigoryev

Antworten:

2

Ich habe ein einfaches Bash-Skript zum Zurücksetzen eines bestimmten USB-Geräts erstellt.

#!/bin/bash
#type lsusb to find "vendor" and "product" ID in terminal
 set -euo pipefail
 IFS=$'\n\t'

        #edit the below tow lines of vendor and product values using lsusb result
        dev=$(lsusb -t | grep usbdevicename | grep 'If 1' | cut -d' ' -f13|cut -d"," -f1)
        #VENDOR=05a3
        #PRODUCT=9230
        VENDOR=$(lsusb -s $dev | cut -d' ' -f6 | cut -d: -f1)
        PRODUCT=$(lsusb -s $dev | cut -d' ' -f6 | cut -d: -f2)

        for DIR in $(find /sys/bus/usb/devices/ -maxdepth 1 -type l); do
          if [[ -f $DIR/idVendor && -f $DIR/idProduct &&
                $(cat $DIR/idVendor) == $VENDOR && $(cat $DIR/idProduct) == $PRODUCT ]]; then
            echo 0 > $DIR/authorized
            sleep 0.5
            echo 1 > $DIR/authorized
          fi
        done
Thoht
quelle
9

Sie können den USB-Bus über dieses C-Programm zurücksetzen. https://gist.github.com/x2q/5124616

Laden Sie den C-Code von github herunter

wget -c --no-check-certificate https://gist.githubusercontent.com/x2q/5124616/raw/3f6e5f144efab2bc8e9d02b95b8301e1e0eab669/usbreset.c -O usbreset.c

Kompilieren Sie C-Code als Usbreset

cc usbreset.c -o usbreset

Geben Sie dem Programm die Ausführungsberechtigung

chmod +x usbreset

Listen Sie Ihre USB-Geräte mit dem Befehl lsusb auf

lsusb

Sie sollten USB-Geräteeinträge in Ihrer Ausgabe sehen und überprüfen, auf welches Gerät Sie zurücksetzen möchten.

Bus 002 Gerät 003 : ID 0fe9: 9010 DVICO

Führen Sie das usbreset-Programm mit Argumenten aus

sudo ./usbreset /dev/bus/usb/002/003
gurcanozturk
quelle
Muss noch in einem Skript zusammengestellt werden. So etwas wie : x = lsusb | grep xxxx:yyyy /usr/sbin/usbreset $x. Leider können wir keine Zeilenumbrüche in einen Kommentar
einfügen
Ich brauche es in meinem init.d-Skript ( wvdialer). Derzeit führt CRON es jede Minute aus und lädt wvdial neu, wenn es nicht vorhanden ist (using start-stop-daemon). Aber es wird nicht gestartet, wenn ttyUSB0 nicht da ist. Aus verschiedenen Gründen muss der Stock nur manchmal wieder zum Leben erweckt werden. Also in diesem Skript brauche ichIf ttyUSB0 is not present reset the USB stick
RoboJ1M
1
Verwenden Sie den Befehl lsusb, um weitere Informationen zu erhalten? Beispiel; lsusb -d xxxx: yyyy Überprüfen Sie dann, ob Ihr USB-Modem dort ist, wenn es usbreset nicht aufruft.
Gurcanozturk
2

Sie können pyusb verwenden, um ein Gerät zurückzusetzen:

Installieren Sie zuerst pyusb:

sudo pip install pyusb

Erstellen Sie dann dieses Skript und führen Sie es aus:

#!/usr/bin/python
from usb.core import find as finddev
dev = finddev(idVendor=0x1234, idProduct=0x5678)
dev.reset()

Passen Sie das idVendorund idProductan das Gerät an, das Sie zurücksetzen möchten (Sie finden die ID über lsusb)

Rishta
quelle
0

Ich danke dir sehr! Dieser C-Code funktioniert einfach super. Dies ist das einfache Shell-Skript, mit dem ich das USB-Gerät identifiziert habe

#!/bin/bash
USBNAME=webcam
LSUSB=$(lsusb | grep --ignore-case $USBNAME)
FOLD="/dev/bus/usb/"$(echo $LSUSB | cut --delimiter=' ' --fields='2')"/"$(echo $LSUSB | cut --delimiter=' ' --fields='4' | tr --delete ":")
echo $LSUSB
echo $FOLD
sudo ./usbreset $FOLD
McPeppr
quelle
0

Das Zurücksetzen meines Huawei-Modems funktioniert nicht immer. Da ich mich sowieso mit einem systemd-Dienst einwähle, habe ich einige Leitungen hinzugefügt, die alle USB-Geräte vollständig ausschalten und die Himbeere nach 5 Minuten neu starten :-)

[Unit]
Description=GSM Internet
Requires=network.target
# If unable to start within 12hrs, unpower all USB and reboot
StartLimitIntervalSec=43200
StartLimitBurst=300
OnFailure=unpower-usb-reboot.service

[Service]
Type=forking
User=root
ExecStartPre=/bin/ls /dev/serial/by-id/usb-HUAWEI_Technology_HUAWEI_Mobile-if00-port0
ExecStart=/usr/bin/pon
RemainAfterExit=yes
ExecStop=/usr/bin/poff
Restart=always
RestartSec=120

[Install]
WantedBy=multi-user.target
[Unit]
Description=Unpowers all USB and reboots
[Service]
User=root
ExecStart=/bin/sh -c 'echo 0 > /sys/devices/platform/soc/20980000.usb/buspower; sleep 5m; shutdown -r now'
ree2k
quelle