Asterisk+Radio
ここでいうRadioは無線機のことなのです。
目次
ニーズ
PBXに無線機、特に特定小電力を接続するニーズは結構あります。特に店舗運営をしているような場合、フロアは無線機を使っているケースが少なくありません。というわけで以前から統合したソリューションを出しているメーカー/ベンダーもあります。んじゃあAsteriskでもやってしまおうという計画。
(SIPを喋る無線基地局もあります)
注意
この方法を使うとアマチュア無線機とか業務無線機(特小とかデジ簡ではないやつ、免許局)も繋ぐことができますが、技術的なこと以外の問題点が多々あるので繋ぐ場合には自分で調べてください。業務上で無線と電話を繋いでいる例はもちろんあります。
しくみ
無線機とはいっても音声のやりとりなので基本的な接続は簡単で、Asteriskからオーディオを入出力してやれば無線と音声でやりとりできます。
とはいえ問題はありまして、PTT(Push-To-Talk)をどうするかです。通常、無線機は半二重で誰かが喋っている間は他は聞く動作になり、喋りたい時にはPTTを押して喋ります。なのでAsteriskからPTTを制御しなくてはなりません。
でまあ無線機のヘッドセットとか外部マイクにはPTT制御がついているため、これを何等かの方法で制御してやればAsteriskから無線機が制御できます。思いつく簡単な方法としては入手性の容易なUSBシリアルを使って、RTSとかDTRの制御線でPTTを制御する方法です。
ですがここで再度問題が。Asteriskを入れるようなサーバとかアプライアンスはオーディオインタフェースが付いていなかったりするわけで、その場合、USBオーディオ(安い)を増設して使う方法が考えられます。
まあ、これで良いといえば良いのですが、この方法だと回路とかケーブルを自作しないとできないのでちょいと面倒です。できれば何も自作したくないですよね。電子回路の知識とかまで要求されるのもアレですし。そして、この方法のもうひとつの問題はUSBケーブル2本挿しというあまり美しくない構成になることです。
DigiRig mobile
探せばある!
上記の構成を考えた場合、必要なコンポーネントとしてはUSBオーディオとUSBシリアルで、これを1台にまとめる(USBケーブル1本)場合にはUSBハブが必要になります。PTT制御回路を加えたものを基板を起こして作れば無線インタフェースのできあがりなので、作るかと思ったのですが作り始める前によく考えようというわけでして。
もともとRaspberry PiをPBX化するPIASTではリレー制御回路を用意したりしてましたが、Raspberry PiはオーディオINを持たない(OUTのみ)ので別途USBかSPIのオーディオインタフェースを付けてやる必要があり、難儀してしました。
んでまあ、こんなのは誰か作って売ってるだろうと探してみたらありました!どうやって探したかというと何のことはないアマチュア無線用です。最近のアマチュア無線機ではデジタルモード(FT8等)通信のためにオーディオIFと無線機制御が付いていて、USB接続できるようになっていますが、ちょっと昔のアマチュア無線機にはオーディオ入出力(要するにマイクとスピーカ)しか付いておらず、オーディオしかない無線機でデジタルモードを使うにはPCのサウンドカードやらを使います。なので昔のアマチュア無線機(リグ)をデジタル対応にする機器類が売られているので、よさげなのを探したらありました!
K0TX 局が開発/販売している DigiRig がそれで、OSHWとして公開されているので自分でも作ろうと思えば作れなくはありませんが、売られているものの出来がとても良く、買った方が早いでしょう。
https://digirig.net/
今回使っているのは RigiRig mobile というタイプです。
https://digirig.net/product/digirig-mobile/
USBインタフェースはUSB-Cコネクタで写真の左側、右側が無線機の接続用です。無線機接続用にAUDIOとSERIALがありますが、今回使用するのはAUDIOだけです。SERIALは無線機制御(CAT)のインタフェースに繋ぐ用です。
無線機と接続するには無線機のメーカ毎のケーブルが売られているので、これも併せて買えばOKです。今回はICOM用を入手して使用しています。
ICOMの特小機なら"ICOM HT Cable for Digirig Mobile"が使えます。ケンウッド機の場合には"Baofeng HT Digirig Cables Set"が使えると思いますが、試してはいません。八重洲(スタンダード:たぶん3.5Φ 4P方式)、アルインコ(たぶんアイコム互換)については調査していませんが、わかれば追記します。
基本的にDigiRig Mobileとケーブルを買えば接続できるので工作等は必要ありません。
注意:ICOMとケンウッドはコネクタの形状が似ていますが、PTTの制御方式が異なるのでケーブルは兼用できません。そもそもプラグ間のピッチが異なります。ケンウッドがなんで Baofeng 用なのかというとケンウッドのPTT方式をパクった中国製が多いからです。なんでケンウッド式を使ったのかは謎ですが。
ここで一回躓く
さて、シカケは揃いました。あとはAsteriskに接続して・・・と、やってみたのですが上手くないです。理由がどうにもこうにもわからないので諦めました。
当初の目論見ではAsteriskのConsoleデバイスで繋ごうと思ってたのですが、どうもオーディオがおかしくなりまともに音が出ないことが多くあります。たまに出ても数秒しか持たないなどさんざんでした。おそらくALSA+Pulseaudio+chan_consoleの組み合わせが悪いのか何なのかなのですが、もし解決方法を気付いた人がいたら教えてください。chan_console のテストをやっていて発見しました。USBオーディオの種類を変えてみても症状が治まらないので諦めました。
無線レピータを作る
というわけで、Asteriskで直収するのは諦めてSIPを喋る無線レピータをつくりましょう。話は簡単です。SIPのソフトフォンを入れたSBC等を用意して、それにDigiRigで無線機を繋ぎ、ヘッドセット等の代わりが無線機になっていればOKです。
でまあ、今回はとりあえずRaspberry Pi 3B+を使いました。ソフトフォンを動かすだけなら余ってるRaspberry Piとかでいけます。
参考:SIP,RTPのポートについて考慮すればAsteriskと同居させることはできます。なので、サーバ内でpjsuaを動かすのもアリです。
今回の接続は下図のようになります。
pjsua
ソフトフォンとしてPjSIPのUA、pjsuaを使います。そういえばpjproject自体のコンパイル等はVoIP-Infoで説明していない(AsteriskのPjSIPだけ)ことに今更気付きました。
Raspberry Piセットアップ
まずRaspberry Piをセットアップします。Raspberry Pi Imagerで最新のものを入れてください。ここではbookwormベースのRaspberry Pi OSを例にしています。インストールしたら最低限のセットアップ/アップデートを行っておきます。なお、ソフトフォンとして使うのでIPアドレスを固定する必要はありません。Asteriskに対してREGISTERして使います。
Raspberry Pi OSの場合デフォルトのインストールでほとんどのものは足りているはずなのですが、pjsuaでALSAを直接使いたいのでALSAのライブラリを入れておいてください。
apt-get install libasound2-dev
ちょっとだけRaspberry Piの設定を変更します。pjsuaでオーディオインタフェースを明示指定しようとしたのですが、うまくいかないのでRaspberry Pi上のオーディオをすべて無効化してUSBオーディオ(DigiRig)だけ使うようにします。(もしかしたら何かのライブラリ不足なのかも)
/boot/firmware/config.txt を編集します。以下の2か所を例のように修正し、BCMオーディオ(ヘッドフォン)とHDMIオーディオを無効にします。
# Enable audio (loads snd_bcm2835) #dtparam=audio=on dtparam=audio=off
# Enable DRM VC4 V3D driver #dtoverlay=vc4-kms-v3d dtoverlay=vc4-kms-v3d,noaudio max_framebuffers=2
以下のようにサウンドカードがひとつだけになれば正解です
# cat /proc/asound/cards 0 [Device ]: USB-Audio - USB Audio Device C-Media Electronics Inc. USB Audio Device at usb-3f980000.usb-1.3.2, full speed
PjSIPコンパイル
PjSIP自体はPjProjectのページからダウンロードして展開します。
https://www.pjsip.org/
展開するとバージョンに応じたディレクトリ(pjproject-2.14.1)ができるので、その下で作業します。
単純に
./configure make dep make
するとコンパイルできます。
コンパイルが完了すると pjproject-2.14.1/pjsip-apps/bin の下に pjsua-aarch64-unknown-linux-gnu というプログラムができあがっているので、これを適当なディレクトリに pjsua という名前でコピーしておきます。
pjsua設定ファイル
以下のような内容でAsteriskに対してREGISTERするソフトフォンとして動作させます。無線機と接続するのでオートアンサモードにしておきます。
# PJSUA config --local-port 5081 --no-vad --id sip:phone10@192.168.254.234 --registrar sip:192.168.254.234:5070 --realm * --username phone10 --password password --auto-answer 200
auto-answerの指定値は応答コード(200 OK)です。
設定ファイルを使用しての起動は以下のようにします。
./pjsua --config-file pjsua.conf
SIPのトレースが出てウルサイのを消したい場合には
# PJSUA config --local-port 5081 --log-level 0 --no-vad --id sip:phone10@192.168.254.234 --registrar sip:192.168.254.234:5070 --realm * --username phone10 --password password --auto-answer 200
--log-level で出力される情報を変更します。
テスト
ここまでで動作を確認できます。Asteriskに対するREGISTERが確認できれば、エンドポイント(ここの例ではphone10)に対してダイヤルすれば無線機と繋がります。Asteriskから
exten => 1234,1,Dial(PJSIP/phone10)
を行えばpjsuaは自動で応答し繋がりますので、無線で何か喋ると電話側で聞こえるはずです。音量の調整は無線機のボリュームと、pjsua側のalsamixerでよしなに調整してください。電話機から喋りたい場合にはpjsuaに繋いだ無線機のPTTを手で押します。このPTTをソフト的に制御するのが次の課題です。
PTT制御
音声の入出力ができるようになったので、後はPTTを制御するだけです。前述のようにDigiRigはUSBシリアルも内蔵しており、RTSでPTTが制御できるようになっています。RTSを制御すればいいので簡単ですねと言いたいところですが、デバイスに対するIOCTLを発行しないとなのでちょいと面倒です。なので、この部分は書いておきました。
Asteriskサンプル設定ファイルと同じところにpttctrlというプログラムを置いておきます。
https://github.com/takao-t/asterisk-conf/tree/main/pttctrl
これをコンパイルするには
gcc pttctl pttctl.c -lrt
で行います。TTYデバイスが /dev/ttyUSB0 ではない場合には書き換えてからコンパイルしてください。
このプログラム自体はデーモン(常駐)化して使用します。やり方は後で説明しますが、とりあえずフォアグラウンドで試してみてください。
PTTを制御するにはパイプ(FIFO)に対して書き込みを行います。/tmp/PTTCTL という名前でパイプをつくりますので、これに対して書き込んでください。使えるコマンドはON,OFF,ALTでPTTをオンにする(押した状態)なら
echo "ON" > /tmp/PTTCTL
オフにする(離す)なら
echo "OFF" > /tmp/PTTCTL
を実行します。ですがこれだけだと押したかどうかを判断するのが面倒なので、状態反転も持たせてあります。
echo "ALT" > /tmp/PTTCTL
で現在の状態を反転します。オフならオンに、オンならオフになります。
なお、特小の場合には連続送信は3分未満となっている(無線機が勝手に切る)ので、このプログラムでは送信状態になってから170秒でオフにするようにしています。
PTT制御をネットワーク化する
今回、別な筐体にpjsuaを入れたので制御が少し面倒になります。AsteriskからPTTを制御するにはpjsuaが動作しているマシン(Raspberry Pi)に対してPTTの制御を投げる必要があります。
処理を簡単にするため、汎用のTCP通信ツールを使ってしまいましょう。くれぐれもこのままインターネット上に公開しないように。セキュリティが必要な場合にはファイアウォールするか別な手段を使ってください。
ここではnetrwを使います。netcatでもかまいませんが。
https://mamuti.net/netrw/index.en.html
Debian系にはパッケージが用意されているのでインストールします。
apt-get install netrw
Raspberry Pi側はネットからコマンドを受信して処理するので netread を使います。こんな感じ
netread -o /tmp/PTTCRL 5091
ネットから受信した内容をパイプに書き込むので、送信すべきデータはパイプに書き込むものと同じになるのでとても単純です。ただし、netreadは1行読み込むと終了するので、以下のようなシェルを作ります。
#!/bin/sh while : do netread -o /tmp/PTTCTL 5091 done
簡単ですね。
まとめる
ここまでの作業をまとめて無線レピータをつくります。Raspberry Pi(3b+)の場合ですが
- オンボードのオーディオデバイスを全て無効化しRigiRigだけ使うようにする
- pjsuaをコンパイルし、/usr/local/bin/pjsua とする
- pjsuaの設定ファイルを /usr/local/etc/pjsua.conf とする
- PTT制御プログラムをコンパイルし /usr/loca/bin/pttctl とする
- PTTをネットワークから制御するため netrwを入れ、シェルスクリプトを /usr/local/etc/netptt.sh とする
以上を行い、/etc/rc.local に以下を書いて再起動しても無線レピータとして動くようにします。
#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi nohup /usr/local/bin/pttctl > /dev/null 2>&1 & nohup /usr/local/etc/netptt.sh > /dev/null 2>&1 & screen -dmS pjsua /usr/local/bin/pjsua --config-file /usr/local/etc/pjsua.conf & exit 0
pjsuaはttyから切り離されたがらないのでscreenでバックグラウンド起動させます。
これで無線レピータ、要するにSIPを喋る無線機アダプタのできあがりです。