9

I have a USB GSM modem that does not alwasys work property (Huawei E367u-2) Sometimes it gets reset (USB device disconnect/reconnect in logs) and when it comes back up, it's has different ttyUSB numbers. Sometimes on boot, usb_modswitch seems to just not get fired. The computer is a Raspberry Pi running Raspbian.

I have a simple solution to this, every minute CRON runs the following script:

If WVDIAL is not running:
    Run WVDIAL

I want to change the script to be this:

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

Obviously this is pseudo code, but I have the following lines that I need to string together but I can't figure out how:

This loads wvdial if it is not running:

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

This lets me find the /sys path to a certain device:

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

And this resets a USB device if you know the correct /sys path:

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

So, I need to string the last 2 sections and a test to /dev/ttyUSB0 into a section that goes under the "If you want a command to always run. put it here" section

UPDATE 1

usbreset, although functioning, does not do the job. Only echo 0 the 1 into authroized correctly simulates a device disconnect/reconnect.
This is what does the trick of booting the device or usb_modeswitch back into life. As such I've managed to cobble together this:

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

I think therefore all I have to do now is put this in the init.d script:

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
  • 1
    +1 usbreset fails with Huawei modems, the modem is not able to recover and freezes at the reboot. I'm currently solving the same problem, and might have a fully working solution soon. – yo' Mar 19 '14 at 22:26
  • I know it's not what you want to hear, but the after the stick I was using that caused this problem fried itself, I picked up a Huawei E3131 for from Tesco (£10). It's a router in a stick, you just plug it in and you get eth1 with a NAT'd IP and you're done. It even has a web interface for config. And it can be flipped to normal PPP mode if you need to. @tohecz – RoboJ1M Mar 20 '14 at 9:51
  • Well, tell me if there's a 4G one so cheap, and you're my hero! :) (I'm currently with 4G tariff and 3G modem, yeah, and with a 4G modem that has no ARM drivers.) – yo' Mar 20 '14 at 10:20
  • Possible duplicate of Resetting usb device from terminal – rishta Dec 26 '16 at 1:19
8

You can reset USB bus via this C program. https://gist.github.com/x2q/5124616

Download C code from github

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

Compile C code as usbreset

cc usbreset.c -o usbreset

Give execute permission to program

chmod +x usbreset

List your USB devices via lsusb command

lsusb

You should see USB device entries in your output and check device you want to reset for.

Bus 002 Device 003: ID 0fe9:9010 DVICO

Run usbreset program with arguments

sudo ./usbreset /dev/bus/usb/002/003
  • Still need to put it together into a script. Something like: x = lsusb | grep xxxx:yyyy /usr/sbin/usbreset $x. Sadly it appears we can't put line breaks in a comment – RoboJ1M Aug 27 '13 at 14:22
  • I need it in my init.d script (wvdialer). Currently CRON runs it every minute, and it re-loads wvdial if it's not present (using start-stop-daemon). But it won't start if ttyUSB0 isn't there. Now for various reasons the stick just sometimes needs kicking back to life. So in that script I need If ttyUSB0 is not present reset the USB stick – RoboJ1M Aug 27 '13 at 14:32
  • 1
    Use lsusb command to get more information? Example ; lsusb -d xxxx:yyyy then check if your USB modem there, if it doesn't call usbreset. – gurcanozturk Aug 28 '13 at 6:41
1
#!/usr/bin/python
from usb.core import find as finddev
dev = finddev(idVendor=0x1234, idProduct=0x5678)
dev.reset()
0

Thank you so much! This C-Code works just great. This is the simple shell script I did to identify the USB device

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

i made a simple bash script for reset particular USB device.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.