アウトドアにおけるオフライン通話環境構築

#前置き
## オフライン通話とは
3G/4G回線パケット通信も利用せずに通話する環境。

---

主にツーリング時の走行中バイク間での通話に利用している人が多いと思われ、主流と思われる物はLINEやSkypeでのパケット通信による通話(以下パケット通話)だと思う。
パケット通話の問題は長距離トンネル時等の圏外に弱いこと。

また個人的な事だが
登山時に二者通話ができればいいなと思って構想を練った
登山時は基本的に圏外になることが多くパケット通話は論外となる。
（まだ構築後に実戦投入はやっていないが。）

よってパケット通話最大の弱点の圏外に耐える目的がオフライン通話となる。

## 解決方法
### アプリを使う
Android向け、iOS向けと各個に様々なアプリが存在するが
Android、iOS間での相互利用問題となる。
そのためマルチプラットフォームでは不可能になる。

### 全く別の方法としてトランシーバーを使う
PTT(プッシュトゥートーク)方式はあまり好ましくない
別途機材も必要
電池持ちはやはりいいが。
同時通話機もあるがいい値段。

### 無線？ハム？
免許…

## 結局

* できるだけ安価に(手持ちのスマホだけで)
* マルチプラットフォームな(Android、iOS両対応、あわよくば他の環境)
* 環境を構築しよう(どこのご家庭にもあるraspberry piで！)

# 構築
SIPサーバー、無線APにはraspberry pi zero wを使用しています。
移動中にUSB給電で動き省電力、省スペースを考慮するとzero wがいい具合かと。
pi3でも構築できますが電力消費的には好ましくないと思われるためzero wを利用しています。

構築図

![image.png](https://qiita-image-store.s3.amazonaws.com/0/150940/a8243acc-62fb-d388-6e33-646a2fbe5865.png)



基本的には複数のシステム構築の組み合わせになるため、
他の記事をまるっと利用しています。
そのため構築、設定はそちらへ譲ります。
(要望、気が向けば構築時の設定等を記載しますが。)

またzero wを利用する際、無線LANをAP化するのでUSBLANでインターネットに繋げる環境があった方が楽です。
また、Dashボタンの設定を入れるのもインターネット回線が必要になると思います。

1. SIPサーバの構築  
   https://tomosoft.jp/design/?p=10040  
   https://qiita.com/hasudon7171/items/925b9512f81cee46fbe3  
   SIPアカウントは2つ作っておく必要があります。  
   (例201/pass,202/pass)
2. 無線LANAPの構築  
   https://qiita.com/mt08/items/f2e4f9d3b1ed00849e23  
   (IP例 192.168.42.1 SSID例 raspzw)
3. AmazonDASHボタンの環境構築(オプション)
1. クライアントのSIP設定

AmazonDASHボタンについては
ボタンが押されたら
` sudo shutdown -h now `
を発行するスクリプトにして安全に電源をOFFにできるようにします。

```
cd
sudo apt-get update
sudo apt-get -y install libpcap-dev
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get -y install nodejs
npm install node-dash-button
cd node_modules/node-dash-button
```

AmazonDashボタンのMACアドレスの確認
` sudo node bin/findbutton `

シャットダウンスクリプト

```
cd
cd node_modules/node-dash-button
vi dash_shutdown.js
```


``` js:dash_shutdown.js
var dash_button = require('node-dash-button');
var dash = dash_button(["xx:xx:xx:xx:xx:xx"], null, null, 'all');
dash.on("detected", function (dash_id) {
        if (dash_id === "xx:xx:xx:xx:xx:xx") {
                console.log("shutdown");
                const execSync = require('child_process').execSync;
                const result =  execSync('sudo shutdown -h now');
                process.exit();
        }
});
```


sudo vi /etc/rc.local
`exit 0`の前に
シャットダウンスクリプト起動と

DHCPデーモンがうまく起動しないため10秒停止を噛ませる

```
sleep 10
service isc-dhcp-server start

node /home/pi/node-dash-button/dash_shutdown.js &
```

## クライアント設定
Androidでは機種によっては標準でSIPクライアント機能があります
iOSにもあったかと思います。

また、別途クライアントアプリが使いたい、SIPクライアント機能が無い
といった場合はストアからインストールして下さい。

* 端末1 
  無線LAN接続先 raspzw(raspberry pi zero w 無線LANAPのSSID) 
  SIPサーバー 192.168.42.1(raspberry pi zero w 無線LANAPのIP) 
  アカウント/パスワード 201/pass 
  待ち受け有り 
  通話方法 常に確認する(機種によって異なる)  
* 端末2
  アカウント/パスワード 202/pass 
  他は端末1と同じ

この状態で端末1から`202→インターネット通話`または`202@192.168.42.1`へ発信します。

端末2が着信し、通話ができれば成功

発信試験終了後
待ち受け有りの場合SIPサーバと通信が発生し電池消費が増えるため
待ち受け有り設定を解除しておきます。

### うまくいかない場合
ストアからのSIPクライアントを利用するのも手です。
ストアSIPクライアント単体で利用する際の利点はSIPを使わないときは全く利用する必要が無い
発信設定が別になるため発信時に「インターネット通話」の設定が不要になる
明確に発信設定が切り替えられる
等の利点があります。

欠点はアプリの性能次第。
消費電力等いろいろ…
「お勧めアプリ」というのはここでは記載しません。
「SIP」で検索すると色々出てきます。


## シャットダウン
いきなりUSB電源を抜くわけにも行かないため
Dashボタンをシャットダウンボタンの代わりに使っています。
押せばシャットダウン。

GPIOへボタンを取り付けてシャットダウンボタン化するのも有効だと思います。
※本記事では扱いません。

## 最終動作確認
* 電源OFF状態ですべての接続を解除(USBLANやHDMI等)
* 電源USBを再接続しrasp zero wを起動
* 公衆回線に出ていかないよう一応端末1、端末2を機内モードに設定  
  無線LANのみON設定
* rasp zero w起動後しばらく後端末1、端末2をrasp zero wのAP(raspzw)へ接続
* 端末からはインターネット接続無しとなること
* SIPアカウントを待ち受け有りに設定
* 端末1、2間で発信
* 着信通話できれば成功
* Dashボタンでシャットダウン確認

# その他

## 消費電力
rasp zero wをUSBのワットチェッカーに繋いで簡易測定
端末とzero wの距離は50cm程度

* 起動中  
  100～200mA
* 待機中  
  100～140mA
* 端末2台AP接続  
  100～140mA
* 端末2台通話  
  100～140mA

そんなに変わらないですね

両端末とも5mほど離して通話状態にしましたが
目立つほどの変化は見られず。

## 遅延
機種やアプリによって遅延が気になる気がします。
Android7の端末(Xperia performance)からの声はほぼ遅延は発生しませんでしたが古い端末からの声は徐々に遅延が発生する感じでした。
iOSは知りません。
機会があれば友達のを繋いでみたいと思います。

## 通信距離
どのくらい飛ぶのでしょうかね。
計測はしていませんが。。

しかしPi3で10mも飛ばない様です

## 強化構想、課題
USB無線LANを利用しバッグ等からアンテナを出した状態で通信すると
当然ながら結構通信改善すると思われます。
https://www.amazon.co.jp/dp/B009GQNMQ8/
https://www.amazon.co.jp/dp/B00BQ6WPQ4/