Jak zresetować urządzenie USB za pomocą skryptu?

11

Mam modem USB GSM, który nie zawsze działa prawidłowo (Huawei E367u-2) Czasami resetuje się (urządzenie USB odłącza / ponownie łączy się w logach), a kiedy wraca, ma różne numery ttyUSB. Czasami po uruchomieniu usb_modswitch wydaje się po prostu nie zostać zwolniony. Komputer to Raspberry Pi z systemem Raspbian.

Mam na to proste rozwiązanie, co minutę CRON uruchamia następujący skrypt:

If WVDIAL is not running:
    Run WVDIAL

Chcę zmienić skrypt w następujący sposób:

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

Oczywiście jest to pseudo kod, ale mam następujące wiersze, które muszę połączyć razem, ale nie wiem, jak to zrobić:

To ładuje wvdial, jeśli nie jest uruchomiony:

#! /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

To pozwala mi znaleźć /sysścieżkę do określonego urządzenia:

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

I to resetuje urządzenie USB, jeśli znasz prawidłową ścieżkę / sys:

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

Muszę więc napisać ostatnie 2 sekcje i test do /dev/ttyUSB0sekcji, która znajduje się w sekcji „Jeśli chcesz, aby polecenie zawsze działało. Umieść je tutaj”

AKTUALIZACJA 1

usbreset, chociaż działa, nie spełnia swojej roli. Tylko echo 0 the 1 authroizedpoprawnie symuluje rozłączenie / ponowne podłączenie urządzenia.
To właśnie polega na ponownym uruchomieniu urządzenia lub przełącznika usb_modeswitch. Jako taki udało mi się połączyć to:

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

Myślę zatem, że wszystko, co muszę teraz zrobić, to umieścić to w skrypcie init.d:

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
źródło
1
+1 usbresetnie działa z modemami Huawei, modem nie jest w stanie się zregenerować i zawiesza się przy ponownym uruchomieniu. Obecnie rozwiązuję ten sam problem i wkrótce mogę znaleźć w pełni działające rozwiązanie.
yo
Wiem, że to nie to, co chcesz usłyszeć, ale po tym, jak użyłem kija, który spowodował sam problem, sam się usmażyłem, kupiłem Huawei E3131 za Tesco (10 funtów). To router w patyku, wystarczy go podłączyć, a otrzymasz eth1 z adresem NAT NAT i gotowe. Ma nawet interfejs WWW do konfiguracji. W razie potrzeby można go przełączyć do normalnego trybu PPP. @tohecz
RoboJ1M
Powiedz mi, czy jest tak tani 4G, a ty jesteś moim bohaterem! :) (Obecnie mam taryfę 4G i modem 3G, tak, i modem 4G, który nie ma sterowników ARM.)
yo
Możliwy duplikat Resetowania urządzenia USB z terminala
rishta
Sprawdź to powiązane pytanie na Unix i Linux SE.
Dmitrij Grigoriew

Odpowiedzi:

2

Zrobiłem prosty skrypt bash do zresetowania konkretnego urządzenia USB.

#!/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
źródło
9

Możesz zresetować magistralę USB za pomocą tego programu C. https://gist.github.com/x2q/5124616

Pobierz kod C z github

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

Skompiluj kod C jako usbreset

cc usbreset.c -o usbreset

Zezwól na wykonanie programu

chmod +x usbreset

Wyświetl listę urządzeń USB za pomocą polecenia lsusb

lsusb

Powinieneś zobaczyć wpisy urządzenia USB na wyjściu i sprawdzić urządzenie, dla którego chcesz zresetować.

Magistrala 002 Urządzenie 003 : ID 0fe9: 9010 DVICO

Uruchom program usbreset z argumentami

sudo ./usbreset /dev/bus/usb/002/003
gurcanozturk
źródło
Nadal trzeba połączyć to w skrypt. Coś jak: x = lsusb | grep xxxx:yyyy /usr/sbin/usbreset $x. Niestety wydaje się, że nie możemy wstawiać
podziałów
Potrzebuję tego w moim skrypcie init.d ( wvdialer). Obecnie CRON uruchamia go co minutę i ponownie ładuje wvdial, jeśli go nie ma (używa start-stop-daemon). Ale nie uruchomi się, jeśli nie będzie tam ttyUSB0. Teraz z różnych powodów kij po prostu czasami potrzebuje powrotu do życia. Potrzebuję więc tego skryptuIf ttyUSB0 is not present reset the USB stick
RoboJ1M,
1
Użyj polecenia lsusb, aby uzyskać więcej informacji? Przykład; lsusb -d xxxx: yyyy, a następnie sprawdź, czy jest tam modem USB, jeśli nie nazywa się usbreset.
gurcanozturk
2

Możesz użyć pyusb do zresetowania urządzenia:

Pierwsza instalacja pyusb:

sudo pip install pyusb

Następnie utwórz ten skrypt i uruchom go:

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

Dostosuj idVendori idProductdo urządzenia, które chcesz zresetować (możesz znaleźć identyfikator za pośrednictwem lsusb)

rishta
źródło
0

Dziękuję bardzo! Ten kod C działa po prostu świetnie. To jest prosty skrypt powłoki, który zrobiłem, aby zidentyfikować urządzenie USB

#!/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
źródło
0

Resetowanie mojego modemu Huawei nie zawsze działa. Ponieważ i tak łączę się z usługą systemową, dodałem kilka linii, które całkowicie wyłączają wszystkie urządzenia USB i ponownie uruchamiają malinę po 5 minutach :-)

[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
źródło