Ubuntu18.04LTSで仮想APを利用して古いiPadをサブモニターにする

※わかりづらいと思ったので、タイトルを変えました

[前回](https://qiita.com/faz479704/items/be673820581883290a0c)の結果、Ubuntuのホットスポットを経由することで、無線ネットワークがなくてもiPadをサブモニター化出来た。しかし、現実的にはインターネット接続せずにPCを操作することはなかなかないだろうから、前回の目的に掲げていた

- また、Ubuntuからはインターネットにも繋がるようにする

の実現を目指して、さらに深みにハマることとする。

## 仮想アクセスポイントの作成→失敗
ホットスポットと言うとWindows10の「モバイルホットスポット」をイメージしていたので、「無線ネットワークに繋ぎながらもWiFiホットスポットにもなる」ことができるはずだと考えてぐぐったところ、以下の投稿がマッチしていたので進めてみた。

(参考)
コマンド一発でLinuxマシンを即席無線LANルーターにできる「create_ap」がすごい便利だった
https://qiita.com/KuwaK/items/5903c7584657151d576a

```
$ sudo apt install hostapd
$ git clone https://github.com/oblique/create_ap
$ cd create_ap ← # カレントディレクトリに出来ている
$ sudo make install
```

やりたいことはインターネットへの接続とAPを同じ内臓無線のインターフェースを使いたいことので、WifiのI/FとAPのI/Fに内蔵無線のIFを指定して実行！

```
$ sudo ./create_ap wlp12s0 wlp12s0 ubuntu_ap passwd
ERROR: Your adapter does not support AP (master) mode
```

あ、なんか怒られた。

## 内蔵無線アダプタはAP対応か？→非対応
「アダプタが何かをサポートしていない」ってことなので、確認のため[こちらのサイト](https://wakanya.wordpress.com/2016/09/18/wifi%E3%82%A2%E3%83%80%E3%83%97%E3%82%BF%E3%81%8Cap%E5%AF%BE%E5%BF%9C%E3%81%8B%E8%AA%BF%E3%81%B9%E3%82%8B%E6%96%B9%E6%B3%95iw%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89/)を参考にしながら進めた。

```
$iw dev
phy#0
	Interface wlp12s0
		ifindex 3
		wdev 0x1
		addr 00:1b:77:9f:65:3b
		ssid aterm-b1d711-a
		type managed
		channel 36 (5180 MHz), width: 20 MHz (no HT), center1: 5180 MHz
		txpower 15.00 dBm
```

物理番号が「phy0」であることがわかったので、詳細情報を表示する。

```
$ iw phy phy0 info
Wiphy phy0
:
	Supported interface modes:
		 * IBSS
		 * managed
		 * monitor
	Band 1:
:
	interface combinations are not supported
:
$
```
このSupported interface modesに「AP」が含まれているとAPとして動作するとのことだが、残念ながらAPは含まれていない。また、combinationがサポートされていれば、WiFi接続とAPの両立はできるとのことだが、こちらもnot support。

ということで予想はしていたが、古いノートの内蔵無線アダプタでは目的＝無線ネットワークとホットスポット経由のサブモニターの両立は不可能であることはわかった。

## 外付け無線アダプタは？→AP対応！でも・・・
仕方ないので有象無象のデバイスを放り込んであった箱を探したら、USB接続(n/b/g、2.4GHzのみ)とPCカード(a/b/c、2.4GHz・5GHz両対応)の無線子機が見つかったので、それぞれをPCに接続してiwコマンドで確認した。

(PCカードの場合)

```
$ iw dev
phy#2
	Interface wlp29s0
		ifindex 5
		wdev 0x200000001
		addr 00:16:01:c6:44:30
		type managed
		txpower 20.00 dBm
:

$ iw phy phy2 info
:
        Supported interface modes:
                 * IBSS
                 * managed
                 * AP
                 * AP/VLAN
                 * monitor
                 * mesh point
        Band 1:
:
        software interface modes (can always be added):
                 * AP/VLAN
                 * monitor
        valid interface combinations:
                 * #{ managed } <= 2048, #{ AP, mesh point } <= 4,
                   total <= 2048, #channels <= 1
:
```
USBは割愛するが、どちらも上記のように「AP」が表示され、combinationsもnot supportedではないので使えると判断。

しかし、create_apを実行してみたところ

```

$ sudo ./create_ap wlp29s0 wlp29s0 ubuntu_ap passphrase
Config dir: /tmp/create_ap.wlp29s0.conf.dueX6muc
PID: 9149
Network Manager found, set ap0 as unmanaged device... DONE
wlp29s0 is already associated with channel 36 (5180 MHz), fallback to channel 36
Creating a virtual WiFi interface... ap0 created.

ERROR: Your adapter can not transmit to channel 36, frequency band 5GHz.


Doing cleanup.. done
```
ということでまたしてもエラーになってしまった。

## 改めて仮想アクセスポイントの作成
iw listの結果から外付けの無線アダプタが扱えるチャネルは１個ではあるが、36chで無線に繋がっているのであれば、同じ36chで仮想APは作れてもおかしくはないだろう。実際、create_apも36chを使っているのを認識しているからこそ、仮想APを36chで作ろうとしているのだから(デフォルトは1chで作られる)。

にもかかわらずエラーってどういうことだ？

またググりまわったところ、真偽はさだかではないが[ココのやり取り](https://github.com/oblique/create_ap/issues/107)を見ると、5GHz側には何らかの問題があるように読み取れた。

なので、無線ネットワークには2.4GHzで接続し直し、iw devコマンドで確認したチャネルをcreate_apのオプション(-c 9)として明示的に指定して起動した。

```
$ iw dev
phy#1
	Interface wlp29s0
:
		channel 9 (2452 MHz), width: 20 MHz (no HT), center1: 2452 MHz
		txpower 20.00 dBm
:
$ sudo ./create_ap -c 9 --freq-band 2.4 wlp29s0 wlp29s0 ubuntu_ap passphrase
Config dir: /tmp/create_ap.wlp29s0.conf.OsntY19U
PID: 17368
Network Manager found, set ap0 as unmanaged device... DONE
wlp29s0 is already associated with channel 9 (2452 MHz)
Creating a virtual WiFi interface... ap0 created.
Sharing Internet using method: nat
hostapd command-line interface: hostapd_cli -p /tmp/create_ap.wlp29s0.conf.OsntY19U/hostapd_ctrl
Configuration file: /tmp/create_ap.wlp29s0.conf.OsntY19U/hostapd.conf
Using interface ap0 with hwaddr 00:16:01:c6:44:31 and ssid "ubuntu_ap"
ap0: interface state UNINITIALIZED->ENABLED
ap0: AP-ENABLED 
```

ifconfigでは

```
$ ifconfig
ap0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.12.1  netmask 255.255.255.0  broadcast 192.168.12.255
:
wlp29s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.8  netmask 255.255.255.0  broadcast 192.168.0.255
:
```

iw devでは

```
$ iw dev
phy#1
	Interface ap0
:
		channel 9 (2452 MHz), width: 20 MHz (no HT), center1: 2452 MHz
	Interface wlp29s0
:
		channel 9 (2452 MHz), width: 20 MHz (no HT), center1: 2452 MHz
:
```

ということで、１つのチャネルを使ってようやく「ap0」という新しいI/Fが出来た。

ちなみに最初に手順を確認していく際には5Ghz(36ch)で仮想APが作れたのだが、再確認したときはいくらやっても5GHz側では作ることが出来なかった。完全に手順が同一ではないかもしれないが、5GHzでの動きが不定なところを見ると不具合の可能性は否めない(が、2.4GHzで出来たので、これ以上深追いはしないこととする)。

この状態でiPadから仮想APのIPアドレス（192.168.12.1)に接続すると、create_apを起動したターミナルにログが流れ、iPadからAPへ接続することが出来た(iPadには192.168.12.64が付与された)。

```
:
ap0: STA xx:xx:xx:xx:xx:xx IEEE 802.11: authenticated
ap0: STA xx:xx:xx:xx:xx:xx IEEE 802.11: associated (aid 1)
ap0: AP-STA-CONNECTED xx:xx:xx:xx:xx:xx
ap0: STA xx:xx:xx:xx:xx:xx RADIUS: starting accounting session 020ACAFD110D9584
ap0: STA xx:xx:xx:xx:xx:xx WPA: pairwise key handshake completed (RSN)
ap0: STA xx:xx:xx:xx:xx:xx WPA: group key handshake completed (RSN)
:
※xx:xx:xx:xx:xx:xxはiPadのMACアドレス
```

そして、iPadのVNC ViewerからAP(192.168.12.1)へ接続すると、iPadのVNCにPCの画面がっ！。

さらに、この状態でPCのブラウザからYahooやらGoogleにアクセス出来ることも確認。かくして、無線ネットワークを経由したインターネット接続と、AP経由でのサブモニター化の両方を実現に成功(^^)

なお、AP対応している無線アダプタであれば、ネットワークがない場合にホットスポットに切り替えるのではなく、この仮想AP作成する方法でもサブモニターは実現できる。

## サブモニターの描画スピード
自環境に限った話だが、無線ネットワークを通したときよりも、ホットスポット・APでほぼ直結した方が表示スピードが上がった気がする(※)。

※使用者個人の感想です

なので、VNC経由でのサブモニター化が遅い！と感じる場合は、この「ほぼ直結」とすることで、もしかしたらそのストレスが少しは解消されるかもしれない。

## まとめ
記事３回分に書き散らした内容を以下にまとめる。

### 事前作業
#### 必須
- PC：仮想ディスプレイ設定(cvt、xrandrでの設定、および自動化)
- PC：[設定]→[共有]→[画面共有]をアクティブにする(vinoの有効化、パスワード設定）
- タブレット：VNC Viewerのインストール

#### オプション(ネットワーク無しでもサブモニター化したい場合)
- PC：[画面共有]をアクティブ→有効に変更
- PC：vino-serverの手動起動(および自動実行設定)

### 実現方法
まず、PCで仮想ディスプレイを有効にして２画面にして適用する。その上で、環境に応じて以下の手順を取る。

#### 家の中など、ネットワークが自由に使える場合
- タブレット：PCと同一のネットワークに接続
- タブレット：VNCでPCのアドレスを指定して接続し、仮想ディスプレイ側を表示

#### 外出先など、ネットワークが無い場合
- PC：ホットスポットの有効化、またはhostapd+create_apによる仮想APの作成
- タブレット：ホットスポットまたは仮想APへ接続
- タブレット：VNCでホットスポットまたは仮想APに接続し、仮想ディスプレイ側を表示

#### フリーWiFiなど、ネット接続は出来ても自由に使えない場合
- PC：hostapd+create_apによる仮想APの作成
- タブレット：仮想APへ接続の上
- タブレット：VNCで仮想APへ接続し、仮想ディスプレイ側を表示

### 注意事項
- VNCサーバはubuntuの標準(画面共有)を利用する想定
- 仮想AP作成はAP対応した無線アダプタに限る。古いものは対応していないことがあるので注意(iw listで確認)

## 雑感
- 実用度は定かではないものの、思い描いたことが実現できたので満足
- 仮想APやらデバイスの状態確認方法などを少しかじれたのも、勉強という意味でよかった
- 仮想AP経由でdroidcamも使えたが、droidcamはUSB接続でも使える。サブモニター化もUSB接続で出来ればこんなに苦労しないのに・・・なのでubuntuでも動くアプリを誰か作って下さい