Raspberry Pi Zero W (WH) をAndroidからBluetoothで遠隔操作して入力するキーボードにする
どういうこと?
- Raspberry Pi Zero WをBluetoothによるシリアル通信でAndroidから制御できるようにします。
- Raspberry Pi Zero WをUSBキーボードにします。
- Androidで入力した文字をRaspberry PiがUSBキーボードとしてパソコンに打ち込みます。
どうして?(使用例)
大学にパソコン室というのがあって大学指定のノートパソコンよりも高機能なパソコンを講義中に使うことができます。
しかし、ログイン時には自分の大学アカウントのIDとパスワードを手打ちしなければなりません。
大学のアカウントということでパスワードはランダム文字列にしてあり講義の度に手打ちというのはなかなか……
パスワードマネージャーソフトを勝手にインストールはまずいでしょうし、ログイン前なので、ポータブル版も使えません……
そこで、ログイン前でも使えて、インストール不要の入力機器として、USBキーボードに白羽の矢が立ちました。
遠隔操作可能なUSBキーボードを学校PCに挿して、スマホからパスワードマネージャーでパスを打ち込んでやれば、ラクラクログインできるという算段です。
今回はそれを作る方法を備忘録的に残しておこうと思います。
あと、同じような悩みを抱えている人のお役に立てれば幸いです。
やり方
用意・Raspberry Piのセットアップ
今回使用するのは、
- Raspberry Pi Zero W(OSは2018-06-27-raspbian-stretch-lite)
- Windows10(TeraTermを用いたSSHでRaspberryPiを操作)
- Android 7.1.1
ラズパイはBluetoothが使えるものでRaspberry Pi Zero WHでも大丈夫ですが、Raspberry Pi3などはUSBポートが複数あるので、USBデバイスにはできないそうです。
AndroidではBluetoothでシリアル通信が可能なターミナルアプリを利用するだけなので、iPhoneにて代替アプリがあるのならば、iPhoneでも同様のことはできると思います。
microSDにRaspbianを焼く工程や、Raspberry Piにログインする方法は省略します。
こちらの方が紹介している方法などでRaspberry Piにコマンドを打ち込める状態にしてください。
準備が終わったら、Raspberry Piは普段使われる電源ポートではなく、USBポートを用いてパソコンのUSBコネクタと接続させます。
(USBポートからでも電力は供給されるみたいです。)
また、接続させるパソコンはRaspberryPiにSSHを行っているものには使わないことをおすすめします。(操作を間違え暴走すると、RaspberryPiを止める手立てがなくなるため)
AndroidにはOTGケーブル(microUSBと普通のパソコンに使われるUSB Type-Aの変換アダプタ)があれば、RaspberryPiを接続しキーを入力させることができます。
次に、aptコマンドで各種パッケージを更新し、RaspberryPiを再起動します。
sudo apt update sudo apt -y upgrade sudo reboot
そして、カーネルバージョンを確認します。
uname -a
今回実行した結果は以下の通りでした。
Linux raspberrypi 4.14.70+ #1144 Tue Sep 18 17:20:50 BST 2018 armv6l GNU/Linux
Raspberry Pi Zero (W) をUSBキーボード(USBガジェット)にする - Qiita
によると、4.4以上あれば大丈夫だそうです。
これで下準備は完了です。
RaspberryPiをUSBキーボードにする
次に、RaspberryPiを接続したパソコンに対してUSBキーボードとして認識されるようにします。
こちらの記事を参考にしました。
まず、USBデバイスとしてのセットアップ用シェルスクリプトを作成し実行します。
ホームディレクトリで作業をすることとして、フォルダを作ります。
cd ~ mkdir otg cd otg
次に、otgフォルダ内で以下のシェルスクリプトsetupOTG.sh
を作成します。
nano setupOTG.sh
これでテキストエディタnanoが開いて、以下のシェルスクリプトを打ち込んだら、ctr+x
で保存です。
#!/bin/bash # See https://gist.github.com/gbaman/50b6cca61dd1c3f88f41 for more info echo "dtoverlay=dwc2" | sudo tee -a /boot/config.txt echo "dwc2" | sudo tee -a /etc/modules
これを実行します。
sudo bash setupOTG.sh
そうしたら、一度再起動して設定を反映させてください。
sudo reboot
再度、RaspberryPiにログインしたら、作業用のディレクトリに戻ります。
cd ~/otg
次に、hid.sh
を作成します。これを実行した瞬間からPCにキーボードとして認識されますが、起動するたびに実行し直さなければならないスクリプトです。
まず作成します。
nano hid.sh
シェルスクリプトの内容は以下の通りです。
#!/bin/bash modprobe libcomposite cd /sys/kernel/config/usb_gadget/ mkdir -p g1 cd g1 echo 0x1d6b > idVendor # Linux Foundation echo 0x0104 > idProduct # Multifunction Composite Gadget echo 0x0100 > bcdDevice # v1.0.0 echo 0x0200 > bcdUSB # USB2 mkdir -p strings/0x409 echo "deadbeef01234567890" > strings/0x409/serialnumber echo "example.com" > strings/0x409/manufacturer echo "Generic USB Keyboard" > strings/0x409/product N="usb0" mkdir -p functions/hid.$N echo 1 > functions/hid.$N/protocol echo 1 > functions/hid.$N/subclass echo 8 > functions/hid.$N/report_length echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 > functions/hid.$N/report_desc C=1 mkdir -p configs/c.$C/strings/0x409 echo "Config $C: ECM network" > configs/c.$C/strings/0x409/configuration echo 250 > configs/c.$C/MaxPower ln -s functions/hid.$N configs/c.$C/ # End functions ls /sys/class/udc > UDC
管理者権限で実行します。
sudo bash hid.sh
これでls /dev
等で確認すると/dev/hidg0
というファイルが現れているはずです。このファイルにデータを書き込むことで、キーボードからパソコンに文字が入力されます。
しかし、このままではls -l /dev/hidg0
をすると権限が足りません。なので、以下のコマンドで権限を追加しておきます。
sudo chmod 777 /dev/hidg0
Raspberry Piからキーボードとして入力してみる
ここまでで、一応Raspberry Piによるキーボードが完成しました。
(hid.shを実行した時点でパソコンによってはキーボードが接続されたというメッセージが出ているはずです。)
ではキーボードとして使ってみます。
以下のコマンドは一行目が「a」を打ち込むもので、二行目が押されたキーを離すものです。
(操作を間違えてRaspberryPiによるキー入力でパソコンが操作できなくなった際は基本的に2行目のコマンドを実行すれば暴走は止まります。それでも止まらなかったら、RaspberryPiを引っこ抜いてマウス操作でPCを再起動するしかありません……)
sudo echo -ne "\0\0\x4\0\0\0\0\0" > /dev/hidg0 sudo echo -ne "\0\0\0\0\0\0\0\0" > /dev/hidg0
そして、キーボードとして認識させるための処理が起動時に自動的に行われるようにします。
sudo nano /etc/rc.local
以下の内容を/etc/profile
の最後に追記します。
sudo bash ~/otg/hid.sh sudo chmod 777 /dev/hidg0
これで、再起動してもキーボードとして認識されるようになりました。
もう少し扱いやすくします。以下のパッケージを使います。
まず、gitが標準ではついていなかったので、以下のコマンドで入手
sudo apt -y install git
以下のコマンドでパッケージを入手し、ビルドします。
cd ~ git clone https://github.com/girst/hardpass-sendHID cd hardpass-sendHID make
ビルドしたら、以下のコマンドを実行することでより簡単に文字が打ち込めます。
echo -n "hello world!" | sudo ./scan /dev/hidg0 1 2
Raspberry PiをAndroidからBluetoothで操作する
Bluetoothには擬似的なシリアル通信を行うプロファイルが存在し、AndroidのBluetoothに対応したシリアルコンソールとRaspberry Piを通信させることでログインが行えるようになります。
以下のサイトを参考にしました。
まず、Raspberry PiとAndroidをBluetoothで接続します。
以下のコマンドでBluetoothを操作します。
sudo bluetoothctl
すると、対話モードに移行するので以下のコマンドを順次実行してください。
power on discoverable on agent on default-agent
そして、AndroidのBluetooth設定画面を開くと「raspberrypi」という項目が現れているはずなので、ペアリングを開始してください。
ペアリングが開始されると、AndrodとRaspberryPiにPINコードが表示され、接続するか聞いてきます。
RaspberryPiとAndroidのPINコードが一致していたら承認して接続を確立してください。接続が確定したら、次回からは自動的に接続されるように設定します。
承認後に表示されたDevice xx:xx:xx:xx:xx:xx Paired: yes
のxx:xx:xx:xx:xx:xx
という部分を用いて、(人によって表示される内容は異なります。)
trust xx:xx:xx:xx:xx:xx
を実行すれば、再起動後も自動で繋がります。
quit
で対話モードを終了します。
そして、RaspberryPiのBluetoothにシリアル通信機能を追加します。一旦、Bluetoothサービスを終了させ、シリアル通信を追加するのは以下のコマンドです。
sudo systemctl stop bluetooth sudo bluetoothd -C & sudo hciconfig hci0 up sudo sdptool add SP
これで、シリアル通信機能が使えるようになりました。
以下のコマンドで、シリアル通信を用いてRaspberry Piへログインできるようになります。
sudo rfcomm watch 0 1 agetty rfcomm0 115200
ここまで、実行したら次にAndroidを操作します。
以下のアプリを使います。
このアプリをインストールし開いたら、まずデバイスを選択します。
左上からメニューを開き、Devices
を選択し、raspberrypi
を選択します。
次に、メニューからTerminal
に戻り、画面上部の接続アイコンを接続すれば接続が開始され、成功するとRaspberryPiにログインできます。
(結構な頻度で接続に失敗するので何度かリトライしたり、RaspberryPiの方で一旦Ctr+C
で接続待機状態を終了させ、再度実行してみてください。)
ここまで確認したら、再度画面上部のアイコンを再度タッチして、接続を解除します。
RaspberryPiに戻り、ctr+C
でシリアル通信を終了します。
次に、RaspberryPiが起動したら、すぐにAndroidで操作できるようにします。
/etc/rc.local
というファイルに記述した内容は起動時に実行されます。以下のコマンドで編集画面を開きます。
sudo nano /etc/rc.local
次に、以下のコマンドをrc.local
のexit 0
の上に記述します。
(exit 0
の下に記述しないでください。)
sudo systemctl stop bluetooth sudo bluetoothd -C & sudo hciconfig hci0 up sudo sdptool add SP sudo rfcomm watch 0 1 agetty rfcomm0 115200
(参考にした記事ではsdptoolにSPを追加するまでの一連の処理は一度きりでいいはずなんですけどね……)
これで、再起動してもAndroidから接続することができます。
遠隔キーボードソフトremipiを作りました
最後に、USBキーボードとなったRaspberryPiで最初に述べたパスワード遠隔入力作戦をしやすいようにremipiというソフトを作りました。
このソフトは、日本語もある程度は送れます。
なお、入力対象は日本語キーボードを持ったWindowsを想定しています。MacやLinux等で実行すると一部の機能が使えないかもしれません。
インストール方法
バイナリファイルをアップしているので、wget
で入手します。以下のコマンドで、バイナリファイルを実行可能なディレクトリにダウンロードします。
cd /usr/local/bin sudo wget https://github.com/tofuso/remipi/releases/download/ver1.0/remipi sudo chmod 777 remipi cd ~
これで、ソフトがインストールされました。
remipi -h
を実行すると、以下のように帰ってくるはずです。
Usage of remipi: -d string デバイスファイル (default "/dev/hidg0") -s string キーボードに出力させる文字を指定してください。 (default "Hello World!") -t 指定すると対話モードで起動します。Ctr+Cまたは_quit_を実行して終了。
これでインストール完了です。
使い方
入力させるPCのUSBポートとRaspberryPiのUSBポートをケーブルで繋ぎ、BluetoothターミナルやSSH等でログインします。
そして、入力されるPC側は半角入力状態で、メモ帳等を開いて、入力待機状態にしてください。
この状態で、以下のコマンドを実行します。
remipi -s こんにちは!
すると、メモ帳に日本語が入力されているはずです。
このようにコマンドから、一発でひらがなを打ち込むことができます。
今度はメモ帳を閉じて、デスクトップ画面にして、以下のコマンドを実行してみてください。
remipi -s _win-r__sec_notepad_enter__sec_このPCをあやつっている!
文字ではないキーボードの操作も_
で囲うことで行うことができます。
(詳しくはこちらで確認してみてください。)
なので、下のようなシャットダウン操作だってできてしまいます!
remipi -s "_win-r__sec_cmd.exe_enter__sec_shutdown -s -t 0_enter_"
このようなキーボードショートカットを利用してUSBキーボード単体で色々な事ができます。 これで、大学のパソコンに楽々ログインできるようになるはずです!
ここまでお付き合いいただきありがとうございました!
それからどうしたの?(PS.)
無事に大学のPCにUSBキーボードとして認識させて、パスワードを遠隔操作で打ち込むことができました!
本当はセキュリティとかで弾かれるんじゃないかと思ってた……
ちなみにそのパソコンは授業では使用しないそうです。そんなぁ……