Raspberry Pi Zero W を、USB キーボードにする

(更新

Configuring a Raspberry Pi Zero W as a general USB keyboard (USB HID device).

今日はちょっとした「お遊び」をしてみました。と言っても、私にとっては真面目な課題なのでした。

Apple の Mac OS では、「システム環境設定」の「省エネルギー」設定で「ネットワークアクセスによるスリープ解除」を有効にしておくと、外部からの(いわゆる)magic packet で Mac を起こすことができます。コマンドラインで設定する場合は、

pmset -a womp 1

とかいう感じです。一度設定しておけば、他のパソコン(あるいは Raspberry Pi など)から 寝ている Mac に magic packet を送ることで、(VPN などを使っていれば社外、屋外からでも)起こすことができる便利な機能です。

こいつは便利なのですが、ちょっと問題もあって、同じサブネット内に Apple の Wi-Fi アクセスポイントがあるからかも知れないのですが、ユーザーが magic packet を意図的に送らない場合でも頻繁に Mac が起き上がってしまい、寝室に Mac があったりすると、けっこう煩わしいことになります。(寝ているときに、ハードディスクのスピンドルアップの音が聞こえたりします。)

そこでちょっと考えたのは、USB HID デバイスを真似た「偽物」のキーボードを Mac に繋いでおき、外部からあたかもシフトキー(コントロールキーなどでも良いのですが)を押してあげることで、Mac を起こしてやれば良いのではないか、というものです。パソコンは、キーボードのキーを何か叩くと起きるようになっていますからね。

さて。ここで紹介したような Arduino ボードを USB HID デバイスとして動作させることことで擬似的なキーボードにすることもできますが、問題は、遠隔から制御しようとすると Ethernet や Wi-Fi にも繋げられなければいけない、ということです。そうなると、Arduino よりも Raspberry Pi Zero W などを USB HID デバイスにしてあげたほうが、ハード工作の手間もなく簡単に実現できそうです。

整理しましょう。通常、Raspberry Pi の USB ポートは「USB ホスト」として使うのが一般的で、外部に「USB デバイス」であるキーボードや USB メモリを繋ぐのですが、Pi Zero W の USB は USB On-The-Go 規格になっているので、逆に「USB デバイス」として、あたかもキーボードや USB メモリのように振る舞うことができる、ということになります。そして、Raspberry Pi に外からリモートログインできるようにしてあげれば、USB で接続した他のパソコンのキーボードとして振る舞える、ということになります。つまり外部からリモートログインしてコマンドをタイプすると、他のパソコンを遠隔制御できる、という訳ですね。

参考サイト

参考になるサイトとしては、以下があります。

なお、実際にシフトキーを押してあげるには、次のようなコードのシェルスクリプトを実行すれば OK です。

#!/bin/sh

/bin/echo -ne "\x02\0\0\0\0\0\0\0" > /dev/hidg0
sleep 1
/bin/echo -ne "\0\0\0\0\0\0\0\0" > /dev/hidg0

なお、/dev/hidg0 の操作には root 権限が必要なので、sudo を使うと良いでしょう。

最後になりましたが、このような使い方をする場合、USB ケーブルは USB OTG ポートだけに繋げば Raspberry Pi Zero W 自身の給電も可能です。便利ですね!

今日はここまで。

重要な後記(オチ)(2018/03/05)

これを書いてから試したのですが、寝ているパソコン(Mac)を起こすことができませんでした。どうやら、この機能を USB の規格で「remote wakeup」というらしいのですが、そのままでは HID のガジェットドライバでは remote wakeup できないぽいです。

まず最初に、bmAttributes という項目で bit 5 を 1 にしておかないといけないようですが、それだけではダメで、 USB シグナリングで特殊な処理をしてやらないといけないようです。以下を読むとガジェットドライバではサポートされているようですが、HID 用のドライバに対応が入っていないかも知れません。これ以上は、カーネルソースを読まないと難しそうで、今回は問題先送りにしたいと思います。ゴメンナサイ。