HW502 を USB モデムとして Linux に認識させる

# HW502 を安定したインターネットルーターとして使う

## 概要
Linux から HW502 を安定したインターネットルーターとして使うようにするために、無線ではなく USB 接続を行ってみます。usb modeswitch を使ってモデムとして認識させ、ttyUSB に AT コマンドを投入する手がそこかしこに紹介されていますが、HW502 については HUAWEI のドライバが必要なかわりに、AT コマンドを入力する必要はありません。


## 環境
* OS: CentOS 6.9 (32 bit)
* USB モデム: [ソフトバンクの HW502](https://www.ymobile.jp/lineup/502hw/)
* USB モデムを接続するノート: VAIO VPCX119KJ (32bit, wlan0, eth0)

## HUAWEI ドライバ作成の下準備

HUAWEI 用 ndis ドライバがコンパイルするための必要なパッケージを投入します。

```shell-session
# yum install kernel-devel kernel-headers
# yum groupinstall "Development tools"
```
usb デバイスの ID を変更してモデムモードにする usb modeswitch （usb_modeswitch および usb_modeswitch-data パッケージ）は不要です。HUAWEI Data Cards Linux Driver に付属する usbmod が相当する機能をもつようです。usb modeswitch との同居も可能ですが、HUAWEI Data Cards Linux Driver のインストール時に HUAWEI 系のモデムの設定 **/etc/usb_modeswitch.d/12d1:*** は全部消去されます。

## HUAWEI Data Cards Linux Driver 4.19.19.00 のダウンロード

公式サイトにはすでに掲載がないので
[MyUSBModem.Com](http://download.myusbmodem.com/index.php?dir=/Huawei%20miscellaneous&start=1) から **HUAWEI Data Cards Linux Driver.zip[7.11 mb]** をクリックします。
```
» Download File
```
とあるので、クリックはせず URL だけコピーして **HUAWEI Data Cards Linux Driver.zip** をダウンロードします。

```shell-session
$ wget http://download.myusbmodem.com/home/Huawei%20miscellaneous/HUAWEI%20Data%20Cards%20Linux%20Driver.zip
```

解凍します。

```shell-session
$ mkdir ~/HUAWEI
$ cd ~/HUAWEI
$ unzip HUAWEI\ Data\ Cards\ Linux\ Driver.zip
$ tar xvfz Linux\ Driver\ 4.19.19.00.tar.gz
$ ls
Installation Guide.txt  Linux Driver 4.19.19.00.tar.gz  driver
```

## /lib/modules/2.6.32-696.el6.i686/build のリンク張替

```shell-session
# cd /lib/modules/2.6.32-696.el6.i686/
# rm build
# ln -s ../../../usr/src/kernels/2.6.32-696.30.1.el6.i686 build
$ ls -la /lib/modules/2.6.32-696.el6.i686/build
lrwxrwxrwx. 1 root root 49  6月 11 19:16 2018 /lib/modules/2.6.32-696.el6.i686/build -> ../../../usr/src/kernels/2.6.32-696.30.1.el6.i686
```

恐らく build のシンボリックリンク先が `./../../usr/src/kernels/2.6.32-696.el6.i686` となっているので正しく張り替えます。直さないとドライバがコンパイルできません。

## ドライバのコンパイルとインストール

```shell-session
$ cd ~/HUAWEI/driver/
$ sudo su
# ./install
old path =/usr/local/Mobile_Partner/driver
DRIVER COPY START
STA_PATH_FLAG=.
STA_PATH_FULL=/home/yamachan/HUAWEI/driver/install
START_PATH_DRIVER=/home/yamachan/HUAWEI/driver
CURRENT install from ./install
INSTALL_PATH is not set ,auto install
INSTALL_PATH=/usr/local/Mobile_Partner
INSTALL_PATH is another path
rm /usr/local/Mobile_Partner/driver
DRIVER COPY END
ls: cannot access /etc/usb_modeswitch.d/: そのようなファイルやディレクトリはありません
have usb_modeswitch rules to HUAWEI DataCard: COUNT=0
ls: cannot access /dev/ttyUSB?: そのようなファイルやディレクトリはありません
ttyUSB%n not exist,ok
ERROR: Removing 'cdc_ether': No such file or directory
ERROR: Removing 'usbnet': No such file or directory
ERROR: Removing 'hw_cdc_driver': No such file or directory
make -C src/ clean
make[1]: ディレクトリ `/usr/local/Mobile_Partner/driver/ndis_driver/ndis_src/src' に入ります
rm -rf *.o *.ko *~ core* .dep* .*.d .*.cmd *.mod.c *.a *.s .*.flags .tmp_versions Module.symvers Modules.symvers *.order
/usr/local/Mobile_Partner/driver/ndis_driver/ndis_src/src/add_header.sh  "clean" "/lib/modules/2.6.32-696.el6.i686/build/include/linux/usb"
rmmod -f hw_cdc_driver
ERROR: Removing 'hw_cdc_driver': No such file or directory
make[1]: *** [clean] エラー 1
make[1]: ディレクトリ `/usr/local/Mobile_Partner/driver/ndis_driver/ndis_src/src' から出ます
make: *** [clean] エラー 2
make -C src/ modules
make[1]: ディレクトリ `/usr/local/Mobile_Partner/driver/ndis_driver/ndis_src/src' に入ります
#/usr/local/Mobile_Partner/driver/ndis_driver/ndis_src/src/add_header.sh  "modules" "/lib/modules/2.6.32-696.el6.i686/build/include/linux/usb"
make -C /lib/modules/2.6.32-696.el6.i686/build SUBDIRS=/usr/local/Mobile_Partner/driver/ndis_driver/ndis_src/src modules
make[2]: ディレクトリ `/usr/src/kernels/2.6.32-696.30.1.el6.i686' に入ります
  CC [M]  /usr/local/Mobile_Partner/driver/ndis_driver/ndis_src/src/hw_cdc_driver.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /usr/local/Mobile_Partner/driver/ndis_driver/ndis_src/src/hw_cdc_driver.mod.o
  LD [M]  /usr/local/Mobile_Partner/driver/ndis_driver/ndis_src/src/hw_cdc_driver.ko.unsigned
  NO SIGN [M] /usr/local/Mobile_Partner/driver/ndis_driver/ndis_src/src/hw_cdc_driver.ko
make[2]: ディレクトリ `/usr/src/kernels/2.6.32-696.30.1.el6.i686' から出ます
strip --strip-debug hw_cdc_driver.ko
make[1]: ディレクトリ `/usr/local/Mobile_Partner/driver/ndis_driver/ndis_src/src' から出ます
make -C src/ install
make[1]: ディレクトリ `/usr/local/Mobile_Partner/driver/ndis_driver/ndis_src/src' に入ります
#install -m 744 -c hw_cdc_driver.ko /lib/modules/2.6.32-696.el6.i686/kernel/drivers/usb/net
#depmod -a
#modprobe hw_cdc_driver
/usr/local/Mobile_Partner/driver/ndis_driver/ndis_src/src/add_header.sh  "install"
modprobe hw_cdc_driver
make[1]: ディレクトリ `/usr/local/Mobile_Partner/driver/ndis_driver/ndis_src/src' から出ます

The Linux NDIS driver is installed successfully.
USBSERIAL_TARGET_PATH =
ACM_TARGET_PATH =
ADDRUNLEVEL=/etc/rc.d/rc2.d
`/etc/rc.d/rc2.d/S99runhwactivator' -> `/etc/init.d/runhwactivator'
`/etc/rc.d/rc2.d/K10runhwactivator' -> `/etc/init.d/runhwactivator'
ADDRUNLEVEL=/etc/rc.d/rc4.d
`/etc/rc.d/rc4.d/S99runhwactivator' -> `/etc/init.d/runhwactivator'
`/etc/rc.d/rc4.d/K10runhwactivator' -> `/etc/init.d/runhwactivator'
ADDRUNLEVEL=/etc/rc.d/rc5.d
`/etc/rc.d/rc5.d/S99runhwactivator' -> `/etc/init.d/runhwactivator'
`/etc/rc.d/rc5.d/K10runhwactivator' -> `/etc/init.d/runhwactivator'
ADDRUNLEVEL=/etc/rc.d/rc3.d
`/etc/rc.d/rc3.d/S99runhwactivator' -> `/etc/init.d/runhwactivator'
`/etc/rc.d/rc3.d/K10runhwactivator' -> `/etc/init.d/runhwactivator'
qmi_wwan interface not exist,ok
```

**The Linux NDIS driver is installed successfully.**
が出ていれば成功です。このメッセージの後に Enter を入力後、起動のスクリプトが設定され、ドライバのインストールはすべて完了します。ここでモデムをつないでリブートをかけると認識はしますが違うドライバがアタッチされるので、下記「不要なドライバの除外」の設定を行わないと通信はできません。

### ttyUSB%n not exist,ok について

インストールされる `/lib/udev/rules.d/10-Huawei-Datacard.rules` に従い `/dev/ttyUSB_utps_pcui` というデバイスができます。 `10-Huawei-Datacard.rules` で usbmod （インストールされます）をつかってモデムモードに切り替える設定が記述されています。

### インストールしたドライバを消去しようとして失敗している

```
ERROR: Removing 'cdc_ether': No such file or directory
ERROR: Removing 'usbnet': No such file or directory
ERROR: Removing 'hw_cdc_driver': No such file or directory
```
余計なドライバの消去にかかるようでパスが狂っているらしくうまくいきません。代わりに「不要なドライバの除外」で手当します。 `cdc_ether`  については、モデムにはアタッチされないので放置。  `usbnet` はこの後「不要なドライバの除外」でアタッチされないよう設定します。 `hw_cdc_driver` はインストールされる HUAWEI モデム専用の下記「不要なドライバの除外」の後に認識するようになります。

## 不要なドライバの除外

[参考: Linux Mint 13以降 (最近のDebian系) でPocket Wifi GL04Pをeth*として使用する](http://sunatomo.blogspot.com/2014/02/linux-mint-15pocket-wifi-gl04peth.html)
インストール時に余計なドライバの消去が失敗に終わるので代わりの手段で回避します。まず、余計なドライバが読み込まれているときは次のようになります。

```shell-session
$ lsmod
Module                  Size  Used by
略
option                  8593  0
usb_wwan                9350  1 option
usbserial              30508  2 option,usb_wwan
hw_cdc_driver          35399  0
cdc_ncm                14948  0
usbnet                 30456  1 cdc_ncm
mii                     4476  2 hw_cdc_driver,usbnet
略
```
`hw_cdc_driver` 以外に `cdc_ncm` / `usbnet` が追加された場合、正常に動作しません。 特に `mii` の下には `hw_cdc_driver` 以外はあってはいけません。 `/etc/modprobe.d/` にブラックリストとして記載し、そのモジュールを読み込ませないようします。

```text:/etc/modprobe.d/blacklist-huawei.conf
blacklist cdc_ncm
blacklist usbnet
```
## リブート / 動作確認
ここまできたら 502HW を USB 接続してリブートします。モジュールが次のようにアタッチされれば正しくインストールされています。

```shell-session
$ lsmod
Module                  Size  Used by
略
option                  8593  0
usb_wwan                9350  1 option
usbserial              30508  2 option,usb_wwan
略
hw_cdc_driver          35399  0
mii                     4476  1 hw_cdc_driver
```

同時に eth1 にモデムが接続されていることが確認できます。IP アドレスも自動で降ってきます。

```shell-session
$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:1D:BA:BD:8A:84
          inet addr:192.168.2.242  Bcast:192.168.2.255  Mask:255.255.255.0
          inet6 addr: fe80::21d:baff:febd:8a84/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8622 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12479 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:695249 (678.9 KiB)  TX bytes:4107729 (3.9 MiB)
          Interrupt:17

eth1      Link encap:Ethernet  HWaddr 00:1E:10:1F:00:01
          inet addr:192.168.128.102  Bcast:192.168.128.255  Mask:255.255.255.0
          inet6 addr: fe80::21e:10ff:fe1f:1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:590 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:282465 (275.8 KiB)  TX bytes:1160 (1.1 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:480 (480.0 b)  TX bytes:480 (480.0 b)
```
`/etc/init.d/runhwactivator` により起動時に `HWActivator` を常駐させて、これが AT コマンドをモデムに発行し ppp 認証を行うようです。 

```shell-session
$ ps auxf | grep HW
root      7106  0.0  0.0   5392   784 pts/1    S+   11:10   0:00                          \_ grep HW
root      4201  0.1  1.6  36000 34508 ?        S<   10:29   0:02 /usr/local/Mobile_Partner/driver/HWActivator .bin
```
[Linux Driver 4.19.19.00 Tool User Guide](https://slidedocuments.org/the-philosophy-of-money.html?utm_source=linux-driver-4-19-19-00-tool-user-guide&utm_campaign=download) には延々 ppp 認証のやり方が書いてありますが、このモデムは該当しません。

## wwan0 が見えるときはうまくいってません

不要なドライバがアタッチされているときは、 `ifconfig -a` で `wwan0` ができてモデムとして認識されているのはわかります。けれども IP アドレスが降ってきませんので通信はできません。以下は `wwan0` が見えているので **失敗しています**。

```shell-session
$ ifconfig -a
eth0      Link encap:Ethernet  HWaddr 00:1D:BA:BD:8A:84
          inet addr:192.168.2.242  Bcast:192.168.2.255  Mask:255.255.255.0
          inet6 addr: fe80::21d:baff:febd:8a84/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:969 errors:0 dropped:0 overruns:0 frame:0
          TX packets:789 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:79506 (77.6 KiB)  TX bytes:234603 (229.1 KiB)
          Interrupt:17

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:480 (480.0 b)  TX bytes:480 (480.0 b)

wlan0     Link encap:Ethernet  HWaddr 00:26:5E:FC:3A:F7
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

wwan0     Link encap:Ethernet  HWaddr 00:1E:10:1F:00:00
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
```