NanoPi NEOの青LEDを消す

目が痛い
© いらすとや

100%自分のためのメモ

既に書いたがNanoPi NEOの青LEDがとんでもなく眩しい。近くにあると目が痛くなるくらい。
armbianの公式サイトで配布されているレガシーカーネル(3.4系)のはapt-getでパッケージの更新を行って再起動すると青LEDは点かなくなるので良いのだが、Mainline系ではシステムを起動してログイン可能になってからずっと青LEDがピッカンピッカンというかギランギラン。

NanoPi NEO Blue LED
写真では伝わらないだろうけど眩しいのはこいつ

緑LEDはどうでもいいのでこの青LEDが点滅するのを停めたい。

ファイルシステムのツリーで/sys/classを覗いてみるとledsというのがある。おそらくこれ。
その下に nanopi:blue:status と nanopi:green:pwr というそのままズバリな名前のディレクトリがある。
# cat trigger
none kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock usbport usb-gadget usb-host mmc0 mmc1 mmc2 disk-activity ide-disk mtd nand-disk [heartbeat] cpu0 cpu1 cpu2 cpu3 default-on panic 1c30000.ethernet:01:100Mbps 1c30000.ethernet:01:10Mbps

現在は heartbeat に角括弧が付いていて none には付いていない。
つまりheartbeatモードなので青LEDがペッカンペッカンしてる。

echo none > /sys/class/leds/nanopi:blue:status/trigger

このtriggerにnoneを送信。
青LEDのペッカンペッカンが停まった。

# cat /sys/class/leds/nanopi:blue:status/trigger
[none] kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock usbport usb-gadget usb-host mmc0 mmc1 mmc2 disk-activity ide-disk mtd nand-disk heartbeat cpu0 cpu1 cpu2 cpu3 default-on panic 1c30000.ethernet:01:100Mbps 1c30000.ethernet:01:10Mbps

今度は none に角括弧が付いていて heartbeat には付いていない。

echo heartbeat > /sys/class/leds/nanopi:blue:status/trigger

triggerにheartbeatを送信してみた。
青LEDのペッカンペッカンが再開した。

/sys/class/leds/nanopi:blue:status/trigger に none を送りつければLEDの点滅が停まることが判ったのでシステム起動時にLED点滅を停めるようにしたいと思う。ただし、システムが起動してログイン可能になったことを知りたいので少しだけ(5秒以上)は点滅させておく。

# vim /etc/rc.local (exit 0 の前に2行追加)
/bin/sleep 5s
echo none > /sys/class/leds/nanopi:blue:status/trigger

NanoPi NEOとGPSモジュールでNTPサーバ 高精度PPS編

NanoPi NEOとarmbianの組み合わせでPPSを使ったNTPサーバを作ろうとしたのに、どうやってもGPIOをPPSデバイスとして認識させることができなくて困っていた。他の機種用のソースを参考に自前でパッチを作成してビルドするも失敗。(ヘッポコなので仕方ない)
と、諦めかけてたところ、ソースツリーを更新したときに表示されたのが patch/kernel/sun8i-dev/add-h3-overlays.patch というパッチ。SoCがH3なSBC用と思われるOverlays周りのパッチ。これは期待できるかもとソースを見た。

patch/kernel/sun8i-dev/add-h3-overlays.patch (説明の一部)

++### pps-gpio
++
++Activates pulse-per-second GPIO client
++
++Parameters:
++
++param_pps_pin (pin)
++	Pin PPS source is connected to
++	Optional
++	Default: PD14
++

キタ――♪ o(゚∀゚o) (o゚∀゚o) (o゚∀゚)o キタ――♪
自分でできなくて実現したかったズバリが入ってる。
更新したソースでフルビルドする。

ビルド時のカーネルオプション選択 (のPPS関連主要部)

General setup > Timers subsystem > Timer tick handling
	(X) Periodic timer ticks (Constant ratem no dynticks)

Device Drivers > PPS Support
	[*] PPS kernel comsumer support (NEW)
	 PPS client using GPIO

Device Drivers > PTP Clock Support
	< *> PTP clock support

その他サウンド関係は削除

ビルドしたイメージファイルをmicroSDカードに書き込んで起動後、Overlay周りの実ファイルを見てみる。

$ cd /boot/dtb/overlay
# dtc -I dtb -O dts -o sun8i-h3-pps-gpio.dts sun8i-h3-pps-gpio.dtbo
$ cat sun8i-h3-pps-gpio.dts
/dts-v1/;

/ {
        compatible = "allwinner,sun8i-h3";

        fragment@0 {
                target = <0xffffffff>;

                __overlay__ {

                        pps_pins {
                                pins = "PD14";
                                function = "gpio_in";
                                linux,phandle = <0x1>;
                                phandle = <0x1>;
                        };
                };
        };

後略

pps-gpioのピンの初期値はPD14 (NanoPi NEOには無い?)になっているみたい。この値が要変更。

/boot/dtb/overlay/sun8i-h3-fixup.scr

前略
if test -n "${param_pps_pin}"; then
	setenv tmp_bank "${param_pps_pin}"
	setenv tmp_pin "${param_pps_pin}"
	run decompose_pin
	fdt set /soc/pinctrl@01c20800/pps_pins pins "${param_pps_pin}"
	fdt get value tmp_phandle /soc/pinctrl@01c20800 phandle
	fdt set /pps@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>"
	env delete tmp_pin tmp_bank tmp_phandle
fi
後略

パッチの説明書きどおり、param_pps_pinで値を指定すれば良さげ。

イケそうなので、Overlay設定を行う。

NanoPi NEOピン配置
©FriendlyARM.

GPIO #18 pinを使う場合は上の図の一番右列の下から4番めなので"PG9"となる。
設定に書く時はpg9やPG09はダメ、PG9と書く必要があるので注意。

# vim /boot/armbianEnv.txt

overlays=pps-gpio
param_pps_pin=PG9

今回はNTP甩なのでPPSだけでなくNMEAも使いたい。で、前回にも書いたがMainline系ではUART1が標準で無効になっているのでoverlayで有効にしてやる必要がある。UART1の有効化ではパラメーター(param_hoge)は不要。

で、本来は overlays=sun8i-h3-uart1 と書く。(前回の内容)
しかし、 /boot/armbianEnv.txt に overlay_prefix=sun8i-h3 が入っているのでプリフィックスの sun8i-h3-は要らない。

overlays=uart1

UART1の有効は以上のように書く。
ただし、pps-gpioも同じ行に書くので半角スペースを挟んで並べる。

# vim /boot/armbianEnv.txt

verbosity=1
console=tty0
overlay_prefix=sun8i-h3
rootdev=UUID=b5649d7f-59d4-4b79-998e-48ebdaecbc45
rootfstype=ext4
overlays=uart1 pps-gpio
param_pps_pin=PG9

こうなった。
再起動を行う。

# dmesg | grep pps
[    3.245898] pps_core: LinuxPPS API ver. 1 registered
[    3.245906] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti 
[    8.015553] pps pps0: new PPS source pps@0.-1
[    8.015650] pps pps0: Registered IRQ 81 as PPS source

下2行でpps0が登録されていることがわかる。
次にデバイスファイルが生えたか確認する。

# ls -l /dev | grep pps
crw------- 1 root root    251,   0 Mar 24 22:48 pps0

/dev/pps0も無事生えてOK.

ネットのRaspberryPiのpps-gpio関連の記事を見ると/etc/modulesに追記するだの/etc/modprobe.dか/etc/modules-load.dにファイルを作成とか/boot/config.txtに行追加とかdtoverlayだとかいろいろ出てくるが、NanoPi NEO + armbian Mainline系では全然当てはまらないっぽい。

# apt-get install pps-tools
# ppstest /dev/pps0
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1490404439.001447609, sequence: 41083 - clear  0.000000000, sequence: 0
source 0 - assert 1490404440.001431655, sequence: 41084 - clear  0.000000000, sequence: 0
source 0 - assert 1490404441.001448742, sequence: 41085 - clear  0.000000000, sequence: 0
source 0 - assert 1490404442.001446747, sequence: 41086 - clear  0.000000000, sequence: 0
source 0 - assert 1490404443.001448001, sequence: 41087 - clear  0.000000000, sequence: 0
source 0 - assert 1490404444.001426256, sequence: 41088 - clear  0.000000000, sequence: 0

pps-toolsをインストールして/dev/pps0をデバイスに指定して実行。
1秒ごとに1行ずつ表示されて問題ないことを確認。[Ctrl]+[C]で終了。

NTPのビルド・インストール

前回は「なんちゃってPPS」だったのでNTPのビルドは不要だったが、今回は本物のPPSなのでそれに対応したNTPをビルド・インストールする。

# apt-get install libcap-dev
# /etc/init.d/ntp stop
# apt-get remove ntp
$ cd ~
$ wget http://archive.ntp.org/ntp4/ntp-4.2.8p8.tar.gz
$ tar zxvf ntp-4.2.8p8.tar.gz
$ cd ntp-4.2.8p8
$ ./configure --enable-linuxcaps --enable-ATOM --enable-NMEA --enable-ipv6
$ make -j4
# make install

# ln -s /usr/local/sbin/ntpd /usr/sbin/ntpd
# ln -s /usr/local/bin/ntpdc /usr/bin/ntpdc      #必要なら
# ln -s /usr/local/bin/ntpq /usr/bin/ntpq          #必要なら
# ln -s /usr/local/bin/ntpsweep /usr/bin/ntpsweep  #必要なら
# ln -s /usr/local/bin/ntptrace /usr/bin/ntptrace  #必要なら

また、前回はgpsd経由だったが、今回はgpsdを使わない。

NMEAの設定追加

# stty -F /dev/ttyS1 9600  ←シリアル速度をGPSモジュールに合わせてやる
# cat /dev/ttyS1

/dev/ttyS1だとNTPが読めないので以下2行。

# chmod 0666 /dev/ttyS1
# ln -s /dev/ttyS1 /dev/gps0

/etc/ntp.confに以下2行追記。mode 16はGPSモジュールのシリアル最高速度が9600bpsの場合に指定。19200bpsならmode 32、38400bpsならmode 48、57600bpsならmode 64を指定。

server 127.127.20.0 mode 16 minpoll 4 maxpoll 4 prefer
fudge  127.127.20.0 refid NMEA

NTPを再起動して確認する。

# /etc/init.d/ntp restart
少し待ってから
# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
-GPS_NMEA(1)     .NMEA.           0 l    6   16   17    0.000  -187.84 102.432
*ntp1.jst.mfeed. 133.243.236.17   2 u   53   64    1   15.076   -2.403   0.008
+ntp2.jst.mfeed. 133.243.236.17   2 u   53   64    1   14.021   -2.540   0.008
+ntp3.jst.mfeed. 133.243.236.17   2 u   54   64    1   14.962   -1.863   0.008

NMEAの行のpoll,reach,offsetが0以外で機能していることを確認。

PPSの設定追加

PPSについてはNTPは/dev/pps0から取得してくれる筈だがパーミッションがおそらくNTPで読めないものなので変更。

# chmod 0666 /dev/pps0

/etc/ntp.confに以下2行追記。

server 127.127.22.0 minpoll 4 maxpoll 4
fudge  127.127.22.0 flag3 1 refid PPS

設定が済んだらNTPを再起動して確認。

# /etc/init.d/ntp restart
5分以上待ってから
# ntptime
ntp_gettime() returns code 0 (OK)
  time dc80dcac.24700044  Sat, Mar 25 2017 21:10:20.142, (.142334118),
  maximum error 99917 us, estimated error 138 us, TAI offset 0
ntp_adjtime() returns code 0 (OK)
  modes 0x0 (),
  offset 0.000 us, frequency -32.493 ppm, interval 128 s,
  maximum error 99917 us, estimated error 138 us,
  status 0x2107 (PLL,PPSFREQ,PPSTIME,PPSSIGNAL,NANO),
  time constant 6, precision 0.001 us, tolerance 500 ppm,
  pps frequency -32.875 ppm, stability 0.650 ppm, jitter 31.055 us,
  intervals 20, jitter exceeded 2, stability exceeded 0, errors 0.

PPSが機能していることが確認できたらOK.上の水色のstatus行を注視。PPSは完全に機能してntpq -pで確認できる状態になるまで5分程度はかかる。

システムを再起動すると/dev内のgps0が無くなり、pps0やttyS1のパーミッションが元に戻ってしまうのでシステム起動後に自動的に設定を行うようにする。
# vim /etc/udev/rules.d/10-gps.rules (新規ファイル作成)

KERNEL=="ttyS1",SYMLINK+="gps0",MODE="0666"
KERNEL=="pps0",MODE="0666"

ntpd起動のタイミングが悪いのかNMEAとPPSが読めないようなので /etc/rc.local ファイルの最後のexit 0の直前に3行挿入。(NTP再起動という手抜き)

/bin/systemctl stop ntp.service
/bin/stty -F /dev/ttyS1 9600
/bin/systemctl start ntp.service

システムを再起動し、ntpq -pででNMEAとPPSに値が入ることを確認。(PPSは5分以上待つ)

出来たと思ったら・・

# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
xGPS_NMEA(0)     .NMEA.           0 l    9   16  377    0.000  -181.01  12.761
xPPS(0)          .PPS.            0 l    9   16  377    0.000    0.001   0.004
*ntp2.jst.mfeed. 133.243.236.17   2 u   12   64   17   13.774   -0.318   1.808
+ntp3.jst.mfeed. 133.243.236.17   2 u   24   64    7   14.750   -0.306   2.135
+ntp1.jst.mfeed. 133.243.236.17   2 u   18   64   17   14.810   -0.029   1.791

ぱっと見では良さ気なんだけどNMEAとPPSに x が付いてしまう。

# ntpq -c assoc
ind assid status  conf reach auth condition  last_event cnt
===========================================================
  1 55298  9124   yes   yes  none falsetick   reachable  2
  2 55299  9124   yes   yes  none falsetick   reachable  2
  3 55300  941a   yes   yes  none candidate    sys_peer  1
  4 55301  9424   yes   yes  none candidate   reachable  2
  5 55302  961a   yes   yes  none  sys.peer    sys_peer  1

上と同じこと。インデックス1と2がNMEAとPPSだが、コンディションがfalsetick (上の x の意味)になっている。
で、かなり悩んだが、最初に戻って調べていたら、GPIOから受け取っているPPS信号がNTPが欲しがってるのと逆なんじゃないかと思い立つ。

パルスの立ち上がりと立ち下がり

$ cat /boot/dtb/overlay/README.sun8i-h3-overlays
前略
param_pps_falling_edge (bool)
	Assert by falling edge
	Optional
	Default: 0
	When set (to 1), assert is indicated by a falling edge
		(instead of by a rising edge)
後略

rising edgeとfalling edgeのどちらを使うかだが、標準が0だから1に変更。

# echo "param_pps_falling_edge=1" >> /boot/armbianEnv.txt

ついでにNanoPi自身の時刻も参照するようにしておく。

# echo "server 127.127.1.0" >> /etc/ntp.conf
# echo "fudge 127.127.1.0 stratum 10" >> /etc/ntp.conf

システムを再起動。

$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*GPS_NMEA(0)     .NMEA.           0 l    4   16  377    0.000  -75.223  16.482
oPPS(0)          .PPS.            0 l    2   16  377    0.000    0.001   0.004
 LOCAL(0)        .LOCL.          10 l  436   64  100    0.000    0.000   0.002
+ntp1.jst.mfeed. 133.243.236.17   2 u   35   64  177   14.852    3.078  67.476
+ntp2.jst.mfeed. 133.243.236.17   2 u   28   64  177   14.161  102.508  72.278
-ntp3.jst.mfeed. 133.243.236.17   2 u   45   64  177   14.415  101.434  84.172

起動後暫くはxが付いた状態だが、数分後には上のようになる。
なお、起動後に"ntpdate -u 他所のNTPサーバ"と"hwclock -w"でRTC timeをしっかり修正しておかないとダメっぽい。(ここ超重要)

armbianとH3なSBCを使ったGPS(PPS)使用のNTPサーバの情報が全然無いので正直苦労した。この件に限っては?RaspberryPiの情報が全然参考にならないんだけどNanoPi,OrangePi等の他のユーザーさんはどうしてるんだろ?

この記事は後で追加と修正がいっぱい入る予感。

NanoPi NEOをSIP電話機にする 前編?

NanoPi NEOをSIP電話機にする

NanoPiでなくてもこの手のワンボードコンピュータでやりたいことの一つが小型SIPクライアント 。

用意したもの。
上の写真にあるUSB接続タイプのハンドセット。
しかし、このハンドセット実はSkypeなどのネット電話のハンドセットとしてWindows用として数百円で販売されていたものだがWindows PCに繋いでも全く使えなかった代物。USB接続を行うとデバイスが接続されたことは認識されるものの、液晶画面表示無し、全ボタン反応無しマイク・スピーカー反応無し、つまりウンともスンとも言わない文鎮。10〜5年ほど前に購入してから1度も使えていないのでNanoPiに繋いで動くか不明。

この記事のNanoPi NEOで使用しているOSはLinux nanopineo 4.10.3-sun8i #2 SMP Tue Mar 21 17:30:21 JST 2017 armv7l GNU/Linux、この記事作成前日の3月21時点で最新のソースでフルビルドしたMainline系のもの。armbianのサイトで配布されているのとはカーネルモジュールの選択が少し違うかもしれない。

USBハンドセットをOS起動済みのNanoPi NEOに接続する。(上の写真の状態)

以下、例によってコマンド実行は行頭が#ならsudo付きかスーバーユーザーで、$なら一般ユーザーでという意味。

$ dmesg
[61363.162468] usbcore: registered new interface driver snd-usb-audio
[61665.443319] usb 2-1: USB disconnect, device number 2
[61901.092898] usb 2-1: new full-speed USB device number 3 using ohci-platform
[61901.595047] usb 2-1: New USB device found, idVendor=04b4, idProduct=0307
[61901.595082] usb 2-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[61901.715947] hid-generic 0003:04B4:0307.0002: hiddev0,hidraw0: USB HID v1.10 Device [HID 04b4:0307] on usb-1c1d400.usb-1/input3

OS起動後にハンドセットを接続したのでdmesgで最後の部分を確認。USBに何か新しいデバイスを認識している。HIDということなので "Raw Access to USB and Bluetooth Human Interface Devices" ということになる。良さ気でやっかいなタイプのデバイスだ。dmesgのメッセージを信用するなら /dev/hiddev0か/dev/hidraw0でアクセスできる筈。/devを見るとhiddev0は居なくてhidraw0が居た。

$ cat /dev/hidraw0

この状態でUSBハンドセットのボタンをアレコレ押してみると押したタイミングでターミナルに意味不明の文字がババッと出てくればOK.
Ctrl+Cで終了。

音声周りを確認する。

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 1: U0x4b40x307 [USB Device 0x4b4:0x307], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: U0x4b40x307 [USB Device 0x4b4:0x307], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

一応使えるっぽい気な様子。

PJSIP

SIPのソフトウエアは取り敢えずPJSIPを使用する。PJSIPのarmbian用パッケージは提供されていないようなので自分でビルドする。armbianで何か大きめなアプリをビルドする場合はpkg-configやlibtoolは最低限入れておく。PJSIPならlibpjproject-devを追加すると結構揃う筈。その他サウンド関係のライブラリを必要なだけ追加。libsndobj-dev, libgsm1-dev, libsamplerate0-dev, libspeex-dev, libesd0-dev, libsndfile1-devこのあたりを入れればいける筈。(むしろ要らないのがあるかも)
NanoPiで何かやろうと思ったらラズパイかオレンジパイでやっている人の記事をググると参考になる筈。ただし、PJSIPのビルドに必要なパッケージとしてlibcelt-devを挙げているページはNanoPiとarmbianの組み合わせではあまり参考にならないかも。

# apt-get install subversion
$ svn checkout http://svn.pjsip.org/repos/pjproject/trunk
$ cd trunk 
$ ./configure --help  ←指定可能なオプションを確認しておく
$ ./configure --disable-video --disable-libwebrtc ←NanoPi NEOでは要らんでしょ
$ ./make dep
$ ./make
$ cd ~/trunk/pjsip-apps/bin ←実行可能なファイルはここにある

試すだけなのでmake installはしていない。

先ずは出来たPJSIPのテストツールを実行。(実行ファイル名は環境による)

$ ./pjsystest-armv7l-unknown-linux-gnueabihf
中略
M E N U :
---------
0: Tests
  00: Run test wizard
  01: Device Test
  02: Play Tone
  03: Play WAV File1
  04: Play WAV File2
  05: Record Audio
  06: Latency Test
  07: AEC/AES Test

  09: Exit
1: Options
  10: View Devices
  11: View Settings

Enter the menu number: 

メニューの2桁の数字を入力してそれぞれテストを実行。
メインメニューの02を実行してハンドセットの耳に当てる方から「プーー プーー」という音が聞こえないとちょっと絶望。 03を実行してハンドセットの耳に当てる方から男性の声でthank you for・・・というメッセージが聞こえてこないとちょっと絶望。
いずれのテストもメニューで選択後に1を押してテスト開始1で終了、OKなら1を押すというような流れ。NanoPiでやると05のRecord Audioで"Master/sound Underflow, buf_cnt=1, will generate 1 frame"が大量に出る。つまりマイクで音を拾う方は問題アリ。実際マイクで拾った音は盛大なビーガー音とノイズが入り、喋った声は「ワレワレハ ウチュウジンダ」みたいな感じ。

PJSIPの通話アプリを動かしてみる。

./pjsua-armv7l-unknown-linux-gnueabihf --help  ←指定可能なオプションを表示してみる
表示省略

./pjsua-armv7l-unknown-linux-gnueabihf         ←オプション無しで実行してみる

中略

>>>>
Account list:
  [ 0] : does not register
       Online status: Online
 *[ 1] : does not register
       Online status: Online
Buddy list:
 -none-

+=============================================================================+
|       Call Commands:         |   Buddy, IM & Presence:  |     Account:      |
|                              |                          |                   |
|  m  Make new call            | +b  Add new buddy       .| +a  Add new accnt |
|  M  Make multiple calls      | -b  Delete buddy         | -a  Delete accnt. |
|  a  Answer call              |  i  Send IM              | !a  Modify accnt. |
|  h  Hangup call  (ha=all)    |  s  Subscribe presence   | rr  (Re-)register |
|  H  Hold call                |  u  Unsubscribe presence | ru  Unregister    |
|  v  re-inVite (release hold) |  t  ToGgle Online status |  >  Cycle next ac.|
|  U  send UPDATE              |  T  Set online status    |  < Cycle prev ac.|
| ],[ Select next/prev call    +--------------------------+-------------------+
|  x  Xfer call                |      Media Commands:     |  Status & Config: |
|  X  Xfer with Replaces       |                          |                   |
|  #  Send RFC 2833 DTMF       | cl  List ports           |  d  Dump status   |
|  *  Send DTMF with INFO      | cc  Connect port         | dd  Dump detailed |
| dq  Dump curr. call quality  | cd  Disconnect port      | dc  Dump config   |
|                              |  V  Adjust audio Volume  |  f  Save config   |
|  S  Send arbitrary REQUEST   | Cp  Codec priorities     |                   |
+-----------------------------------------------------------------------------+
|  q  QUIT   L  ReLoad   sleep MS   echo [0|1|txt]     n: detect NAT type     |
+=============================================================================+
You have 0 active call
>>> 

メニューが表示されるので取り敢えずSIPサーバに接続してみる。アカウント関係は右上のAccountにある。+a [Enter]で自分の(持っている) SIPアカウントを指定してSIPサーバに接続する。
以下の実行例、SIPサーバがsip.example.comとする。NanoPiで使用しているIPアドレスは192.168.0.64とする。自分のSIPアカウントが4321でパスワードがsecretpasswordとする。情報が足りないところはテキトーで良い。

>>> +a  
Your SIP URL: (empty to cancel): sip:4321@192.168.0.64
URL of the registrar: (empty to cancel): sip:asterisk@sip.example.com
Auth Realm: (empty to cancel): *
Auth Username: (empty to cancel): 4321
Auth Password: (empty to cancel): secretpassword

URLの入力は「sip:」で始まること。なお、れこ上の例では自分のSIP URLをアカウント@IPアドレスにしているが@の右側は正直なんでも良いっぽい。

SIPサーバにレジストが成功すると先ほどのメニュー表示の直前に表示されるアカウントリストに以下のように表示される。
Account list:
 *[ 0] sip:4321@192.168.0.64: 200/OK (expires=61)
       Online status: Online
Buddy list:
 -none-

200/OKが出ること。expiresの値は無視

PJSIPの設定

上で入力したアカウント情報だが、毎回このようにするのは面倒なので設定ファイルに入れてしまいたい。
このメニューの右下にSave configがあって設定ファイルを作成できる。メニューでは特に設定らしいことはできないが、引数付きでpjsua-armv7l-unknown-linux-gnueabihfを実行した場合はその値が入った状態で保存されるみたい。
fを押して設定ファイル名(任意)を指定。

設定ファイルはテキストファイルなのでテキストエディタで開く。

#
# Logging options:
#
--log-level 5
--app-log-level 4

#
# Network settings:
#
--local-port 5060

#
# Media settings:
#
--snd-auto-close 1
#using default --clock-rate 16000
#using default --quality 8
#using default --ec-tail 200
#using default --ilbc-mode 30
--rtp-port 4000

#
# User agent:
#
--max-calls 4

#
# Buddies:
#

#
# SIP extensions:
#
--use-timer 1

上は引数無しでpjsua-armv7l-unknown-linux-gnueabihfを実行してそのまま設定ファイルにしたもの。要するにこれをベースにすれば良い。で、見ればわかるが、pjsua-armv7l-unknown-linux-gnueabihfの引数を1行に1つ指定してるだけ。
SIPアカウントを追加してみる。

--id=sip:4321@192.168.0.64
--registrar=sip:asrterisk@sip.example.com
--realm=*
--username=4321
--password=secretpassword

次回からは --config-file=保存したファイル名 を指定して起動する。

$ ./pjsua-armv7l-unknown-linux-gnueabihf --config-file=test.cfg

上はtest.cfgという設定ファイルを指定した場合

発信

一応使えるようになった筈なので通話してみる。

発信はメニューの左上に表示されている「m Make new call」がそれ。
[m][Enter]を押すと発信メニューが表示される。

>>> m
(You currently have 0 calls)
Buddy list:
 -none-

Choices:
   0         For current dialog.
  -1         All 0 buddies in buddy list
  [1 - 0]    Select from buddy list
  URL        An URL
      Empty input (or 'q') to cancel
Make call:

buddyとかは登録していないので普通に通話先を指定するので通話先のURLを入力する。
たとえば内線番号2000番にかけたいと思った時は、2000を指定したのではダメ。
自分のSIP URLがsip:4321@192.168.0.64でSIPサーバのURLがhoge@sip.example.comであれば、sip:2000@sip.example.comであることが想像つくと思う。
つまり直接sip:2000@sip.example.com[Enter]と入力する。"URL"は不要。

すぐに呼び出しが始まり発信先がオフフック(応答)すれば通話できる。

毎回sip:hogehogeを入力するのは面倒なのでbuddyに登録する。
buddyはメニューの中央上段。buddy登録は+b[Enter]

>>> +b
Enter buddy's URI: (empty to cancel): sip:2000@sip.example.com
New buddy 'sip:2000@sip.example.com' added at index 1
>>>

sip:2000@sip.example.com がbuddy番号1に登録された。
メニューを表示したときにメニュー直前のbuddyリストにも表示されている筈。
次からはメニューから発信の[m][enter]の後に[1][Enter]で内線番号2000に発信できる。

ただし、注意としてメニューで登録したBuddyは設定ファイルを出力しても入っていない(なんじゃそりゃ)。PJSIP起動の度にBuddyを登録するのは馬鹿らしいので設定ファイルをエディタで編集して登録してやる。

着信

次は着信。とりあえず発信してもらう。上の例だと内線4321にかけてもらう。
特に操作しなくてもハンドセットが鳴動する筈。
着信はメニューの左上の方にある「a Answer call」

>>> a
Answer with code (100-699) (empty to cancel): 200
>>>

つまり[a][Enter]のあとに200を入力して[Enter]、電話に出たいだけなのに面倒。

これで通話できる。相手から切断したなら特にすることはない。自分の側から切断したいときはメニューの「h Hangup call」、つまり[h][Enter]。

ステータスの変更

着信できる状態を変更するならメニュー中央の「T Set online status」または「t ToGgle Online status」。

>>> T

Choices:
  1  Available
  2  Busy
  3  On the phone
  4  Idle
  5  Away
  6  Be right back
  7  Offline
Select status (empty to cancel):

普通は着信可のAvailableの1か着信不可のOfflineの7を選択する程度。それを簡易に行うために[t][Enter]で実行のたびにOnline = AvailableとOfflineを切り替える。なお、たとえばBusyのときに[t][Enter]を押しても効かない筈。

とりあえず、今のところNanoPi NEOでは通話の音声はビー、ブギャー、ピロロロが中心で短波ラジオの電波がひどい状態のような殆ど何を言ってるのかわからない声「のようなもの」が入る程度。何かが根本的におかしいのでそれを直さないと使いものにならない。
あと、CLIの操作だとPC必須(しかも操作がタルい)なのでNanoPiを電話機にする意味がない。できたらハンドセットのボタンで操作できるようにしたい。

2017年3月24日追記:
NanoPi NEOの処理能力だとエコーキャンセラーが有効だとマイクで集音した音を処理しきれずにビーブギャーになるっぽい。--ec-tail=0を指定してやれば普通の声になることがわかった。ただしエコーに注意。