Raspberry PiのWifiを安定させようと色々試行錯誤したりして、結構安定していたようなんですが、

ココ最近、また不安定になってきました。

なんで?寒くなってきたから?

wifiドングルを抜き差しすれば再接続するので、usbデバイスがよろしくない状態になっているのでは?

という仮説の元、ネットが切れているようならusbデバイスをリセットするようにしてみました。

ちなみにwifiドングルはこちらを使ってます。

BUFFALO Air Station NFINITI HighPower 11n/g/b USB用 無線子機 WLI-UC-GNHP

まずはこちらを参考にデバイスリセット用のプログラムを作ります。

1
~/src $ vim usbreset.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>

#include <linux/usbdevice_fs.h>

int main(int argc, char **argv)
{
    const char *filename;
    int fd;
    int rc;

    if (argc != 2) {
        fprintf(stderr, "Usage: usbreset device-filename\n");
        return 1;
    }
    filename = argv[1];

    fd = open(filename, O_WRONLY);
    if (fd < 0) {
        perror("Error opening output file");
        return 1;
    }

    printf("Resetting USB device %s\n", filename);
    rc = ioctl(fd, USBDEVFS_RESET, 0);
    if (rc < 0) {
        perror("Error in ioctl");
        return 1;
    }
    printf("Reset successful\n");

    close(fd);
    return 0;
}
1
2
3
4
5
6
7
~/src $ cc usbreset.c -o usbreset
~/src $ ls -la
total 20
drwxr-xr-x 2 pi pi 4096 Nov 11 19:36 .
drwxr-xr-x 7 pi pi 4096 Nov 11 19:35 ..
-rwxr-xr-x 1 pi pi 6373 Nov 11 19:36 usbreset
-rw-r--r-- 1 pi pi  706 Nov 11 19:35 usbreset.c

コンパイルが通ったら、デバイスファイル名を特定して、実行

1
2
3
~/src $ sudo lsusb | grep "Wireless LAN Adapter"
Bus 001 Device 007: ID 0411:0158 BUFFALO INC. (formerly MelCo., Inc.) WLI-UC-GNHP Wireless LAN Adapter
~/src $ sudo ./usbreset /dev/bus/usb/001/007

うむむ、ネットワークが戻ってきません。

ちなみに作業はSSH経由でやってますんで、wifiアダプタがリセットされたら接続も切れます。

wifiドングル直接リセットはダメみたいなんで、usbハブをリセットしてみます。

1
2
3
4
5
~/src $ sudo lsusb | grep "USB-2.0 4-Port HUB"
Bus 001 Device 004: ID 05e3:0608 Genesys Logic, Inc. USB-2.0 4-Port HUB
~/src $ sudo ./usbreset /dev/bus/usb/001/004
Resetting USB device /dev/bus/usb/001/004
Reset successful

とりあえず動いたようです。

いろいろやってるうちにusbハブリセットでもネットワークが戻って来なくなってしまいました。

どうもusbデバイスの準備が整う前にifupをやってもうまく動かないみたいです。

usbリセット後にsleepを入れて ifupも失敗しているようならリトライするようにしました。

これをこちらの記事のスクリプトに組み込んでみます。

最終的なスクリプトはこちら。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/bin/bash

# reset usb device by name (part)
# arg1: part of usb device name
reset_usb_device()
{
        local dev_name="$1"
        local usb_info=`lsusb | grep "$dev_name"`

        echo $usb_info
        local bus_num=`echo $usb_info | awk '{ printf("%.3s", $2) }'`
        local dev_num=`echo $usb_info | awk '{ printf("%.3s", $4) }'`

        local usb_dev_file=/dev/bus/usb/$bus_num/$dev_num

        echo $usb_dev_file

        /home/pi/src/usbreset $usb_dev_file

        #lsusb >> /home/pi/src/lsusb.txt
}

# check network status
# return: 0: inactive
#         1: active
is_network_active()
{
        local cnn=`/sbin/ifconfig wlan0 | /bin/grep  "inet addr:"`
        if [ "$cnn" = "" ]; then
                return 0
        fi
        return 1
}

# restart wlan0
wlan0_up()
{
        local act=0
        local retry=0
        while [ $act -eq 0 ]
        do
                ifup --force wlan0
                is_network_active
                act=$?
                echo $act
                retry=`expr $retry + 1`
        done
        echo retry $retry
}

# main
is_network_active
if  [ $? -eq 0 ]; then
        reset_usb_device "WLI-UC-GNHP Wireless LAN Adapter"
        #reset_usb_device "Genesys Logic, Inc. USB-2.0 4-Port HUB"
        sleep 5s        #wait for device up
        wlan0_up        #ifup
        logger "wlan0 restarted"
fi

ちょっと長くなったので、関数とか使ってみました。

ちなみにRaspberryPiにはキーボードとかモニタとか付いてないので、すべてSSH経由での作業です。

インターフェースぶち切るスクリプトをネットワーク経由で作るので、

ヘマするとすぐ繋がらなくなります。

なんかMS-DOSでプログラム作ってて、暴走させるとリセットするしか無かったあの頃を思い出しますな。

とりあえずこれでまた様子見です。