Asterisk Reference
Tips
- chan-sccp/chan-sccp
- http://chan-sccp-b.sourceforge.net/
- a replacement Channel Driver for chan_skinny in the Asterisk Channel Driver Library
- BUGS
- [#26423]https://issues.asterisk.org/jira/browse/ASTERISK-26423 res_pjsip_sdp_rtp: Asymmetric RTP codec can cause audio loss and wonkiness
Install
FAQ
user , peer, friend
- user 本端做验证, 呼入
- peer 远端做验证, 呼出
- friend 两端都要验证
- agent
- 用户代理
- 终端
- 代理服务
- 用户代理
Macro vs Sub
- 首选 Sub
- Macro 最多 7 层嵌套
Failed to insert call detail record into database
在使用 PJSIP_DIAL_CONTACTS
时, 号码可能非常长, 会导致数据库插入失败
[Sep 5 11:34:50] WARNING[11511]: cel_pgsql.c:351 pgsql_log: Failed to insert call detail record into database!
[Sep 5 11:34:50] WARNING[11511]: cel_pgsql.c:352 pgsql_log: Reason: ERROR: value too long for type character varying(80)
对接 O 口网关时, 程序崩溃
可能是由于 UDP 消息截断导致, 打开日志可以看到消息内容应该只有一部分
CDR vs CEL
- 都可以对接后端存储
- CDR
- 相对信息更少
- CEL
- 支持用于账单
- Control over which Asterisk applications are tracked.
- Control over which events should be raised.
- Configurable date format.
- Integration with the Asterisk Manager Interface.
- Integration with RADIUS
- Modules for various logging back-ends including customized CEL output, integration with ODBC, PGSQL, SQLite and TDS.
DAHDi 有持续性的噪音
- 可能是打开了 crc4 导致的, 在
system.conf
中关闭即可 - 如果有异常, 那也可能是 crc4 导致的
DAHDi 拨号选项
- channels/chan_dahdi.c#L13167
Dial(DAHDI/pseudo[/extension[/options]])
Dial(DAHDI/<channel#>[c|r<cadance#>|d][/extension[/options]])
Dial(DAHDI/<subdir>!<channel#>[c|r<cadance#>|d][/extension[/options]])
Dial(DAHDI/i<span>[/extension[/options]])
Dial(DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]])
- i - ISDN span channel restriction.
- Used by CC to ensure that the CC recall goes out the same span.
- Also to make ISDN channel names dialable when the sequence number is stripped off. (Used by DTMF attended transfer feature.)
- g - channel group allocation search forward
- G - channel group allocation search backward
- r - channel group allocation round robin search forward
- R - channel group allocation round robin search backward
- c - Wait for DTMF digit to confirm answer
- r<cadance#> - Set distintive ring cadance number
- d - Force bearer capability for ISDN/SS7 call to digital.
PJ ICE Rx error status code: 370401
Core Dump
- Getting a Backtrace
- 需要安装
gdb
- 除非编译时带了
DEBUG_THREADS
, 否则locks
为空 - 可以使用
libbfd
, 在编译时加上DONT_OPTIMIZE
,BETTER_BACKTRACES
以获得更好的转储信息 - 默认转储文件位于当前目录下的
core
, 会遵循kernel.core_pattern
配置将转储存到指定的地方
sysctl -n kernel.core_pattern
/var/lib/asterisk/scripts/ast_coredumper core
Probation passed
后程序崩溃
- 在 cli.conf 中打开全量日志
res_rtp_asterisk.c: Unsupported payload type received
CEL 数据库写入失败, 字段过长
- 应该是 appdata 字段导致, 可以将数据库的长度改长
DAHDi
DTMF/Dual-tone multi-frequency
- DTMF:wikipedia
- https://www.voip-info.org/wiki/view/Asterisk+sip+dtmfmode
- https://www.voip-info.org/wiki/view/DTMF
- 可选模式包括
- inband
- rfs2833
- info
- auto
ADSI/Analog Display Services Interface
- https://www.voip-info.org/wiki/view/ADSI
- adsi.conf
- asterisk.adsi
HA
Database
# 源码中包含了操作数据库的脚本
cd ./contrib/ast-db-manage
pip install alembic
# 创建配置文件
cp config.ini.sample config.ini
# 调整配置项
# 主要配置 sqlalchemy.url
nano config.in
# 数据库更新到最新结构
alembic -c config.ini upgrade head
# 如果不想操作数据库, 也可以生成 SQL
alembic -c config.ini upgrade head --sql
- sqlite
- render_as_batch=True
找不到 ENUM
- ASTERISK-27272 使用的那个版本配置可能有点问题, 在那个文件里添加以下内容即可
from sqlalchemy.dialects.postgresql import ENUM
YESNO_NAME = 'yesno_values'
YESNO_VALUES = ['yes', 'no']
实时配置
- Realtime Database Configuration
- 实时模块主要是抽象数据层的访问, 是可以添加自定义的表的
; modules.conf
; 预先加载必须的模块
[modules]
preload => res_odbc.so
preload => res_config_odbc.so
; extconfig.conf
; 定义外部配置
[settings]
; 语法
; file.conf => driver,database[,table[,priority]]
meetme => odbc,general
# 获取一条数据
realtime load sippeers name 9009
realtime load queues name marka
# 操作自定义的表
realtime load staffs no 8002
cel.postgres.sql
CREATE TABLE cel (
id serial ,
eventtype varchar (30) NOT NULL ,
eventtime timestamp NOT NULL ,
userdeftype varchar(255) NOT NULL ,
cid_name varchar (80) NOT NULL ,
cid_num varchar (80) NOT NULL ,
cid_ani varchar (80) NOT NULL ,
cid_rdnis varchar (80) NOT NULL ,
cid_dnid varchar (80) NOT NULL ,
exten varchar (80) NOT NULL ,
context varchar (80) NOT NULL ,
channame varchar (80) NOT NULL ,
appname varchar (80) NOT NULL ,
appdata varchar (80) NOT NULL ,
amaflags int NOT NULL ,
accountcode varchar (20) NOT NULL ,
peeraccount varchar (20) NOT NULL ,
uniqueid varchar (150) NOT NULL ,
linkedid varchar (150) NOT NULL ,
userfield varchar (255) NOT NULL ,
peer varchar (80) NOT NULL
);
Sorcery
- Sorcery
- Asterisk 12 添加
- 数据对象 CURD 抽象层
- Asterisk Database
- Static Configuration Files
- Asterisk Realtime Architecture
- In-Memory
- 提供了缓存服务, 用于从 ARI 推送配置
AST_SORCERY(module_name,object_type,object_id,field_name[,retrieval_method[,retrieval_details]])
- 操作函数
- retrieval_method, 默认为 concat
- concat, 当有多条数据时进行拼接, 默认使用
,
- single, 当有多条时返回一条记录, 默认为
1
- concat, 当有多条数据时进行拼接, 默认使用
- retrieval_details, 控制 concat 的连接符和 single 的位置
- retrieval_method, 默认为 concat
- 操作函数
- 先配置 extconfig.conf, 再配置 sorcery.conf 使用 extconfig 中定义的信息
func_sorcery.so Get a field from a sorcery object
res_sorcery_astdb.so Sorcery Astdb Object Wizard
res_sorcery_config.so Sorcery Configuration File Object Wizard
res_sorcery_memory.so Sorcery In-Memory Object Wizard
res_sorcery_memory_cache.so Sorcery Memory Cache Object Wizard
res_sorcery_realtime.so Sorcery Realtime Object Wizard
pjsip 的默认配置
[res_pjsip]
auth=config,pjsip.conf,criteria=type=auth
domain_alias=config,pjsip.conf,criteria=type=domain_alias
global=config,pjsip.conf,criteria=type=global
system=config,pjsip.conf,criteria=type=system
transport=config,pjsip.conf,criteria=type=transport
aor=config,pjsip.conf,criteria=type=aor
endpoint=config,pjsip.conf,criteria=type=endpoint
contact=astdb,registrator
[res_pjsip_endpoint_identifier_ip]
identify=config,pjsip.conf,criteria=type=identify
[res_pjsip_outbound_publish]
outbound-publish=config,pjsip.conf,criteria=type=outbound-publish
[res_pjsip_outbound_registration]
registration=config,pjsip.conf,criteria=type=registration
pjsip 实时配置
_extconfig.conf
ps_aors => pgsql,asterisk
ps_asterisk_publications => pgsql,asterisk
ps_auths => pgsql,asterisk
ps_contacts => pgsql,asterisk
ps_domain_aliases => pgsql,asterisk
ps_endpoint_id_ips => pgsql,asterisk
ps_endpoints => pgsql,asterisk
ps_globals => pgsql,asterisk
ps_inbound_publications => pgsql,asterisk
ps_outbound_publishes => pgsql,asterisk
ps_registrations => pgsql,asterisk
ps_resource_list => pgsql,asterisk
ps_subscription_persistence => pgsql,asterisk
ps_systems => pgsql,asterisk
ps_transports => pgsql,asterisk
sorcery.conf
[res_pjsip]
auth =realtime,ps_auths
domain_alias=realtime,ps_domain_aliases
global =realtime,ps_globals
system =realtime,ps_systems
transport =realtime,ps_transports
aor =realtime,ps_aors
endpoint =realtime,ps_endpoints
contact =realtime,ps_contacts
[res_pjsip_endpoint_identifier_ip]
identify =realtime,ps_endpoint_id_ips
[res_pjsip_outbound_publish]
outbound-publish=realtime,ps_outbound_publishes
[res_pjsip_outbound_registration]
registration=realtime,ps_registrations
Channel
# 查看所有的通道类型
core show channeltypes
chan_alsa/chan_console/chan_oss
- 同一时间只能启用一个, 默认启用 oss
- ALSA - Advanced Linux Sound Architecture
- OSS - Open Sound System
- Linux 2.6 默认为 ALSA, OSS 标记为废弃
- console - PortAudio
chan_sip
- 传输支持: tcp,udp,tls,ws,wss
- tcp 和 tls 位于实验阶段
- 5060: This is the standard port for SIP communications
- 8089: This is the standard port for Secure Websockets when used with Asterisk's built-in HTTP sever
- 10000:20000: This is the port range configured in rtp.conf for audio to flow.
QoS
- IP Quality of Service
- 默认未开启 QoS, 所以 Peer 的状态都是显示的未知
res_pjsip
- 总结: 建议使用
res_pjsip
, 禁用chan_sip
- SIP vs. CHAN_SIP vs. CHAN_PJSIP
- Migrating from chan sip to res pjsip
- 幻灯片
- astricon2015
- 脚本和相关文件配置
- 包含数据库
sippeers
转ps_
的脚本
- PJSIP: Tuning for Performance
- WHY
- 更好的配置
- 多个 aors -> 单个终端
- 多个终端共振
- NAT 更简单
- 没有 user,peer,friend
- 更好的设备和 邮箱状态
- 更简单更快更好的开发
- 配置类型
- transport
- 绑定 res_pjsip 到地址端口
- 可绑定多个
- 不能重载
- endpoint
- 发起和接收通话的设备
- 包含: transport, aor, auth
- 配置的 transport 主要用于发送, 所有的都能接收
- auth
auth_type
- 授权类型
- nonce_lifetime
- 单位 秒
- 默认 32
- userpass
- password 存储明文
- md5
- md5_cred 存储密文
- 格式为 账号*⃣密码
- asterisk 为 realm, 可以修改
- aor
- Address of Record
- Multiple AORS for 1 device
- AORS can be overwritten or not
- Can be static or dynamic (qualify)
- identify
- Endpoint Identification
res_pjsip_endpoint_identifier_ip
- 基于 IP 的认证
- 匹配进入的包 -> 终端
res_pjsip_endpoint_identifier_user
- 可以从
From
头中提取出用户信息由于验证
- 可以从
- 使用 IP 还是用用户取决于模块加载顺序
- 用于外部线路,直接匹配 IP 来对应 endpoint
- registration
- 将 Asterisk 连接到另外一个 Asterisk
- 以前为
register => username:password@server/context
- acl
- Access Control List
- phoneprov
- Phone Provisioning
- System
- Domain alias
- 域名别名
- 在 AOR 的域名找不到时尝试找别名
- outbound-publish
- transport
- Tips
Dial(PJSIP/${EXTEN})
Dial(${PJSIP_DIAL_CONTACTS(${EXTEN})})
- 拨打所有设备
PJSIP/9001/sip:[email protected]:33322&PJSIP/9001/sip:[email protected]:58069
Dial(PJSIP/mytrunk/sip:${EXTEN:1})
Dial(PJSIP/${EXTEN:1}@mytrunk)
- PJSIP 使用的表前缀为
ps_
, 有很多表, 而不像 chan_sip 只有一个 sippeers 表- aors, auths, contacts, endpoints, domain_aliases, endpoint_id_ips, globals, registrations, subscription_persistence, systems, transports
# 问题排查
core set verbose 4
core set debug 4
pjsip set logger on
[ts-udp]
type=transport
protocol=udp
bind=0.0.0.0
[ts-tcp]
type=transport
protocol=tcp
bind=0.0.0.0
[trans-more]
type=transport
protocol=udp,tcp,tls,ws,wss
bind=0.0.0.0:5061
local_net=192.0.2.0/2
external_medial_address=20.0.113.1
external_signaling_address=20.0.113.1
[6001]
type=endpoint
context=default
disallow=all
allow=ulw
transport=trans-one
auth=auth6001
aors=6001
; aor static
[6001]
type=aor
contact=sip:[email protected]:5060
contact=sip:[email protected]:5060
; aor dynamic
[6001]
type=aor
default_exporation=3600
maximum_exporation=7200
minimum_exporation=60
max_contacts=1
remove_existing=yes
qualify_frequency=60
qualify_timeout=3.0
[auth6001]
type=auth
auth_type=userpass
password=secret
username=6001
[mytrunk]
type=registration
transport=simpletrans
outbound_auth=mytrunk
server_uri=sip:sip.example.com
client_uri=sip:[email protected]
retry_interval=60
[my-itsip]
type=wizard
sends_auth=yes
sends_registrations=yes
remote_hosts=sip.my-itsp.net
outbound_auth/username=my_username
outbound_auth/password=my_password
endpoint/context=default
aor/qualify_frequency=15
; 简单的用户模板
[user-template](!)
type = wizard
accepts_registrations = yes
accepts_auth = yes
endpoint/context = default
endpoint/allow = !all,ulaw,gsm,g722
aor/max_contacts=5
[9001](user-template)
inbound_auth/username = 9001
inbound_auth/password = 9001
[9002](user-template)
inbound_auth/username = 9002
inbound_auth/password = 9002