Raspberry Pi3をSORACOM経由で通信&自動接続に挑戦

# 概要
[以前の記事](http://qiita.com/yumatsud/items/83732a5be3fe80b1054b)で、Raspberry Pi3(以後ラズパイ)の初期設定が終わりました。
引き続き、SORACOMを利用した通信ができるように設定して見たいと思います。

# ゴール
* ラズパイをSORACOMを利用して通信できるようにする
* ラズパイにSORACOMを差したら自動で接続するようにする

# 準備するもの
* [SORACOM Air](https://soracom.jp/services/air/)
    * SORACOMの初期設定は、[SORACOM の利用を始める](https://dev.soracom.io/jp/start/begin_soracom/)をご参照ください
* [3G USB ドングル (FS01BU)](https://www.amazon.co.jp/%E5%AF%8C%E5%A3%AB%E3%82%BD%E3%83%95%E3%83%88-3G-USB-%E3%83%89%E3%83%B3%E3%82%B0%E3%83%AB-FS01BU/dp/B015J4WVEO/ref=sr_1_1?s=computers&ie=UTF8&qid=1443920096&sr=1-1&keywords=FS01BU)
* SORACOMのSIMでnanoを利用する場合(携帯などでも使えるため)、[Nano SIM MicroSIM 変換アダプタ](https://www.amazon.co.jp/mobee-MicroSIM-%E5%A4%89%E6%8F%9B%E3%82%A2%E3%83%80%E3%83%97%E3%82%BF-3%E7%82%B9%E3%82%BB%E3%83%83%E3%83%88-2%E5%80%8B%E3%82%BB%E3%83%83%E3%83%88/dp/B010H4IPVO/ref=pd_bxgy_147_img_3?_encoding=UTF8&psc=1&refRID=VMWMRSTFGRQGNMSR4TC1)もあると良いです

# 機器の接続
* SORACOMのSIMを変換アダブタにセット。FS01BUの蓋を開けて中のSDカード差し込み口を引っ張り出す
![IMG_4141.JPG](https://qiita-image-store.s3.amazonaws.com/0/71637/1e1d0b76-1e88-11c9-ce6c-a2b9ac9cf8a8.jpeg)

* SDカードに変換アダブタに入れたSIMごとセットし、ラズパイのUSBに差し込む
![IMG_4140.JPG](https://qiita-image-store.s3.amazonaws.com/0/71637/1f1770b4-7781-b0c8-8c1a-a9c65b6fca32.jpeg)

* FS01BUの点滅が緑になったら準備OK!!

# ラズパイ側の設定
* 認識されているUSBデバイスの確認。

```
$ lsusb 
Bus 001 Device 007: ID 1c9e:6801 OMEGA TECHNOLOGY ※1
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
```
※1 FS01BUはOMEGA TECHNOLOGY社製。Vender IDが1c9e、Product IDが6801。

* デバイスの認識

```
■確認
下記コマンドで、USBデバイスが表示されれば使用可能。もしない場合は、次の認識コマンドを実行
$ ls -l /dev/ttyU*
crw-rw---- 1 root dialout 188, 0  1月  6 18:48 /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 1  1月  6 18:47 /dev/ttyUSB1
crw-rw---- 1 root dialout 188, 2  1月  6 18:47 /dev/ttyUSB2

■認識コマンド
$ sudo modprobe usbserial vendor=0x1c9e product=0x6801
```
* ダイヤル実行をするために、wvdialをインストール 

```
$ sudo apt-get install wvdial 
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
・・・・・・
Success!  You can run "wvdial" to connect to the internet.
  (You can also change your configuration by editing /etc/wvdial.conf)

libc-bin (2.19-18+deb8u6) のトリガを処理しています ...
systemd (215-17+deb8u5) のトリガを処理しています ...
```
* USBのデバイス部分を固定するため(場合によっては/dev/ttyUSB2とならない場合があるとのこと)、usb-modeswitchが入っていない場合はインストール

```
$ sudo apt-get install usb-modeswitch
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
usb-modeswitch はすでに最新版です。
```
* /etc/wvdial.confファイルの編集 (編集前にオリジナルファイルをBackupをとっておくと良さそう)

```/etc/wvdial.conf
[Dialer Defaults]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Init3 = AT+CGDCONT=1,"IP","soracom.io"
Dial Attempts = 3
Modem Type = Analog Modem
Dial Command = ATD
Stupid Mode = yes
Baud = 460800
New PPPD = yes
Modem = /dev/ttyUSB2
ISDN = 0
APN = soracom.io
Phone = *99***1#
Password = sora
Username = sora
Carrier Check = no
Auto DNS = 1
Check Def Route = 1
```
* wvdialを実行して接続(バックグラウンド実行)

```
$ sudo wvdial &
--> WvDial: Internet dialer version 1.61
--> Initializing modem.
--> Sending: ATZ
ATZ
OK
--> Sending: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
OK
--> Sending: AT+CGDCONT=1,"IP","soracom.io"
AT+CGDCONT=1,"IP","soracom.io"
OK
--> Modem initialized.
--> Sending: ATD*99***1#
--> Waiting for carrier.
ATD*99***1#
CONNECT 14400000
--> Carrier detected.  Starting PPP immediately.
--> Starting pppd at Fri Jan  6 19:21:38 2017
--> Pid of pppd: 12495
--> Using interface ppp0
--> pppd: [18]?6[01]
--> pppd: [18]?6[01]
--> pppd: [18]?6[01]
--> pppd: [18]?6[01]
--> pppd: [18]?6[01]
--> pppd: [18]?6[01]
--> local  IP address XX.XXX.XXX.XX
--> pppd: [18]?6[01]
--> remote IP address XX.XX.XX.XX
--> pppd: [18]?6[01]
--> primary   DNS address XXX.XXX.X.XX
--> pppd: [18]?6[01]
--> secondary DNS address XXX.XXX.X.XX
--> pppd: [18]?6[01]
```
自分のIPアドレスやプライマリDNSのIPアドレスが表示されればOK。さらにFS01BU本体のLEDが緑色で点灯したままになると、通信中の状態を示しているよう。

* 接続確認

```
■ifconfigでの確認
$ ifconfig ppp0
ppp0      Link encap:Point-to-Pointプロトコル  
          inetアドレス:XX.XXX.XXX.XX P-t-P:10.64.64.64  マスク:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  メトリック:1
          RXパケット:7 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:8 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:3 
          RXバイト:130 (130.0 B)  TXバイト:181 (181.0 B)

■curlやping
$ curl http://www.yahoo.co.jp
$ ping www.yahoo.co.jp
```
* 切断

```
$ fg
sudo wvdial
<<Ctrl+C>>
Caught signal 2:  Attempting to exit gracefully...
--> Terminating on signal 15
--> pppd: [18]?6[01]
--> Connect time 8.5 minutes.
--> pppd: [18]?6[01]
--> pppd: [18]?6[01]
--> pppd: [18]?6[01]
--> Disconnecting at Fri Jan  6 19:30:08 2017
```







# 自動接続の設定
現状のままだと、電源を消したり、ログアウトするたびに接続が切れてしまい、再度wvdialを実行しないといけない。
ラズパイ起動時に自動接続するようにしてみる。方法としては下記のいずれか。

* ```udev``` でデバイス挿抜時に ```ifup/ifdown``` を実行する
* ```Systemd``` でサービスの登録を行う

下記には両方やって見た手順を書きますが、2つ目はうまくいかずでした。。
もし2つ目の方法の原因がわかる方がいらっしゃいましたらコメント頂けると嬉しいです。


## ①udev/ifup/ifdownを使う
下記の記事を大いに参考にさせて頂きました！良記事、ありがとうございます！

* [Raspberry PiでUSBモデム挿入時にSORACOMへ自動接続する](http://qiita.com/gimy/items/1d49f8e08210e9c9f20a)

### スクリプトの設定
自動接続前までの手続きを一発でやってくれる[手動設定スクリプト](https://gist.github.com/j3tm0t0/65367f971c3d770557f3)を実行すると、楽でしたw
ただし、既に設定が終わっている場合は下記は不要。

```
$ curl -O http://soracom-files.s3.amazonaws.com/connect_air.sh
$ chmod 755 ./connect_air.sh
$ sudo ./connect_air.sh
```

### ifupで接続、ifdownで切断
* ```/etc/network/interfaces```に下記を追加

```/etc/network/interfaces
allow-hotplug soracom
iface soracom inet wvdial
```
* ```ifup soracom``` で接続されることを確認

```
$ sudo ifup soracom
$ ifconfig ppp0
ppp0      Link encap:Point-to-Pointプロトコル
・・・・・
```
* ```ifdown soracom``` で切断されることを確認

```
$ sudo ifdown soracom
$ ifconfig ppp0
ppp0: インタフェース情報を取得中にエラーが発生しました: デバイスが見つかりません
```

* 自動再接続のために、pppdの再接続オプション**persist**を設定 (下記の2行を追加)

```
$ sudo vi /etc/ppp/peers/wvdial
・・・・・
persist
holdoff 10
```


### デバイスの固定
wvdial時に下記のようにUSBを指定しているが、他のUSB端子を刺したり、FS01BUを抜き差しすると、この番号がずれることがあるとのこと＞＜

```/etc/wvdial.conf
・・・・・
Modem = /dev/ttyUSB2
・・・・・
```

これだと自動接続に支障をきたすので、**[デバイス名を固定する](http://qiita.com/osada9000/items/3e6ff429ba782624def1)**の記事を参考にしつつ、接続するデバイスを固定にする。
下記のようにファイルを追加する。

```/etc/udev/rules.d/10-soracom.rules
KERNEL=="ttyUSB*", ATTRS{../idVendor}=="1c9e", ATTRS{../idProduct}=="6801", ATTRS{bNumEndpoints}=="02", ATTRS{bInterfaceNumber}=="02", SYMLINK+="ttyUSB_SoraomModem"
```

リブートしてUSBの接続状態を確認

```
$ sudo reboot
・・・・再度ログイン・・・・
$ ls -l /dev/ttyUSB*
crw-rw---- 1 root dialout 188, 0  1月  7 14:37 /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 1  1月  7 14:37 /dev/ttyUSB1
crw-rw---- 1 root dialout 188, 2  1月  7 14:37 /dev/ttyUSB2
lrwxrwxrwx 1 root root         7  1月  7 14:37 /dev/ttyUSB_SoraomModem -> ttyUSB2
```

できたできた。こうなると、wvdial.confに記載してあった内容は下記に変更

```/etc/wvdial.conf
・・・・・
Modem = /dev/ttyUSB_SoraomModem
・・・・・
```

### デバイス認識時に自動接続
最後に、デバイスを認識したタイミングで接続するようにする。
先ほどのudevルールの末尾に```ENV{SYSTEMD_WANTS}="ifup@soracom"```を追記

```
$ sudo vi /etc/udev/rules.d/10-soracom.rules
KERNEL=="ttyUSB*", ATTRS{../idVendor}=="1c9e", ATTRS{../idProduct}=="6801", ATTRS{bNumEndpoints}=="02", ATTRS{bInterfaceNumber}=="02", SYMLINK+="ttyUSB_SoraomModem", ENV{SYSTEMD_WANTS}="ifup@soracom"
```

これでリブート後、そしてUSBを抜き差ししても自動で接続できるようになりました！

```
$ sudo reboot

・・・・再度ログイン・・・・

$ ls -l /dev/ttyUSB*
crw-rw---- 1 root dialout 188, 0  1月  7 14:52 /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 1  1月  7 14:52 /dev/ttyUSB1
crw-rw---- 1 root dialout 188, 2  1月  7 14:52 /dev/ttyUSB2
lrwxrwxrwx 1 root root         7  1月  7 14:52 /dev/ttyUSB_SoraomModem -> ttyUSB2

$ ifconfig ppp0
ppp0      Link encap:Point-to-Pointプロトコル  

・・・・USBを抜き差し(下記はちょっとだけ接続までに時間を要しました・・・・

$ ls -l /dev/ttyUSB*
crw-rw---- 1 root dialout 188, 0  1月  7 14:54 /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 1  1月  7 14:54 /dev/ttyUSB1
crw-rw---- 1 root dialout 188, 3  1月  7 14:54 /dev/ttyUSB3
lrwxrwxrwx 1 root root         7  1月  7 14:54 /dev/ttyUSB_SoraomModem -> ttyUSB3

$ ifconfig ppp0
ppp0      Link encap:Point-to-Pointプロトコル
```

これでなんとか自動接続というゴールは達成！！

## ②Systemdを用いる方法
* [Systemd入門](http://enakai00.hatenablog.com/entry/20130914/13791461570)
* [Systemdを使ってさくっと自作コマンドをサービス化してみる](http://qiita.com/DQNEO/items/0b5d0bc5d3cf407cb7ff)

### Unitの作成
```/etc/systemd/system/wvdial.service
[Unit]
Description=wvdial service
Wants=network.target

[Service]
ExecStart=/usr/bin/wvdial
ExecStop=/bin/kill -HUP $MAINPID
Type=simple
Restart = always

[Install]
WantedBy=multi-user.target
```

### サービスの有効化
下記コマンドで自動起動をONにする

```
$ sudo systemctl list-unit-files --type=service | grep wvdial
wvdial.service                         disabled

$ sudo systemctl enable wvdial.service
Created symlink from /etc/systemd/system/multi-user.target.wants/wvdial.service to /etc/systemd/system/wvdial.service.

$ sudo systemctl list-unit-files --type=service | grep wvdial
wvdial.service                         enabled 
```

### サービスの操作
* 起動

```
$ sudo systemctl start wvdial.service
$ sudo systemctl status wvdial.service
● wvdial.service - wvdial service
   Loaded: loaded (/etc/systemd/system/wvdial.service; enabled)
   Active: active (running) since 金 2017-01-06 19:51:10 JST; 7s ago
 Main PID: 14735 (wvdial)
   CGroup: /system.slice/wvdial.service
           ├─14735 /usr/bin/wvdial
           └─14740 /usr/sbin/pppd 460800 modem crtscts defaultroute usehostname -detach user sora noipdefault call wvdial usepeerdns idle 0 logfd 6

 1月 06 19:51:13 darmaso-raspberry pppd[14740]: Could not determine remote IP address: defaulting to 10.64.64.64
 1月 06 19:51:13 darmaso-raspberry pppd[14740]: not replacing default route to wlan0 [XXX.XXX.X.X]
 1月 06 19:51:13 darmaso-raspberry pppd[14740]: local  IP address XX.XXX.XXX.XX
 1月 06 19:51:13 darmaso-raspberry pppd[14740]: remote IP address 10.64.64.64
 1月 06 19:51:13 darmaso-raspberry pppd[14740]: primary   DNS address XXX.XXX.X.XX
 1月 06 19:51:13 darmaso-raspberry pppd[14740]: secondary DNS address XXX.XXX.X.XX
 1月 06 19:51:13 darmaso-raspberry wvdial[14735]: --> local  IP address XX.XXX.XXX.XX
 1月 06 19:51:13 darmaso-raspberry wvdial[14735]: --> remote IP address 10.64.64.64
 1月 06 19:51:13 darmaso-raspberry wvdial[14735]: --> primary   DNS address XXX.XXX.X.XX
 1月 06 19:51:13 darmaso-raspberry wvdial[14735]: --> secondary DNS address XXX.XXX.X.XX

$ ifconfig ppp0
ppp0      Link encap:Point-to-Pointプロトコル
・・・・上記と同じ・・・・
```
* 停止

```
$ sudo systemctl stop wvdial.service
$ sudo systemctl status wvdial.service
● wvdial.service - wvdial service
   Loaded: loaded (/etc/systemd/system/wvdial.service; enabled)
   Active: failed (Result: exit-code) since 金 2017-01-06 19:54:48 JST; 3s ago ※2
  Process: 15112 ExecStop=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
  Process: 14735 ExecStart=/usr/bin/wvdial (code=exited, status=1/FAILURE)
 Main PID: 14735 (code=exited, status=1/FAILURE)

 1月 06 19:54:48 darmaso-raspberry pppd[14740]: Connect time 3.6 minutes.
 1月 06 19:54:48 darmaso-raspberry pppd[14740]: Sent 0 bytes, received 0 bytes.
 1月 06 19:54:48 darmaso-raspberry pppd[14740]: Connection terminated.
 1月 06 19:54:48 darmaso-raspberry wvdial[14735]: --> Terminating on signal 15
 1月 06 19:54:48 darmaso-raspberry wvdial[14735]: --> Connect time 3.6 minutes.
 1月 06 19:54:48 darmaso-raspberry wvdial[14735]: --> Terminating on signal 15
 1月 06 19:54:48 darmaso-raspberry wvdial[14735]: --> Disconnecting at Fri Jan  6 19:54:48 2017
 1月 06 19:54:48 darmaso-raspberry systemd[1]: wvdial.service: main process exited, code=exited, status=1/FAILURE
 1月 06 19:54:48 darmaso-raspberry systemd[1]: Stopped wvdial service.
 1月 06 19:54:48 darmaso-raspberry systemd[1]: Unit wvdial.service entered failed state.
```
※2 failedになっているが、ifconfigで確認すると、しっかり終わっている。。。謎＞＜

### 再起動後も接続されているか確認
* リブート

```
$ sudo reboot
```
* 再度ログインして状態を確認

```
$ sudo systemctl status wvdial.service
● wvdial.service - wvdial service
   Loaded: loaded (/etc/systemd/system/wvdial.service; enabled)
   Active: failed (Result: start-limit) since 土 2017-01-07 11:17:06 JST; 1h 38min ago
  Process: 659 ExecStart=/usr/bin/wvdial (code=exited, status=1/FAILURE)
 Main PID: 659 (code=exited, status=1/FAILURE)
```
・・・・・うまくいかない。。。調べてもあまりいい方法が見つからずに断念＞＜


# 終わりに
ラズパイとSORACOMの接続、コマンドを数回実行するだけでうまくいきました。
自動接続は色々と工夫しないといけないのがやや難点ですが＞＜

これでWifi環境に依存せずに、ラズパイをどこでも動かせそうです！

次は、AWS IoTを用いてなんかやってみようと思います！


# 諸々のメモ
| コマンドなど | 説明 |
|:--|:--|
| [lsusb](http://itpro.nikkeibp.co.jp/article/COLUMN/20140303/540548/?rt=nocnt) | USBデバイスを表示する |
| [modprove](http://itpro.nikkeibp.co.jp/article/COLUMN/20130909/503342/) | カーネルモジュールをロードまたはアンロードする |
| [wvdial](https://wiki.archlinuxjp.org/index.php/Wvdial) | Point-to-Point Protocol ダイアラで、インターネットに接続するためにモデムに発信して pppd を起動するもの |
| [usb_modeswitch](http://www.draisberghof.de/usb_modeswitch/) | USBのモードを動的に切り替えることができるもののよう。デバイスを固定するためのルールを記載するためなどに利用 |
| [ifup](http://itpro.nikkeibp.co.jp/article/COLUMN/20140122/531524/?rt=nocnt) | ネットワーク・インターフェースを有効にする |
| [ifdown](http://itpro.nikkeibp.co.jp/article/COLUMN/20140122/531526/) | ネットワーク・インターフェースを無効にする |
| **holdoff n** <br> (pppdオプション) | リンク切断から再初期化までn秒待つ。 persist または demand オプション使用時にのみ有効。  |

# その他参考記事
* [もうちょっと楽にRaspberry PiでSORACOM Airを使う(FS01BU USBモデムを用いて)](http://qiita.com/dietposter/items/bf3b0311a044eaf36df8)
* [Raspberry PiでSORACOM SIMを使う(FS01BU)](http://qiita.com/osada9000/items/9254646652717cba0267)
* [ネットワークの設定(debian公式サイト)](https://www.debian.org/doc/manuals/debian-reference/ch05.ja.html)