はじめに
我が家では、Raspberry PIでasteriskを動かし、VoIP アダプタ経由で固定電話を接続したり、SIPフォンを接続したりして、内線として利用しています。
しかし、「ごはんができたよ」とか「お風呂入って」と呼びかけたいだけの場合、受話器を取ってもらうことが手間です。そこで、電話をかけたらそのまま声をかけられるよう、ページング(放送)ができると良いと思いつきました。
Raspberry PIに、USBのSpeakerphoneを接続し、ページングできるようにしたので、その経験を投稿しようと思います。
ハードウェア構成
Raspberry Pi Model B Rev 2に、Plantronics P610を接続しています。Raspberry Pi Model B Rev 2は古いですが、今の所、正常動作しています。
写真のように壁に取り付けています。
ソフトウェア構成
インターネットの情報を検索したところ、以下のページにたどり着き、PJSIPに含まれるpjsuaがSIP clientとして使えそうなことが分かりました。
PJSIPのページは以下です。
課題への対処
PJSIPのデバイスID
pjsuaの起動オプションとして--capture-devと--playback-devがあり、オーディオデバイスのデバイスIDを指定する必要があります。このデバイスIDは、PJSIPが見つけたオーディオデバイスに対して順番に割り振る値のようで、Raspberry Piの再起動によって変わる可能性があります。
LinuxのオーディオサブシステムであるALSAでのデバイス名はarecord -L
やaplay -L
で調べられます。私のUSB speakerphoneの場合は、plughw:CARD=P610,DEV=0
です。
そこで、ドライバ名(常にALSA)とデバイス名からデバイスIDを取得するヘルパープログラムを作成しました。
誰かの役に立つかもしれないので、githubで公開しました。
以下のように使います。
$ pjsip-lookup ALSA plughw:CARD=P610,DEV=0
18
このコマンドの実行結果を--capture-devと--playback-devに渡すことで、実行時のデバイスIDが渡ります。
systemd経由のpjsuaの起動
pjsuaはコンソール上でインタラクティブに実行するSIPクライアントですが、ページングとして利用するためには自動起動する必要があります。systemdのサービスファイルを作成することで、自動起動することが最近(この10年ほど)の標準的な方法と思います。
ところが、systemd経由でpjsuaを起動したところ、メニューが表示されたあとに「Cannot switch back to console from file redirection」と表示されて終了してしまいました。PJSIPのソースコードを調査したところ、stdinに対するfgets()がNULLを返すと、このメッセージが表示されるようになっています。つまり、標準入力が閉じられると、このメッセージが出力されて、pjsuaが終了するようになっています。
回避策を探して試行錯誤したところ、tail -f /dev/null | pjsua ...
というように起動すれば、pjsuaは標準入力からの待ち状態になるので、動作し続けることが分かりました。
次のようなサービスファイルを作成しました。
[Unit]
Description=PJSUA SIP client
After=network.target
[Service]
ExecStart=bash -c "tail -f /dev/null | pjsua --log-level 1 --no-cli-console --local-port 5082 --capture-dev
`pjsip-lookup ALSA plughw:CARD=P610,DEV=0` --playback-dev `pjsip-lookup ALSA plughw:CARD=P610,DEV=0` --no-va
d --auto-answer 200 --config-file /usr/local/etc/sip-account.conf"
User=pjsip
Group=pjsip
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
/usr/local/etc/sip-account.conf には以下のようにSIPのアカウント情報を記載しておきます。
--id sip:user@localhost
--registrar sip:localhost:5060
--realm *
--username user
--password password
これらの設定ファイルもgithubでも公開しました。
まとめ
PJSIPに含まれるpjsuaと、インターネット上の情報でほぼページングは実現できましたが、いくつかの課題がありましたので、ヘルパープログラムを作成したり、些細な工夫をしたサービスファイルを作成しました。
これで大声で叫ばなくても、電話経由で、子供へ声をかけられそうです。