Comment réinitialiser un périphérique USB à l'aide d'un script?

11

J'ai un modem USB GSM qui ne fonctionne pas toujours (Huawei E367u-2) Parfois, il est réinitialisé (déconnexion / reconnexion du périphérique USB dans les journaux) et lorsqu'il revient, il a des numéros ttyUSB différents. Parfois au démarrage, usb_modswitch semble juste ne pas être viré. L'ordinateur est un Raspberry Pi exécutant Raspbian.

J'ai une solution simple à cela, chaque minute CRON exécute le script suivant:

If WVDIAL is not running:
    Run WVDIAL

Je veux changer le script comme ceci:

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

Évidemment, c'est du pseudo-code, mais j'ai les lignes suivantes que je dois enchaîner, mais je ne peux pas comprendre comment:

Cela charge wvdial s'il n'est pas en cours d'exécution:

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

Cela me permet de trouver le /syschemin vers un certain appareil:

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

Et cela réinitialise un périphérique USB si vous connaissez le chemin / sys correct:

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

Donc, je dois enchaîner les 2 dernières sections et un test /dev/ttyUSB0dans une section qui passe sous la section "Si vous voulez qu'une commande soit toujours exécutée. Mettez-la ici"

MISE À JOUR 1

usbreset, bien que fonctionnel, ne fait pas l'affaire. Seul l'écho 0 le 1 dans authroizedsimule correctement une déconnexion / reconnexion de périphérique.
C'est ce que fait l'astuce de redémarrer l'appareil ou usb_modeswitch dans la vie. En tant que tel, j'ai réussi à bricoler ensemble ceci:

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

Je pense donc que tout ce que j'ai à faire maintenant est de mettre ceci dans le script 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
la source
1
+1 usbresetéchoue avec les modems Huawei, le modem n'est pas en mesure de récupérer et se fige au redémarrage. Je suis en train de résoudre le même problème, et je pourrais avoir une solution pleinement opérationnelle bientôt.
yo
Je sais que ce n'est pas ce que vous voulez entendre, mais après que le bâton que j'utilisais qui a causé ce problème se soit frit, j'ai acheté un Huawei E3131 pour Tesco (10 £). C'est un routeur dans une clé, il vous suffit de le brancher et vous obtenez eth1 avec une IP NAT et vous avez terminé. Il a même une interface Web pour la configuration. Et il peut être basculé en mode PPP normal si vous en avez besoin. @tohecz
RoboJ1M
Eh bien, dites-moi s'il y en a un 4G si bon marché, et vous êtes mon héros! :) (Je suis actuellement avec un tarif 4G et un modem 3G, oui, et avec un modem 4G qui n'a pas de pilotes ARM.)
yo '
Consultez cette question connexe sur Unix et Linux SE.
Dmitry Grigoryev

Réponses:

2

j'ai fait un simple script bash pour réinitialiser un périphérique USB particulier.

#!/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
la source
9

Vous pouvez réinitialiser le bus USB via ce programme C. https://gist.github.com/x2q/5124616

Télécharger le code C depuis github

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

Compiler le code C en tant qu'usbreset

cc usbreset.c -o usbreset

Donner la permission d'exécuter pour programmer

chmod +x usbreset

Lister vos périphériques USB via la commande lsusb

lsusb

Vous devriez voir les entrées de périphérique USB dans votre sortie et vérifier le périphérique pour lequel vous souhaitez réinitialiser.

Bus 002 Appareil 003 : ID 0fe9: 9010 DVICO

Exécuter le programme usbreset avec des arguments

sudo ./usbreset /dev/bus/usb/002/003
gurcanozturk
la source
Encore faut-il le rassembler dans un script. Quelque chose comme: x = lsusb | grep xxxx:yyyy /usr/sbin/usbreset $x. Malheureusement, il semble que nous ne pouvons pas mettre de sauts de ligne dans un commentaire
RoboJ1M
J'en ai besoin dans mon script init.d ( wvdialer). Actuellement, CRON l'exécute toutes les minutes et recharge à nouveau le wvdial s'il n'est pas présent (en utilisant start-stop-daemon). Mais il ne démarrera pas si ttyUSB0 n'est pas là. Maintenant, pour diverses raisons, le bâton a parfois besoin de reprendre vie. Donc, dans ce script, j'ai besoinIf ttyUSB0 is not present reset the USB stick
RoboJ1M
1
Utilisez la commande lsusb pour obtenir plus d'informations? Exemple ; lsusb -d xxxx: yyyy puis vérifiez si votre modem USB là-bas, s'il n'appelle pas usbreset.
gurcanozturk
2

Vous pouvez utiliser pyusb pour réinitialiser un appareil:

Installez d'abord pyusb:

sudo pip install pyusb

Créez ensuite ce script et exécutez-le:

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

Adaptez le idVendoret idProductà l'appareil que vous souhaitez réinitialiser (vous pouvez trouver l'identifiant via lsusb)

rishta
la source
0

Merci beaucoup! Ce code C fonctionne très bien. Ceci est le simple script shell que j'ai fait pour identifier le périphérique 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
la source
0

La réinitialisation de mon modem Huawei ne fonctionne pas toujours. Comme je me connecte avec un service systemd de toute façon, j'ai ajouté quelques lignes qui désalimentent complètement tous les périphériques USB et redémarrent la framboise après 5 minutes :-)

[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
la source