AsteriskのチャンネルドライバをPJSIPにした

いつものようにFreeBSDのportsでAsteriskをver.13.16.0に更新したら突然動かなくなった。起動させてもログを出さないで一瞬で終了するので原因は不明。いろいろ試したらSIPチャンネルドライバのchan_sip.soを読み込むところで突然死しているみたい。(他に保留音などのmp3形式のファイルの再生などの機能が全く機能しないことも判明。slnとかは大丈夫)
何か変だが、Asteriskの13.16.0が悪いのかportsが悪いのかうちの環境固有の問題なのか・・・たぶん最後だろうけど

SIPが動かないとうちではIP電話のPBXとしてどうしようもない。(SIP用のCISCO 7961Gが居るので)
そこで標準のSIPチャンネルドライバではなくPJSIPチャンネルドライバを使用することに。これも動かないとかなり困ることに・・

とりあえずAsteriskをPJSIPでFUSION IP-Phone SMARTに接続する設定を書いた。(ただし以下は記事用の簡易版)

/usr/local/etc/asterisk/pjsip.conf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
[transport-udp4]
type = transport
protocol = udp
bind = 0.0.0.0

;[transport-tcp4]
;type = transport
;protocol = tcp
;bind = 0.0.0.0

;[transport-udp6]
;type=transport
;protocol=udp
;bind=::
  
;[transport-tcp6]
;type=transport
;protocol=tcp
;bind=::

;---
[fusion]
type=registration
transport=transport-udp4
outbound_auth=fusion
server_uri=sip:smart.0038.net:5060
client_uri=sip:5???????@smart.0038.net:5060
retry_interval=60

[fusion]
type = auth
auth_type=userpass
username=5???????
password=secretpassword

[fusion]
type=endpoint
transport = transport-udp4
context=default
outbound_auth=fusion
;force_rport=yes
allow = !all,g722,ulaw
aors=fusion

[fusion]
type=identify
match=61.213.230.153
endpoint=fusion
 
[fusion]
type=aor
contact=sip:5???????@smart.0038.net

;---
;クライアント用のテンプレ設定 読み込むので消したらダメ
[endpoint-default](!)
type = endpoint
context = default
allow = !all,g722,ulaw
;direct_media = no
device_state_busy_at = 1
dtmf_mode = rfc4733
force_rport=no

[auth-default](!)
type=auth
auth_type=userpass

[aor-default](!)
type=aor
max_contacts=1

;---
; 内線 5000
[5000](endpoint-default)
type=endpoint
transport=transport-udp4
aors=5000
auth=5000auth

[5000](aor-default)

[5000auth](auth-default)
username=5000
password=himitsupassword

;---
; 内線 5100
[5100](endpoint-default)
type=endpoint
transport=transport-udp4
aors=5100 
auth=5100auth

[5100](aor-default)

[5100auth](auth-default)
username=5100
password=himitsupassword

5???????がFusionのSIP用ID、secretpasswordがそのパスワード。
sip.confと比べるとちょっと面倒な書き方。同じ[hoge]が続くと一瞬混乱するけどtypeで見て判断。[hoge]を[hage-hoge]にして識別するのもアリ(上の例だと5000authみたいなの)だけど解りやすそうで逆に迷う元になる(気がする)。

/usr/local/etc/asterisk/extensions.conf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
[general]
writeprotect=no
priorityjumping=no

[globals]
SPEAKINGCLOCK=117
MORNINGCALL=0840
CLOCONUMNER=03????????
FUSIONNUMBER=5??????? 

[default]
;=== 時報 ===
exten => ${SPEAKINGCLOCK},1,Goto(speakclock,s,1)

;=== モーニングコール ===
exten => ${MORNINGCALL},1,Goto(morningcall,s,1)

;=== Cloco クラウドPBXで外線着信 ===
exten => ${CLOCONUMBER},1, Goto(chakushin,s,1)

;=== Fusionで外線着信 ===
exten => ${FUSIONNUMBER},1, Goto(chakushin,s,1)

;=== Cloco クラウドPBXで外線発信 (通常)===
;exten => _0.,1,Dial(PJSIP/${EXTEN}@cloco,120,T) ;普通に0から始まる電話番号だけで発信 この場合はCloco
;exten => _0.,n,Hangup()

;=== Cloco クラウドPBXで外線発信 (965付き)===
exten => _965.,1,NoOp  ;番号最初の965は処理しない
exten => _965.,n,Dial(PJSIP/${EXTEN}@cloco,120,T) ;965+電話番号でCloco使用を明確にして発信
exten => _965.,n,Hangup()

;=== Fusionで外線発信 (38付き)===
exten => _38.,1,NoOp  ;番号最初の38は処理しない
exten => _38.,n,Dial(PJSIP/${EXTEN}@fusion,120,T) ;38+電話番号でFusion使用による発信
exten => _38.,n,Hangup()

;=== 内線 ===
exten => 5000,1,Dial(PJSIP/5000,30)
exten => 5000,2,Congestion
exten => 5000,102,Busy

exten => 5100,1,Dial(PJSIP/5100,30)
exten => 5100,2,Congestion
exten => 5100,102,Busy

;===========

[speakclock]
; 時報
exten => s,1,Answer()
exten => s,n,Wait(1)
exten => s,n,AGI(speaktime.agi)
exten => s,n,Wait(1)
exten => s,n,Hangup()

[morningcall]
; モーニングコール
exten => s,1,Answer()
exten => s,n,Wait(1)
exten => s,n,AGI(wakeup.agi)
exten => s,n,Wait(1)
exten => s,n,Hangup()

[chakushin]
; 着信
exten => s,1,Set(FROMNUM=${CALLERID(number)})
exten => s,n,Set(CALLERID(name)=${FROMNUM})
exten => s,n,Goto(default,5000,1)

上のはサンプルなので実際に使ってるのとは全然違うけど、こんな感じよってことで関係ないのも少しだけ混ぜてみた。モーニングコールとか時報のAGIスクリプトはこの記事では書かない。
外線から着信したら内線5000だけを鳴らす。(最後の行で内線5000に行く)。複数の電話を鳴らしたいならGotoの替わりにDial(PJSIP/5000&PJSIP/5100,30)みたいにするか、電話番号+内線番号で着信したら電話番号を除いてその番号(内線)に飛ばすなど。

でたらめに拡張しまくってたので巨大な設定ファイルになってたけど1から設定し直したら1/3くらいになった。たまには見直すのもいいね。

で、PJSIPにした結果だけど無事動いた。mp3ファイルが再生されないのは直ってないけどslnなどに変換すりゃ済むし・・

関連記事: