Инструменты пользователя

Инструменты сайта


сервис_asterisk

Содержание

Сервис Asterisk

Установка

Debian/Ubuntu

root@server:~# apt install asterisk

root@server:~# cd /etc/asterisk/

FreeBSD

[server:~] # pkg install asterisk13

[server:~] # service asterisk rcvar

[server:~] # cd /usr/local/etc/asterisk/

Удаление

# apt purge asterisk-config asterisk

# apt autoremove

Настройка базового функционала IP PBX

Настройка CHAN_SIP каналов

server# cat sip.conf
[general]
;udpbindaddr=0.0.0.0:5061
transport=udp
disallow=all
allow=alaw
;context=default
;allowguest=no          ;Allow unknown access
;alwaysauthreject=yes   ;Always auth rejects
;autocreatepeer=no      ;AutoCreate Peer
;localnet=192.168.X.0/255.255.255.0
;;;externip=172.16.1.X
;externaddr = 172.16.1.X
;externaddr = 172.16.1.X:6050
;defaultexpiry=60

[401]
secret=tpassword401
type=friend
host=dynamic

[402]
secret=tpassword402
type=friend
host=dynamic
;allowsubscribe=no
;setvar=MY-USER-ID=user2@corpX.un       ;in channel type=user 
;callerid=Petrov Petr Petrovitch<402>
;cid_number=402
;fullname=Petrov Petr Petrovitch
;disallow=all
;allow=gsm
;canreinvite=no ;1.4
;directmedia=no ;1.6
;;;nat=yes
;nat=force_rport,comedia
;qualify=yes
;call-limit=1
;deny=0.0.0.0/0.0.0.0
;permit=172.16.1.0/255.255.255.0

;[user1]
;secret=password1
;type=friend
;host=dynamic

;[corpY]
;type=peer
;context=default
;host=server.corpY.un

Использование шаблонов в именах CHAN_SIP каналов

root@server# cat sip.conf
...
;[office](!)
;type=friend
;host=dynamic
;deny=0.0.0.0/0.0.0.0
;permit=192.168.X.0/255.255.255.0

;[403](office)
;secret=tpassword403

;[404](office)
;secret=tpassword404
...

Настройка RES_PJSIP каналов

Настройка PJSIP транспорта

# cat /etc/asterisk/sip.conf
[general]
udpbindaddr=0.0.0.0:5061
# cat /etc/asterisk/pjsip.conf
[udp-transport-1]
type=transport
protocol=udp
bind=0.0.0.0:5060
;local_net=192.168.X.0/255.255.255.0
;external_media_address=172.16.1.X
;external_signaling_address=172.16.1.X

Настройка PJSIP точки подключения телефона

Базовый вариант

# cat /etc/asterisk/pjsip.conf
...
[401]
type=endpoint
transport=udp-transport-1
context=default
disallow=all
allow=alaw
aors=401
auth=401
;callerid=Иван Иванов<401>
;set_var=MY-USER-ID=user1@corpX.un
;set_var=MY-PSTN-CALLER-ID=8495123456X
;rtp_symmetric=yes
;force_rport=yes
;rewrite_contact=yes
;direct_media=no

[401]
type=aor
max_contacts=1
remove_existing=yes

[401]
type=auth
auth_type=userpass
password=tpassword401
username=401
...

Wizard вариант

!!! Изменение отдельных параметров требует либо удаление/reload/добавление/reload всего описания точки подключения, либо перезапуска asterisk

# cat /etc/asterisk/pjsip_wizard.conf
[402]
type=wizard
accepts_auth=yes
accepts_registrations=yes
transport=udp-transport-1
inbound_auth/username=402
inbound_auth/password=tpassword402
endpoint/allow=alaw
endpoint/context=default
;endpoint/set_var=MY-USER-ID=user2@corp13.un
;endpoint/callerid=Petr P. Petrov<402>
aor/max_contacts=1
aor/remove_existing=yes

Настройка PJSIP точки подключения к VoIP провайдеру

# cat /etc/asterisk/pjsip.conf
...
[voip1_00000X]
type=endpoint
transport=udp-transport-1
context=default
disallow=all
allow=alaw
outbound_auth=voip1_00000X
aors=voip1_00000X
from_user=00000X
from_domain=voip1.un
;direct_media=no
;rtp_symmetric=yes
;;;force_rport=yes
;;;rewrite_contact=yes

[voip1_00000X]
type=auth
auth_type=userpass
password=spasswordX
username=00000X

[voip1_00000X]
type=aor
contact=sip:voip1.un:5060
;qualify_frequency=60

[voip1_00000X]
type=registration
transport=udp-transport-1
outbound_auth=voip1_00000X
server_uri=sip:voip1.un
client_uri=sip:00000X@voip1.un
;;;retry_interval=10
;;;expiration=10
contact_user=voip1_00000X

[voip1_00000X]
type=identify
endpoint=voip1_00000X
match=voip1.un

Настройка базового плана нумерации

server# cat extensions.conf
;[general]

;[globals]

[default]

exten => 301,1,Answer()
exten => 301,n,Playback(hello-world)
exten => 301,n,SayNumber(X)
exten => 301,n,Hangup()

exten => 311,1,Answer()
     same => n,Echo()

;exten => 321,1,Answer()
;     same => n,SayDigits(${EXTEN})
;     same => n,Playback(beep)
;     same => n,SayDigits(${CALLERID(num)})
;     same => n,Hangup()

;exten => 331,1,Answer()
;exten => 331,n,NoOp(${MY-USER-ID})
;exten => 331,n,Verbose(1,${MY-USER-ID})
;exten => 331,n,Hangup()

;exten => 401,1,Dial(SIP/401)

;exten => 402,1,Dial(SIP/402)

exten => _4XX,1,Dial(SIP/${EXTEN})
;exten => _4XX,1,Dial(PJSIP/${EXTEN})

Командный интерфейс Asterisk

server# asterisk -r

server*CLI> sip reload
server*CLI> sip show settings
server*CLI> sip show users
server*CLI> sip show user 401
server*CLI> sip show peers
server*CLI> sip show peer 401
server*CLI> sip unregister 401

server*CLI> pjsip reload
server*CLI> pjsip show endpoints

server*CLI> dialplan reload
server*CLI> dialplan show default

server*CLI> core reload
server*CLI> core restart gracefully

server*CLI> exit

server# asterisk -x 'sip show peers'

Видеозвонки

server# cat sip.conf
[general]
...
allow=h263
allow=h264
videosupport=yes
avpf=yes
...

Отладка работы Asterisk

Сервисные сообщения

server# asterisk -rvvv

server*CLI> core set verbose 1

server# cat logger.conf
...
;console => notice,warning,error
console => warning,error,dtmf
messages => notice,warning,verbose(10),error
...
# tail -f /var/log/asterisk/messages

Отладка SIP

server*CLI> sip set debug peer 401
server*CLI> sip set debug ip 172.16.1.Z
server*CLI> sip set debug off

Отладка RTP

server*CLI> rtp set debug on 

Управление контекстами

TimeBased контексты

server# cat extensions.conf
[default]
...
include=>notwork,18:00-9:00,*,*,*
include=>work,9:00-18:00,*,*,*

[work]
exten => voip1_00000X,1,Dial(SIP/403,10,t)
exten => voip1_00000X,n,Dial(SIP/401&SIP/402)

[notwork]
exten => voip1_00000X,1,Dial(SIP/voip1_00000X/89161234567)

Подключение Asterisk к VoIP провайдеру по протоколу SIP

Шаблон конфигурации для осуществления исходящих вызовов

server# cat sip.conf
...
[voip1_00000X]
type=peer
defaultuser=00000X
secret=spasswordX
host=voip1.un
fromuser=00000X
fromdomain=voip1.un
server# cat extensions.conf
...
exten => _8XXXXXXXXXX,1,Dial(SIP/voip1_00000X/${EXTEN})
;exten => _8XXXXXXXXXX,1,Dial(SIP/${EXTEN}@voip1_00000X)
;exten => _8XXXXXXXXXX,1,Dial(PJSIP/${EXTEN}@voip1_00000X)  ;PJSIP только так

Шаблон конфигурации для обработки входящих вызовов

server# cat sip.conf
[general]
...
;register => 00000X:spasswordX@voip1.un/voip1_00000X
...
[voip1_00000X]
type=peer
defaultuser=00000X
secret=spasswordX
host=voip1.un
fromuser=00000X
fromdomain=voip1.un
;context=incoming
insecure=invite
callbackextension=voip1_00000X
server# cat extensions.conf
[globals]

;MY-RING-GROUP => SIP/401&SIP/402&SIP/403&SIP/404

;MY-RING-GROUP-84951234567 => SIP/401&SIP/402
;MY-RING-GROUP-84957654321 => SIP/403&SIP/404

[default]
...

;[incoming]
exten => voip1_00000X,1,Dial(SIP/401&SIP/402&SIP/403&SIP/404)

;exten => voip1_00000X,1,Dial(${MY-RING-GROUP})

;exten => 8495XXXXXXX,1,Dial(${MY-RING-GROUP-${EXTEN}})
server*CLI> sip show registry

Использование asterisk в качестве телефона

phone2# cat extensions.conf
[default]

exten => 301,1,Answer()
exten => 301,n,Playback(hello-world)
exten => 301,n,Hangup()
debian# cat modules.conf
...
load => chan_alsa.so
noload => chan_oss.so
...
pasberry# cat alsa.conf
...
input_device=hw:1,0
output_device=hw:0,0
...
phone2*CLI> module show like alsa

phone2*CLI> channel originate Console/dsp extension 301
phone2*CLI> console answer
phone2*CLI> console hangup
phone2# cat sip.conf
[general]
transport=udp
disallow=all
allow=alaw

[sipproxy]
type=peer
defaultuser=402
secret=tpassword402
host=gate.corpX.un
insecure=invite
callbackextension=sipproxy
phone2# cat extensions.conf
...
exten => _4XX,1,Dial(SIP/sipproxy/${EXTEN})
exten => sipproxy,1,Dial(Console/dsp)

Подключение Asterisk к Asterisk по протоколу SIP

Настройка серверов филиалов

Настройка центрального сервера

root@isp.un:~# cat sip.conf
...
[000001]
type=user
;type=friend
secret=spassword1
host=dynamic
context=from-sip-trunk
...
[000006]
type=user
;type=friend
secret=spassword6
host=dynamic
context=from-sip-trunk
root@isp.un:~# cat /etc/asterisk/extensions.conf
...
[from-sip-trunk]
exten => _8XXXXXXXXXX,1,Dial(SIP/sipnet_00000X/${EXTEN})

Подключение Asterisk к Asterisk по протоколу IAX

Настройка IAX каналов

server.corpX.un# cat iax.conf
[general]
;bindport=4569
;bindaddr=0.0.0.0
disallow=all
allow=alaw

[corpY]
type=user
;context=default
host=dynamic
secret=apasswordY
auth=md5

[corpY]
type=peer
host=server.corpY.un
username=corpX
secret=apasswordX
auth=md5

;[corpY]
;type=friend
;context=default
;host=server.corpY.un

Настройка плана нумерации

server.corpX.un# cat extensions.conf
[default]
...
exten => _00Y4XX,1,Set(CALLERID(num)=00X${CALLERID(num)})
exten => _00Y4XX,n,Dial(IAX2/corpY/${EXTEN:3})

;;пример универсального шаблона для звонков в офисы с 1-го по 9-й
;exten => _0XX4XX,1,Set(CALLERID(num)=013${CALLERID(num)})
;exten => _0XX4XX,n,Dial(IAX2/corp${EXTEN:2:1}/${EXTEN:3})
server*CLI> iax2 reload

server*CLI> dialplan reload

Детализация разговоров

Просмотр текущих звонков

server*CLI> sip show channels

server*CLI> cdr show active

server*CLI> channel request hangup SIP/<TAB>

# curl -v -X GET "http://localhost:8088/ari/channels?api_key=asterisk:asterisk"

Настройка местного времени

server# cat /etc/asterisk/cdr.conf
...
[csv]
usegmtime=no
...

Добавление IP адреса

exten => _4XX,1,Set(CDR(userfield)=${CHANNEL(recvip)})
exten => _4XX,n,Dial(SIP/${EXTEN},,Tt)

Использование файлов для хранения CDR

Просмотр

server# tail -f /var/log/asterisk/cdr-csv/Master.csv

Построение отчетов

Ротация с использованием SYSLOG

server# :> cdr.conf

server# cat cdr_syslog.conf
[general]
facility=local0

[cdr-simple]
template = "${CDR(clid)}","${CDR(src)}","${CDR(dst)}","${CDR(dcontext)}","${CDR(channel)}","${CDR(dstchannel)}","${CDR(lastapp)}","${CDR(lastdata)}","${CDR(start)}","${CDR(answer)}","${CDR(end)}","${CDR(duration)}","${CDR(billsec)}","${CDR(disposition)}","${CDR(amaflags)}","${CDR(accountcode)}","${CDR(uniqueid)}","${CDR(userfield)}"
server# asterisk -x 'core restart gracefully'

server# asterisk -x 'cdr show status'
...
  Mode:                       Simple
...
* Registered Backends
  -------------------
    cdr-syslog
...
server# tail -f /var/log/cisco.log

Использование СУБД для хранения CDR

Создание базы данных

# cat cdr.sql
CREATE DATABASE asterisk;
 
GRANT ALL ON asterisk.* TO asterisk@localhost IDENTIFIED BY 'asterisk';

USE asterisk;

CREATE TABLE `cdr` (
 `calldate` datetime NOT NULL default CURRENT_TIMESTAMP,
 `clid` varchar(80) NOT NULL default '',
 `src` varchar(80) NOT NULL default '',
 `dst` varchar(80) NOT NULL default '',
 `dcontext` varchar(80) NOT NULL default '', 
 `channel` varchar(80) NOT NULL default '',
 `dstchannel` varchar(80) NOT NULL default '',
 `lastapp` varchar(80) NOT NULL default '',
 `lastdata` varchar(80) NOT NULL default '',
 `duration` int(11) NOT NULL default '0',
 `billsec` int(11) NOT NULL default '0',
 `disposition` varchar(45) NOT NULL default '', 
 `amaflags` int(11) NOT NULL default '0',
 `accountcode` varchar(20) NOT NULL default '',
 `userfield` varchar(255) NOT NULL default '',
 `uniqueid` VARCHAR(32) NOT NULL default '',
 `linkedid` VARCHAR(32) NOT NULL default '',
 `sequence` VARCHAR(32) NOT NULL default '',
 `peeraccount` VARCHAR(32) NOT NULL default ''
 );

ALTER TABLE `cdr` ADD INDEX ( `calldate` );
ALTER TABLE `cdr` ADD INDEX ( `dst` );
ALTER TABLE `cdr` ADD INDEX ( `accountcode` );
# mysql < cdr.sql

Настройка записи в БД

Просмотра статистики CDR и прослушивание записей

# cd /var/www/html

# wget http://val.bmstu.ru/unix/voip/asterisk-cdr-viewer-latest.tgz

# tar -xzvf asterisk-cdr-viewer-*.tgz

# cat /var/www/html/asterisk-cdr-viewer/include/config.inc.php
...
$db_user = 'asterisk';
$db_pass = 'asterisk';
$db_name = 'asterisk';
...
$system_auth_require = 0;
...
# cat extensions.conf
...
;exten => _4XX,1,Macro(monitor)
exten => _4XX,1,GoSub(sub-monitor,s,1)
exten => _4XX,n,Dial(SIP/${EXTEN})
...
;[macro-monitor]
[sub-monitor]
exten => s,1,Set(MONITOR_FILE=/var/spool/asterisk/monitor/${UNIQUEID})
exten => s,n,MixMonitor(${MONITOR_FILE}.wav,b)
exten => s,n,Return()
# usermod -G asterisk www-data

# service apache2 restart
http://server.corpX.un/asterisk-cdr-viewer/

Asterisk realtime

PJSIP

CREATE TABLE `ps_aors` (
  `id` varchar(40) NOT NULL,
  `contact` varchar(255) DEFAULT NULL,
  `default_expiration` int(11) DEFAULT NULL,
  `mailboxes` varchar(80) DEFAULT NULL,
  `max_contacts` int(11) DEFAULT NULL,
  `minimum_expiration` int(11) DEFAULT NULL,
  `remove_existing` enum('yes','no') DEFAULT NULL,
  `qualify_frequency` int(11) DEFAULT NULL,
  `authenticate_qualify` enum('yes','no') DEFAULT NULL,
  `maximum_expiration` int(11) DEFAULT NULL,
  `outbound_proxy` varchar(40) DEFAULT NULL,
  `support_path` enum('yes','no') DEFAULT NULL,
  `qualify_timeout` float DEFAULT NULL,
  `voicemail_extension` varchar(40) DEFAULT NULL,
  UNIQUE KEY `id` (`id`),
  KEY `ps_aors_id` (`id`),
  KEY `ps_aors_qualifyfreq_contact` (`qualify_frequency`,`contact`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `ps_auths` (
  `id` varchar(40) NOT NULL,
  `auth_type` enum('md5','userpass') DEFAULT NULL,
  `nonce_lifetime` int(11) DEFAULT NULL,
  `md5_cred` varchar(40) DEFAULT NULL,
  `password` varchar(80) DEFAULT NULL,
  `realm` varchar(40) DEFAULT NULL,
  `username` varchar(40) DEFAULT NULL,
  UNIQUE KEY `id` (`id`),
  KEY `ps_auths_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `ps_contacts` (
  `id` varchar(255) DEFAULT NULL,
  `uri` varchar(255) DEFAULT NULL,
  `expiration_time` bigint(20) DEFAULT NULL,
  `qualify_frequency` int(11) DEFAULT NULL,
  `outbound_proxy` varchar(40) DEFAULT NULL,
  `path` text,
  `user_agent` varchar(255) DEFAULT NULL,
  `qualify_timeout` float DEFAULT NULL,
  `reg_server` varchar(20) DEFAULT NULL,
  `authenticate_qualify` enum('yes','no') DEFAULT NULL,
  `via_addr` varchar(40) DEFAULT NULL,
  `via_port` int(11) DEFAULT NULL,
  `call_id` varchar(255) DEFAULT NULL,
  `endpoint` varchar(40) DEFAULT NULL,
  `prune_on_boot` enum('yes','no') DEFAULT NULL,
  UNIQUE KEY `id` (`id`),
  UNIQUE KEY `ps_contacts_uq` (`id`,`reg_server`),
  KEY `ps_contacts_id` (`id`),
  KEY `ps_contacts_qualifyfreq_exp` (`qualify_frequency`,`expiration_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `ps_domain_aliases` (
  `id` varchar(40) NOT NULL,
  `domain` varchar(80) DEFAULT NULL,
  UNIQUE KEY `id` (`id`),
  KEY `ps_domain_aliases_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `ps_endpoint_id_ips` (
  `id` varchar(40) NOT NULL,
  `endpoint` varchar(40) DEFAULT NULL,
  `match` varchar(80) DEFAULT NULL,
  UNIQUE KEY `id` (`id`),
  KEY `ps_endpoint_id_ips_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `ps_endpoints` (
  `id` varchar(40) NOT NULL,
  `transport` varchar(40) DEFAULT NULL,
  `aors` varchar(200) DEFAULT NULL,
  `auth` varchar(40) DEFAULT NULL,
  `context` varchar(40) DEFAULT NULL,
  `disallow` varchar(200) DEFAULT NULL,
  `allow` varchar(200) DEFAULT NULL,
  `direct_media` enum('yes','no') DEFAULT NULL,
  `connected_line_method` enum('invite','reinvite','update') DEFAULT NULL,
  `direct_media_method` enum('invite','reinvite','update') DEFAULT NULL,
  `direct_media_glare_mitigation` enum('none','outgoing','incoming') DEFAULT NULL,
  `disable_direct_media_on_nat` enum('yes','no') DEFAULT NULL,
  `dtmf_mode` enum('rfc4733','inband','info','auto') DEFAULT NULL,
  `external_media_address` varchar(40) DEFAULT NULL,
  `force_rport` enum('yes','no') DEFAULT NULL,
  `ice_support` enum('yes','no') DEFAULT NULL,
  `identify_by` enum('username','auth_username') DEFAULT NULL,
  `mailboxes` varchar(40) DEFAULT NULL,
  `moh_suggest` varchar(40) DEFAULT NULL,
  `outbound_auth` varchar(40) DEFAULT NULL,
  `outbound_proxy` varchar(40) DEFAULT NULL,
  `rewrite_contact` enum('yes','no') DEFAULT NULL,
  `rtp_ipv6` enum('yes','no') DEFAULT NULL,
  `rtp_symmetric` enum('yes','no') DEFAULT NULL,
  `send_diversion` enum('yes','no') DEFAULT NULL,
  `send_pai` enum('yes','no') DEFAULT NULL,
  `send_rpid` enum('yes','no') DEFAULT NULL,
  `timers_min_se` int(11) DEFAULT NULL,
  `timers` enum('forced','no','required','yes') DEFAULT NULL,
  `timers_sess_expires` int(11) DEFAULT NULL,
  `callerid` varchar(40) DEFAULT NULL,
  `callerid_privacy` enum('allowed_not_screened','allowed_passed_screened','allowed_failed_screened','allowed','prohib_not_screened','prohib_passed_screened','prohib_failed_screened','prohib','unavailable') DEFAULT NULL,
  `callerid_tag` varchar(40) DEFAULT NULL,
  `100rel` enum('no','required','yes') DEFAULT NULL,
  `aggregate_mwi` enum('yes','no') DEFAULT NULL,
  `trust_id_inbound` enum('yes','no') DEFAULT NULL,
  `trust_id_outbound` enum('yes','no') DEFAULT NULL,
  `use_ptime` enum('yes','no') DEFAULT NULL,
  `use_avpf` enum('yes','no') DEFAULT NULL,
  `media_encryption` enum('no','sdes','dtls') DEFAULT NULL,
  `inband_progress` enum('yes','no') DEFAULT NULL,
  `call_group` varchar(40) DEFAULT NULL,
  `pickup_group` varchar(40) DEFAULT NULL,
  `named_call_group` varchar(40) DEFAULT NULL,
  `named_pickup_group` varchar(40) DEFAULT NULL,
  `device_state_busy_at` int(11) DEFAULT NULL,
  `fax_detect` enum('yes','no') DEFAULT NULL,
  `t38_udptl` enum('yes','no') DEFAULT NULL,
  `t38_udptl_ec` enum('none','fec','redundancy') DEFAULT NULL,
  `t38_udptl_maxdatagram` int(11) DEFAULT NULL,
  `t38_udptl_nat` enum('yes','no') DEFAULT NULL,
  `t38_udptl_ipv6` enum('yes','no') DEFAULT NULL,
  `tone_zone` varchar(40) DEFAULT NULL,
  `language` varchar(40) DEFAULT NULL,
  `one_touch_recording` enum('yes','no') DEFAULT NULL,
  `record_on_feature` varchar(40) DEFAULT NULL,
  `record_off_feature` varchar(40) DEFAULT NULL,
  `rtp_engine` varchar(40) DEFAULT NULL,
  `allow_transfer` enum('yes','no') DEFAULT NULL,
  `allow_subscribe` enum('yes','no') DEFAULT NULL,
  `sdp_owner` varchar(40) DEFAULT NULL,
  `sdp_session` varchar(40) DEFAULT NULL,
  `tos_audio` varchar(10) DEFAULT NULL,
  `tos_video` varchar(10) DEFAULT NULL,
  `sub_min_expiry` int(11) DEFAULT NULL,
  `from_domain` varchar(40) DEFAULT NULL,
  `from_user` varchar(40) DEFAULT NULL,
  `mwi_from_user` varchar(40) DEFAULT NULL,
  `dtls_verify` varchar(40) DEFAULT NULL,
  `dtls_rekey` varchar(40) DEFAULT NULL,
  `dtls_cert_file` varchar(200) DEFAULT NULL,
  `dtls_private_key` varchar(200) DEFAULT NULL,
  `dtls_cipher` varchar(200) DEFAULT NULL,
  `dtls_ca_file` varchar(200) DEFAULT NULL,
  `dtls_ca_path` varchar(200) DEFAULT NULL,
  `dtls_setup` enum('active','passive','actpass') DEFAULT NULL,
  `srtp_tag_32` enum('yes','no') DEFAULT NULL,
  `media_address` varchar(40) DEFAULT NULL,
  `redirect_method` enum('user','uri_core','uri_pjsip') DEFAULT NULL,
  `set_var` text,
  `cos_audio` int(11) DEFAULT NULL,
  `cos_video` int(11) DEFAULT NULL,
  `message_context` varchar(40) DEFAULT NULL,
  `force_avp` enum('yes','no') DEFAULT NULL,
  `media_use_received_transport` enum('yes','no') DEFAULT NULL,
  `accountcode` varchar(80) DEFAULT NULL,
  `user_eq_phone` enum('yes','no') DEFAULT NULL,
  `moh_passthrough` enum('yes','no') DEFAULT NULL,
  `media_encryption_optimistic` enum('yes','no') DEFAULT NULL,
  `rpid_immediate` enum('yes','no') DEFAULT NULL,
  `g726_non_standard` enum('yes','no') DEFAULT NULL,
  `rtp_keepalive` int(11) DEFAULT NULL,
  `rtp_timeout` int(11) DEFAULT NULL,
  `rtp_timeout_hold` int(11) DEFAULT NULL,
  `bind_rtp_to_media_address` enum('yes','no') DEFAULT NULL,
  `voicemail_extension` varchar(40) DEFAULT NULL,
  `mwi_subscribe_replaces_unsolicited` int(11) DEFAULT NULL,
  `deny` varchar(95) DEFAULT NULL,
  `permit` varchar(95) DEFAULT NULL,
  `acl` varchar(40) DEFAULT NULL,
  `contact_deny` varchar(95) DEFAULT NULL,
  `contact_permit` varchar(95) DEFAULT NULL,
  `contact_acl` varchar(40) DEFAULT NULL,
  `subscribe_context` varchar(40) DEFAULT NULL,
  `fax_detect_timeout` int(11) DEFAULT NULL,
  `contact_user` varchar(80) DEFAULT NULL,
  `asymmetric_rtp_codec` enum('yes','no') DEFAULT NULL,
  UNIQUE KEY `id` (`id`),
  KEY `ps_endpoints_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `ps_globals` (
  `id` varchar(40) NOT NULL,
  `max_forwards` int(11) DEFAULT NULL,
  `user_agent` varchar(255) DEFAULT NULL,
  `default_outbound_endpoint` varchar(40) DEFAULT NULL,
  `debug` varchar(40) DEFAULT NULL,
  `endpoint_identifier_order` varchar(40) DEFAULT NULL,
  `max_initial_qualify_time` int(11) DEFAULT NULL,
  `default_from_user` varchar(80) DEFAULT NULL,
  `keep_alive_interval` int(11) DEFAULT NULL,
  `regcontext` varchar(80) DEFAULT NULL,
  `contact_expiration_check_interval` int(11) DEFAULT NULL,
  `default_voicemail_extension` varchar(40) DEFAULT NULL,
  `disable_multi_domain` enum('yes','no') DEFAULT NULL,
  `unidentified_request_count` int(11) DEFAULT NULL,
  `unidentified_request_period` int(11) DEFAULT NULL,
  `unidentified_request_prune_interval` int(11) DEFAULT NULL,
  `default_realm` varchar(40) DEFAULT NULL,
  `mwi_tps_queue_high` int(11) DEFAULT NULL,
  `mwi_tps_queue_low` int(11) DEFAULT NULL,
  `mwi_disable_initial_unsolicited` enum('yes','no') DEFAULT NULL,
  `ignore_uri_user_options` enum('yes','no') DEFAULT NULL,
  UNIQUE KEY `id` (`id`),
  KEY `ps_globals_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `ps_registrations` (
  `id` varchar(40) NOT NULL,
  `auth_rejection_permanent` enum('yes','no') DEFAULT NULL,
  `client_uri` varchar(255) DEFAULT NULL,
  `contact_user` varchar(40) DEFAULT NULL,
  `expiration` int(11) DEFAULT NULL,
  `max_retries` int(11) DEFAULT NULL,
  `outbound_auth` varchar(40) DEFAULT NULL,
  `outbound_proxy` varchar(40) DEFAULT NULL,
  `retry_interval` int(11) DEFAULT NULL,
  `forbidden_retry_interval` int(11) DEFAULT NULL,
  `server_uri` varchar(255) DEFAULT NULL,
  `transport` varchar(40) DEFAULT NULL,
  `support_path` enum('yes','no') DEFAULT NULL,
  `fatal_retry_interval` int(11) DEFAULT NULL,
  `line` enum('yes','no') DEFAULT NULL,
  `endpoint` varchar(40) DEFAULT NULL,
  UNIQUE KEY `id` (`id`),
  KEY `ps_registrations_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



CREATE TABLE `ps_subscription_persistence` (
  `id` varchar(40) NOT NULL,
  `packet` varchar(2048) DEFAULT NULL,
  `src_name` varchar(128) DEFAULT NULL,
  `src_port` int(11) DEFAULT NULL,
  `transport_key` varchar(64) DEFAULT NULL,
  `local_name` varchar(128) DEFAULT NULL,
  `local_port` int(11) DEFAULT NULL,
  `cseq` int(11) DEFAULT NULL,
  `tag` varchar(128) DEFAULT NULL,
  `endpoint` varchar(40) DEFAULT NULL,
  `expires` int(11) DEFAULT NULL,
  UNIQUE KEY `id` (`id`),
  KEY `ps_subscription_persistence_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `ps_systems` (
  `id` varchar(40) NOT NULL,
  `timer_t1` int(11) DEFAULT NULL,
  `timer_b` int(11) DEFAULT NULL,
  `compact_headers` enum('yes','no') DEFAULT NULL,
  `threadpool_initial_size` int(11) DEFAULT NULL,
  `threadpool_auto_increment` int(11) DEFAULT NULL,
  `threadpool_idle_timeout` int(11) DEFAULT NULL,
  `threadpool_max_size` int(11) DEFAULT NULL,
  `disable_tcp_switch` enum('yes','no') DEFAULT NULL,
  UNIQUE KEY `id` (`id`),
  KEY `ps_systems_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



CREATE TABLE `ps_transports` (
  `id` varchar(40) NOT NULL,
  `async_operations` int(11) DEFAULT NULL,
  `bind` varchar(40) DEFAULT NULL,
  `ca_list_file` varchar(200) DEFAULT NULL,
  `cert_file` varchar(200) DEFAULT NULL,
  `cipher` varchar(200) DEFAULT NULL,
  `domain` varchar(40) DEFAULT NULL,
  `external_media_address` varchar(40) DEFAULT NULL,
  `external_signaling_address` varchar(40) DEFAULT NULL,
  `external_signaling_port` int(11) DEFAULT NULL,
  `method` enum('default','unspecified','tlsv1','sslv2','sslv3','sslv23') DEFAULT NULL,
  `local_net` varchar(40) DEFAULT NULL,
  `password` varchar(40) DEFAULT NULL,
  `priv_key_file` varchar(200) DEFAULT NULL,
  `protocol` enum('udp','tcp','tls','ws','wss') DEFAULT NULL,
  `require_client_cert` enum('yes','no') DEFAULT NULL,
  `verify_client` enum('yes','no') DEFAULT NULL,
  `verify_server` enum('yes','no') DEFAULT NULL,
  `tos` varchar(10) DEFAULT NULL,
  `cos` int(11) DEFAULT NULL,
  `allow_reload` enum('yes','no') DEFAULT NULL,
  UNIQUE KEY `id` (`id`),
  KEY `ps_transports_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
# cat /etc/asterisk/sorcery.conf
[res_pjsip]
endpoint=realtime,ps_endpoints
auth=realtime,ps_auths
aor=realtime,ps_aors
domain_alias=realtime,ps_domain_aliases
contact=realtime,ps_contacts

[res_pjsip_endpoint_identifier_ip]
identify=realtime,ps_endpoint_id_ips
insert into ps_aors (id, max_contacts) values (403, 1);
insert into ps_aors (id, max_contacts) values (404, 1);
insert into ps_auths (id, auth_type, password, username) values (403, 'userpass', 'tpassword403', 403);
insert into ps_auths (id, auth_type, password, username) values (404, 'userpass', 'tpassword404', 404);
insert into ps_endpoints (id, transport, aors, auth, context, disallow, allow, direct_media) values (403, 'udp-transport-1', '403', '403', 'default', 'all', 'alaw', 'no');
insert into ps_endpoints (id, transport, aors, auth, context, disallow, allow, direct_media) values (404, 'udp-transport-1', '404', '404', 'default', 'all', 'alaw', 'no');

CHAN SIP

# cat chan_sip_realtime.sql
CREATE TABLE IF NOT EXISTS `sipfriends` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(10) NOT NULL,
      `ipaddr` varchar(15) DEFAULT NULL,
      `port` int(5) DEFAULT NULL,
      `regseconds` int(11) DEFAULT NULL,
      `defaultuser` varchar(10) DEFAULT NULL,
      `fullcontact` varchar(35) DEFAULT NULL,
      `regserver` varchar(20) DEFAULT NULL,
      `useragent` varchar(20) DEFAULT NULL,
      `lastms` int(11) DEFAULT NULL,
      `host` varchar(40) DEFAULT NULL,
      `type` enum('friend','user','peer') DEFAULT NULL,
      `context` varchar(40) DEFAULT NULL,
      `permit` varchar(40) DEFAULT NULL,
      `deny` varchar(40) DEFAULT NULL,
      `secret` varchar(40) DEFAULT NULL,
      `md5secret` varchar(40) DEFAULT NULL,
      `remotesecret` varchar(40) DEFAULT NULL,
      `transport` enum('udp','tcp','udp,tcp','tcp,udp') DEFAULT NULL,
      `dtmfmode` enum('rfc2833','info','shortinfo','inband','auto') DEFAULT NULL,
      `directmedia` enum('yes','no','nonat','update') DEFAULT NULL,
      `nat` enum('yes','no','never','route') DEFAULT NULL,
      `callgroup` varchar(40) DEFAULT NULL,
      `pickupgroup` varchar(40) DEFAULT NULL,
      `language` varchar(40) DEFAULT NULL,
      `allow` varchar(40) DEFAULT NULL,
      `disallow` varchar(40) DEFAULT NULL,
      `insecure` varchar(40) DEFAULT NULL,
      `trustrpid` enum('yes','no') DEFAULT NULL,
      `progressinband` enum('yes','no','never') DEFAULT NULL,
      `promiscredir` enum('yes','no') DEFAULT NULL,
      `useclientcode` enum('yes','no') DEFAULT NULL,
      `accountcode` varchar(40) DEFAULT NULL,
      `setvar` varchar(40) DEFAULT NULL,
      `callerid` varchar(40) DEFAULT NULL,
      `amaflags` varchar(40) DEFAULT NULL,
      `callcounter` enum('yes','no') DEFAULT NULL,
      `busylevel` int(11) DEFAULT NULL,
      `allowoverlap` enum('yes','no') DEFAULT NULL,
      `allowsubscribe` enum('yes','no') DEFAULT NULL,
      `videosupport` enum('yes','no') DEFAULT NULL,
      `maxcallbitrate` int(11) DEFAULT NULL,
      `rfc2833compensate` enum('yes','no') DEFAULT NULL,
      `mailbox` varchar(40) DEFAULT NULL,
      `session-timers` enum('accept','refuse','originate') DEFAULT NULL,
      `session-expires` int(11) DEFAULT NULL,
      `session-minse` int(11) DEFAULT NULL,
      `session-refresher` enum('uac','uas') DEFAULT NULL,
      `t38pt_usertpsource` varchar(40) DEFAULT NULL,
      `regexten` varchar(40) DEFAULT NULL,
      `fromdomain` varchar(40) DEFAULT NULL,
      `fromuser` varchar(40) DEFAULT NULL,
      `qualify` varchar(40) DEFAULT NULL,
      `defaultip` varchar(40) DEFAULT NULL,
      `rtptimeout` int(11) DEFAULT NULL,
      `rtpholdtimeout` int(11) DEFAULT NULL,
      `sendrpid` enum('yes','no') DEFAULT NULL,
      `outboundproxy` varchar(40) DEFAULT NULL,
      `callbackextension` varchar(40) DEFAULT NULL,
      `registertrying` enum('yes','no') DEFAULT NULL,
      `timert1` int(11) DEFAULT NULL,
      `timerb` int(11) DEFAULT NULL,
      `qualifyfreq` int(11) DEFAULT NULL,
      `constantssrc` enum('yes','no') DEFAULT NULL,
      `contactpermit` varchar(40) DEFAULT NULL,
      `contactdeny` varchar(40) DEFAULT NULL,
      `usereqphone` enum('yes','no') DEFAULT NULL,
      `textsupport` enum('yes','no') DEFAULT NULL,
      `faxdetect` enum('yes','no') DEFAULT NULL,
      `buggymwi` enum('yes','no') DEFAULT NULL,
      `auth` varchar(40) DEFAULT NULL,
      `fullname` varchar(40) DEFAULT NULL,
      `trunkname` varchar(40) DEFAULT NULL,
      `cid_number` varchar(40) DEFAULT NULL,
      `callingpres` enum('allowed_not_screened','allowed_passed_screen','allowed_failed_screen','allowed','prohib_not_screened','prohib_passed_screen','prohib_failed_screen','prohib') DEFAULT NULL,
      `mohinterpret` varchar(40) DEFAULT NULL,
      `mohsuggest` varchar(40) DEFAULT NULL,
      `parkinglot` varchar(40) DEFAULT NULL,
      `hasvoicemail` enum('yes','no') DEFAULT NULL,
      `subscribemwi` enum('yes','no') DEFAULT NULL,
      `vmexten` varchar(40) DEFAULT NULL,
      `autoframing` enum('yes','no') DEFAULT NULL,
      `rtpkeepalive` int(11) DEFAULT NULL,
      `call-limit` int(11) DEFAULT NULL,
      `g726nonstandard` enum('yes','no') DEFAULT NULL,
      `ignoresdpversion` enum('yes','no') DEFAULT NULL,
      `allowtransfer` enum('yes','no') DEFAULT NULL,
      `dynamic` enum('yes','no') DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `name` (`name`),
      KEY `ipaddr` (`ipaddr`,`port`),
      KEY `host` (`host`,`port`)
) ENGINE=MyISAM;
# mysql asterisk < chan_sip_realtime.sql

# mysql asterisk

MariaDB [asterisk]> delete from sipfriends;

insert into sipfriends(name, secret, host, type) values ('403', 'tpassword403', 'dynamic', 'friend');
insert into sipfriends(name, secret, host, type) values ('404', 'tpassword404', 'dynamic', 'friend');
# cat sip.conf
[general]
...
rtcachefriends=yes
rtcache=yes
...
# cat extensions.conf
...
exten => _5XX,1,Answer()
exten => _5XX,n,Set(row="${REALTIME(sippeers,name,4${EXTEN:1})}")
exten => _5XX,n,NoOp(ROW is ${row})
exten => _5XX,n,Set(col_name_pair=${CUT(row,",",1)})
exten => _5XX,n,NoOp(${col_name_pair})
exten => _5XX,n,Hangup()
...

Asterisk MySQL

Установка asterisk-mysql

debian# apt install asterisk-mysql

debian# service asterisk restart

# asterisk -x 'module show' | grep mysql

Asterisk MySQL CDR

# cat cdr_mysql.conf
[global]
hostname=localhost
user=asterisk
password=asterisk
dbname=asterisk
table=cdr

[columns]
alias start => calldate
# service asterisk restart

server*CLI> cdr show status
...
* Registered Backends
  -------------------
    mysql
...
server*CLI> cdr mysql status
...
Wrote NNN records ...

Asterisk MySQL realtime

# cat /etc/asterisk/res_config_mysql.conf
[general]
dbhost = 127.0.0.1
dbname = asterisk
dbuser = asterisk
dbpass = asterisk
# cat /etc/asterisk/extconfig.conf
[settings]
sippeers => mysql,general,sipfriends
server*CLI> core reload

server*CLI> realtime mysql status
general connected to asterisk@127.0.0.1, port 3306 with username asterisk for 12 seconds.

Asterisk MySQL dialplan

# apt install asterisk-mysql

# cat extensions.conf
...
exten => 312,1,Answer()
     same => n,MYSQL(Connect connid localhost asterisk asterisk asterisk)
;     same => n,MYSQL(Query resultid ${connid} SET NAMES 'utf8')
     same => n,MYSQL(Query resultid ${connid} SELECT name, fullname FROM sipfriends)
     same => n(loop),MYSQL(Fetch fetchid ${resultid} NM FN)
     same => n,GotoIf($[${fetchid} = 0]?clear)
     same => n,NoOp(fetchid ${fetchid} ${FN} ${NM})
     same => n,SayDigits(${NM})
;     same => n,Festival(${FN})
     same => n,Goto(312,loop)
     same => n(clear),MYSQL(Clear ${resultid})
     same => n,MYSQL(Disconnect ${connid})
     same => n,Hangup()
...
exten => _6XX,1,MYSQL(Connect connid localhost asterisk asterisk asterisk)
;     same => n,MYSQL(Query resultid ${connid} SET NAMES 'utf8')
     same => n,MYSQL(Query resultid ${connid} SELECT fullname FROM sipfriends where name="4${EXTEN:1}")
     same => n,MYSQL(Fetch fetchid ${resultid} FN)
     same => n,NoOp(fullname ${FN})
;     same => n,Festival(${FN})
     same => n,MYSQL(Clear ${resultid})
     same => n,MYSQL(Disconnect ${connid})
     same => n,Hangup()
...

Asterisk ODBC

Подключение Asterisk ODBC

  • !!! Не совместим с пакетом asterisk-mysql
# cat res_odbc.conf
[asterisk]
enabled => yes
dsn => asterisk
pre-connect => yes
server*CLI> core reload

server*CLI> odbc show all
ODBC DSN Settings
-----------------

  Name:   asterisk
  DSN:    asterisk_dsn
    Last connection attempt: 1970-01-01 03:00:00
    Number of active connections: 1 (out of 1)

Asterisk ODBC CDR

# cat cdr_adaptive_odbc.conf
[default]
connection=asterisk
table=cdr
# service asterisk restart

server*CLI> cdr show status

Asterisk ODBC realtime

# cat /etc/asterisk/modules.conf
...
;noload => res_config_odbc.so
...
# cat /etc/asterisk/extconfig.conf
[settings]
sippeers => odbc,asterisk,sipfriends

ps_endpoints => odbc,asterisk
ps_auths => odbc,asterisk
ps_aors => odbc,asterisk
ps_domain_aliases => odbc,asterisk
ps_endpoint_id_ips => odbc,asterisk
ps_contacts => odbc,asterisk

Asterisk ODBC функции

# cat func_odbc.conf
...
[SIPFRIENDS_BY_NAME]
dsn=asterisk
readsql=SELECT fullname FROM sipfriends where name='${ARG1}'
# cat extensions.conf
...
exten => _6XX,1,Set(FN=${ODBC_SIPFRIENDS_BY_NAME(4${EXTEN:1})})
        same => n,NoOp(fullname ${FN})
;     same => n,Festival(${FN})
...

Аутентификация и учет звонков в RADIUS

# cat /usr/share/auth.sh
#!/bin/sh

CALL_FROM=$1

# chown asterisk /tmp/auth.log

if echo "User-Name=${CALL_FROM},User-Password=${CALL_FROM},NAS-IP-Address=127.0.0.1" | radclient localhost auth testing123 >>/tmp/auth.log
then
        echo -n YES
else
        echo -n NO
fi

exit 0
# cat /usr/share/acct-start.sh
#!/bin/sh

CALL_ID=$1
CALL_FROM=$2
CALL_TO=$3

echo "User-Name=${CALL_FROM},Acct-Session-Id=${CALL_ID},Called-Station-Id=${CALL_TO},Calling-Station-Id=${CALL_FROM},Acct-Status-Type=Start,NAS-IP-Address=127.0.0.1,NAS-Port=${CALL_FROM}${CALL_TO}"| radclient localhost acct testing123

exit 0
# cat /usr/share/acct-stop.sh
#!/bin/sh

CALL_ID=$1
CALL_FROM=$2
CALL_TO=$3

echo "User-Name=${CALL_FROM},Acct-Session-Id=${CALL_ID},Acct-Status-Type=Stop,NAS-IP-Address=127.0.0.1,NAS-Port=${CALL_FROM}${CALL_TO}"| radclient localhost acct testing123

exit 0

Примечания:

  • Помещаем абонента, звонки которого надо тарифицировать, в контекст billing
  • Переводим все тарифицируемые вызовы в контекст aaa-call (что-бы отследить событие окончания разговора через контекст «h»)
  • В случае MYAUTH!=NO разрешаем абоненту совершить звонок. С помощью макроса «U» программируем вызов кода в момент снятия трубки для начала тарификации. По какой то причине переменные ${CALLERID(num)} ${CALLERID(dnid)} не передаются, а ${UNIQUEID} меняет значение в этом коде, поэтому занчения передаются через аргументы.
  • В контексте «h» проверяем факт наличия разговора и только в этом случае тарифицируем его окончание
# cat extensions.conf
...
[billing]
...
exten => _4XX,1,Goto(aaa-call,s,1)
...
[aaa-call]
exten => s,1,Verbose(AUTH CALL_ID=${UNIQUEID} CALL_FROM=${CALLERID(num)} CALL_TO=${CALLERID(dnid)})
exten => s,n,Set(MYAUTH=${SHELL(/usr/share/auth.sh ${CALLERID(num)})});
exten => s,n,GotoIf($["${MYAUTH}" = "NO"]?end_call)
exten => s,n,Dial(SIP/${CALLERID(dnid)},,U(aaa-call-beg-acct,${UNIQUEID},${CALLERID(num)},${CALLERID(dnid)}));
exten => s,n(end_call),Hangup()

exten => h,1,GotoIf($["${DIALSTATUS}" != "ANSWER"]?no-answer)
exten => h,n,Verbose(END ACCT DIALSTATUS=${DIALSTATUS} CALL_ID=${UNIQUEID} CALL_FROM=${CALLERID(num)} CALL_TO=${CALLERID(dnid)})
exten => h,n,System(/usr/share/acct-stop.sh ${UNIQUEID} ${CALLERID(num)} ${CALLERID(dnid)})
exten => h,n(no-answer),NoOp()

[aaa-call-beg-acct]
exten => s,1,Verbose(BEGIN ACCT CALL_ID=${ARG1} CALL_FROM=${ARG2} CALL_TO=${ARG3})
exten => s,n,System(/usr/share/acct-start.sh ${ARG1} ${ARG2} ${ARG3})
exten => s,n,return
...

Настройка дополнительных видов обслуживания

Базовая конфигурация

Настройка прохождения трафика и сигнализации через asterisk и режима тонального набора для всех каналов

server# cat sip.conf
[general]
...
directmedia=no ;1.6
canreinvite=no ;1.4
dtmfmode=rfc2833
...

Перевод вызова на другого абонента

  • С сопровождение и слепой
  • Клавиша «flash» аналогового телефона
  • Кнопка «transfer» ip телефона
  • Программируемая комбинация DTMF
server# cat features.conf
[general]
...
featuredigittimeout = 1000
...
[featuremap]
...
blindxfer => *21
atxfer => *22
...
server# cat extensions.conf
...
exten => _4XX,1,Dial(SIP/${EXTEN},,Tt)
...
exten => voip1_00000X,1,Dial(SIP/403,10,t)
exten => voip1_00000X,n,Dial(SIP/401&SIP/402&SIP/403,,t)
server*CLI> core reload

server*CLI> features show

Мониторинг текущего состояния абонента (BLF)

Настройка asterisk

# cat sip.conf
[general]
...
allowsubscribe=yes
notifyhold=yes
callcounter=yes
notifyringing=yes
limitonpeers=yes
subscribecontext=default
...
# cat extensions.conf
[default]
...
exten => _4XX,hint,SIP/${EXTEN}
...

Настройка телефонов

Мониторинг

server*CLI> sip show subscriptions

server*CLI> core show hints

Перехват вызова

server# cat sip.conf
...
[401]
callgroup=1
pickupgroup=1
...
[403]
callgroup=1
pickupgroup=1
server# cat features.conf
...
[general]
...
pickupexten = *88
...
server*CLI> features show

Парковка разговора

Сценарий: снимаем трубку чужого, звонящего телефона, просим подождать, набираем *21700, слушаем номер слота, кладем трубку. Со своего телефона набираем номер слота и продолжаем разговор.

asterisk11# less features.conf

asterisk13# less res_parking.conf
...
[default]
parkext => 700
parkpos => 701-720
...
context => parkedcalls
...
server# cat extensions.conf
[default]

include => parkedcalls
...

Локализация сообщений Asterisk

Кодеки

*CLI> core show codecs

*CLI> core show translation

Установка из пакетов

root@server:~# apt install asterisk-core-sounds-ru-wav

root@server:~# find /usr/share/asterisk/sounds/ru/

Установка с сайта

server# cd /usr/share/asterisk/sounds

server# mkdir ru; cd ru/

server# wget http://downloads.asterisk.org/pub/telephony/sounds/asterisk-core-sounds-ru-alaw-current.tar.gz

server# tar -xvf asterisk-core-sounds-ru-alaw-current.tar.gz

Настройка локализации

server# cat asterisk.conf
...
[options]
...
defaultlanguage = ru
...
# service asterisk restart
server# cat sip.conf
[general]
language=ru
...
[401]
language=ru
...
server# cat extensions.conf
...
exten => 301,1,Answer()
exten => 301,n,Playback(hello-world)
exten => 301,n,Set(CHANNEL(language)=en)
exten => 301,n,Playback(hello-world)
exten => 301,n,Hangup()
...

Голосовая почта

server# cat voicemail.conf
[general]

...

;For IMAP/SMTP
;charset=UTF-8
;locale=ru_RU.UTF-8
;emailsubject=Голосовое сообщение от абонента ${VM_CALLERID}
;emailbody=Здравствуйте ${VM_NAME}\n\n${VM_DATE} получено голосовое сообщение от абонента ${VM_CALLERID}
;emaildateformat=%A, %B %d, %Y в %r

...

;For IMAP
;debian# apt install asterisk-voicemail-imapstorage
;debian# service asterisk restart
;imapserver=mail.isp.un
;imapfolder=INBOX

;For SMTP
;debian# apt install postfix mailutils

...

[corpX]
;401 => ,,
;402 => 2222,,
;403 => ,Ваше Имя Отчество Фамилия,userX@isp.un,,attache=yes|delete=yes
;404 => 4444,Ваше Имя Отчество Фамилия,,,imapuser=userX|imappassword=passwordX
server*CLI> voicemail reload
server# cat extensions.conf
[default]
...
exten => 390,1,VoiceMailMain(@corpX)
...
exten => _4XX,1,Dial(SIP/${EXTEN},10,Tt)
exten => _4XX,n,VoiceMail(${EXTEN}@corpX)
exten => _4XX,n,Hangup()

...

Альтернативный dialplan для прослушивания голосовой почты (звонок на номер своего телефона)

exten => _4XX,1,GotoIf($["${CALLERID(num)}" = "${EXTEN}"]?MAIL)
exten => _4XX,n,Macro(monitor)
exten => _4XX,n,Dial(SIP/${EXTEN},10)
exten => _4XX,n,VoiceMail(${EXTEN}@corpX)
exten => _4XX,n,Hangup()

exten => _4XX,n(MAIL),VoiceMailMain(${EXTEN}@corpX)
exten => _4XX,n,Hangup()
server# cat sip.conf
...
[401]
;allowsubscribe=no
mailbox=401@corpX
...
[402]
mailbox=402@corpX
...
[403]
mailbox=403@corpX
...
[404]
mailbox=404@corpX
...
server# ls /var/spool/asterisk/voicemail/corpX/

server# ls -l /var/mail/

Конференц связь

Настройка

  • Сценарий 1: все желающие участвовать в конференции звонят на заранее обговоренный номер 6NN
  • Сценарий 2: ответственный за проведение конференции обзванивает участников и переводит вызовы в конференцию набирая *216NN
  • Сценарий 3: ответственный звонит на номер 389, у участников 401 и 403 звонят телефоны и ответственный тоже становится участником конференции.
server# cat extensions.conf
[default]
...
exten => 389/402,1,Originate(SIP/401,exten,default,601,1)
exten => 389/402,n,Originate(SIP/403,exten,default,601,1)
exten => 389/402,n,ConfBridge(601)

exten => _6XX,1,ConfBridge(${EXTEN})
...

Отладка

server# asterisk -x "confbridge list 601"
...

Организация обратных вызовов

Из командной строки

# asterisk -x "channel originate SIP/403 extension 301@default"

; сначала вызов телефона оператора, затем вызов абонента
server*CLI> channel originate SIP/403 extension 89161234567@default

; сначала вызов абонента, затем телефона оператора 
server*CLI> channel originate SIP/voip1_00000X/89161234567 extension 403@default

; сначала вызов обработчика входящих вызовов (секретарь, IVR, Queue), затем вызов абонента
server*CLI> channel originate Local/voip1_00000X@default extension 89161234567@default

С использованием Call файлов

server# cat /usr/share/403.call
Channel: sip/403
Context: default
Extension: 601
CallerId: Conferencia <601>
server# cat /usr/share/401.call
Channel: sip/401
Context: default
Extension: 601
CallerId: Conferencia <601>
server# cat /usr/share/start_conference.sh
#!/bin/sh

cp /usr/share/4* /tmp
chown asterisk /tmp/4*
mv /tmp/4* /var/spool/asterisk/outgoing/
server# chmod +x /usr/share/start_conference.sh

server# /usr/share/start_conference.sh

Пример с использованием Asterisk AMI

Пример с использованием Asterisk ARI

# curl -v -X POST "http://localhost:8088/ari/channels?endpoint=SIP%2F401&extension=301&context=default&callerId=301&api_key=asterisk:asterisk"

или

# curl -v -u asterisk:asterisk -X POST "http://localhost:8088/ari/channels?endpoint=SIP%2F401&extension=301&context=default&callerId=301"

Интерактивное голосовое меню IVR

Реализация с использованием стандартного языка описания диалплана

sever# cat extensions.conf
[default]
...
exten => 302,1,Authenticate(1234)
exten => 302,n,Playback(vm-intro)
exten => 302,n,Record(recordings/speech.alaw,,,xk)
exten => 302,n,Hangup()

exten => 303,1,Answer()
exten => 303,n,Playback(beep)
exten => 303,n,Playback(recordings/speech)
exten => 303,n,Playback(beep)
exten => 303,n,Hangup()

exten => 304,1,Goto(menu,s,1) ; for debug
...
;[incoming]
exten => voip1_00000X,1,Goto(menu,s,1)
...
[menu]
exten => s,1,Background(recordings/speech)
exten => s,2,Goto(s,1)
 
; exten => 1,1,Dial(SIP/401)
; exten => 2,1,Dial(SIP/402)
; exten => 3,1,Dial(SIP/403)
; exten => 4,1,Dial(SIP/404)
; exten => _X,1,Dial(SIP/40${EXTEN})

exten => _X,1,Goto(default,40${EXTEN},1)

;exten => 0,1,Goto(menu2,s,1)
;exten => 0,1,DISA(no-password,default)

;exten => _[34]XX,1,Goto(default,${EXTEN},1)
;exten => _[43]XX,1,Dial(Local/{EXTEN}@default)
 
;exten => t,1,Goto(s,1)  ; timeout exceeded
;exten => i,1,Goto(s,1)  ; error extensions

;[menu2]
;exten => s,1,WaitExten(8)
;exten => _XXX,1,Goto(default,${EXTEN},1)

Реализация с использованием AEL

sever# cat extensions.conf
[default]
...
include => ivr
...
;[incoming]
exten => voip1_00000X,1,Goto(menu,s,1)
sever# cat extensions.ael
context ivr {
  302 => {
    Answer();
    Record(recordings/speech:alaw);
    Hangup();
  }
  303 => {
    Answer();
    Playback(beep);
    Playback(recordings/speech);
    Playback(beep);
    Hangup();
  }
  304 => {
    goto menu|s|begin;
  }
}

context menu {
  s => {
    begin:
      Background(recordings/speech);
      goto begin;
  }
  _X => {
     goto default|40${EXTEN}|1;
  }
}

Прослушивание разговоров

server# cat extensions.conf
[default]
...
exten => _5XX/402,1,ChanSpy(SIP/4${EXTEN:1})
...

Запись разговоров

Запись по желанию абонента

server# cat features.conf
...
[featuremap]
...
automon => *11
...
server# cat extensions.conf
...
exten => _4XX,1,Set(TOUCH_MONITOR=${STRFTIME(${EPOCH},,%Y%m%d%H%M)}-${CALLERID(number)}-${EXTEN})
exten => _4XX,n,Dial(SIP/${EXTEN},,Ww)
...
server*CLI> core reload

server# ls /var/spool/asterisk/monitor/

Автоматическая запись средствами Asterisk

server# cat extensions.conf
...
[menu]
...
exten => _X,1,Set(MY-FILE-NAME=${STRFTIME(${EPOCH},,%Y%m%d%H%M)}-${CALLERID(number)}-40${EXTEN}.wav)
exten => _X,n,MixMonitor(${MY-FILE-NAME},b)
exten => _X,n,Goto(default,40${EXTEN},1)
...
server*CLI> dialplan reload

server# ls /var/spool/asterisk/monitor/

Автоматическая запись путем анализа трафика

MOH

Добавление своих звуковых файлов

[server:~] # rm /usr/local/share/asterisk/moh/*
[server:~] # cp Knockin_on_Heavens_Door.raw /usr/local/share/asterisk/moh/

root@server:~# rm /usr/share/asterisk/moh/*
root@server:~# cp Knockin_on_Heavens_Door.raw /usr/share/asterisk/moh/

server*CLI> moh reload

server*CLI> moh show files

server# cat extensions.conf
...
exten => 305,1,Answer()
exten => 305,n,MusicOnHold()
...

Добавление своих классов

server# mkdir /usr/share/asterisk/busy

server# cp -v /usr/share/asterisk/sounds/ru/tt-allbusy.* /usr/share/asterisk/busy/

server# cat musiconhold.conf
...
[busy]
mode=files
directory=busy
server# cat extensions.conf
...
exten => ABC,1,Answer()
exten => ABC,n,Dial(SIP/ABC,,m(busy))
...

Синтез речи с использованием пакета Festival

# asterisk -x 'module show' | grep fest

server# cat extensions.conf
...
exten => 303,1,Answer()
exten => 303,n,Festival('Привет Мир')
exten => 303,n,Hangup()

exten => 304,1,Answer()
exten => 304,n,Set(foo=${FILE(/tmp/text.txt)})
exten => 304,n,Festival(${foo})
exten => 304,n,Hangup()

exten => 305,1,Answer()
;linux   exten => 305,n,Set(foo=${SHELL(uptime | sed -E 's/.* (.*), .*, .*$/\1/' | sed 's/,/ запятая /g')})
exten => 305,n,Festival(${foo})
exten => 305,n,Hangup()
...
exten => _4XX,1,Dial(SIP/${EXTEN},10)
exten => _4XX,n,Set(MY-CALLED-USER-NAME=${ODBC_SIPFRIENDS_BY_NAME(${EXTEN})})
exten => _4XX,n,Festival(${MY-CALLED-USER-NAME} не может ответить)

Переадресация вызовов на внешний номер

Использование FollowMe

server# cat followme.conf
[101+X]
;number=>401,30
;number=>89162323232,30
context=>default
[401]
number=>89162323232,30
;number=>89163434345,30
context=>default
server# cat extensions.conf
;...
exten => _4XX,1,Dial(SIP/${EXTEN},10,t)
exten => _4XX,n,FollowMe(${EXTEN})

Использование MySQL

Использование AstDB

AstDB

server*CLI> database show

Использование AstDB для связи номеров и учетных записей

server*CLI> database put num2login 401 user1

server*CLI> database put num2login 402 user2

server*CLI> database put num2login 403 user3

server*CLI> database num2login
# cat extensions.conf
exten => _[a-z].,1,Dial(SIP/${EXTEN})

exten => _4XX,1,Set(MY-LOGIN=${DB(num2login/${EXTEN})})
exten => _4XX,n,NoOp(variable MY-LOGIN set to ${MY-LOGIN})
exten => _4XX,n,Verbose(1,variable MY-LOGIN set to ${MY-LOGIN})
exten => _4XX,n,Dial(SIP/${MY-LOGIN})

Использование AstDB для перенаправления вызовов

server*CLI> database put redirect 403 89166071103

server*CLI> database get redirect 403

server*CLI> database show redirect

server*CLI> database del redirect 403
server# cat extensions.conf
...
[default]
...
exten => 308,1,Answer()
exten => 308,n,Goto(setredirect,s,1)

exten => 309,1,Answer()
exten => 309,n,Playback(beep)
exten => 309,n,NoOp(${DB_DELETE(redirect/${CALLERID(num)})})
exten => 309,n,Hangup()
...
exten => _4XX,1,Dial(SIP/${EXTEN},10,t)

exten => _4XX,n,Set(MY-REDIRNUM=${DB(redirect/${EXTEN})})
exten => _4XX,n,GotoIf($[${LEN(${MY-REDIRNUM})} > 0]?CALLMOBILE)
...
exten => _4XX,n(CALLMOBILE),Goto(default,${MY-REDIRNUM},1)
...
[setredirect]
exten => s,1,Playback(beep)
exten => s,n,WaitExten()
exten => _8XXXXXXXXXX,1,Set(DB(redirect/${CALLERID(num)})=${EXTEN})
exten => _8XXXXXXXXXX,n,Playback(beep)
exten => _8XXXXXXXXXX,n,SayDigits(${EXTEN})
exten => _8XXXXXXXXXX,n,Playback(beep)
exten => _8XXXXXXXXXX,n,Hangup()

Подсчет количества одновременных вызовов абонента

С использованием функции SIPPEER

  • curcalls работает только если для канала установлено ограничение на число одновременных вызовов (call-limit)
server*CLI> core show function SIPPEER
exten => _4XX,1,Set(MY-CALLS-COUNT=${SIPPEER(${EXTEN},curcalls)})
exten => _4XX,n,Verbose(2,*** MY-CALLS-COUNT = ${MY-CALLS-COUNT} ***)
exten => _4XX,n,ExecIf($[ ${MY-CALLS-COUNT} > 0 ]?Set(MY-CLASS-MOH=busy))
exten => _4XX,n,Dial(SIP/${EXTEN},,tTm(${MY-CLASS-MOH}))

С использованием GROUP_COUNT

exten => _4XX,1,Set(GROUP(MYCALLTO)=${EXTEN})
exten => _4XX,n,Set(MYCALLS=${GROUP_COUNT(${GROUP(MYCALLTO)})})
exten => _4XX,n,Verbose(2,*** ${MYCALLS} ***)
exten => _4XX,n,ExecIf($[ ${MYCALLS} > 1 ]?Set(MYCLASSMOH=busy))
exten => _4XX,n,Verbose(2,(*** ${MYCLASSMOH} ***)
exten => _4XX,n,Dial(SIP/${EXTEN},10,Ttm(${MYCLASSMOH}))

Обработка статуса вызова

[default]

exten => _X!,1,Goto(pbx-invalid,s,1)
...
exten => _4XX,1,Dial(SIP/${EXTEN})
exten => _4XX,n,Verbose(1,${DIALSTATUS})
exten => _4XX,n,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL"]?pbx-invalid,s,1)
...
[pbx-invalid]
exten => s,1,Playback(pbx-invalid)

Абдирахимов Мансур представил решение «Vip звонок» - определенный номер при звонке на офисный телефон соединялся с определенным номером даже если последний разговаривает.

[office]

...
exten => s,n,Gotoif($["${CALLERID(num)}"="9259280996"]?delta,s,1)
...

[delta];Звонок от Директора
exten => s,1,Playback(priv-trying)
exten => s,n,ExecIf($["${DIALSTATUS}"="${BUSY}"]?Bridge(SIP/854))
exten => s,n,Dial(SIP/854)

Организация Call центра

Автоматизация распределения вызовов ACD

Организация очередей

server# cat queues.conf
[general]
persistentmembers = yes

[queue1]
member => SIP/403 ;установить call-limit=1 для linksys
sever# cat extensions.conf
...
;[incoming]
exten => voip1_00000X,1,Answer()
exten => voip1_00000X,n,Queue(queue1)
...

Регистрация агентов

asterisk# agents.conf
[general]

[801]
fullname=Ivan Ivanovitch Ivanov
[802]
fullname=Petr Petrovitch Petrov
[803]
fullname=Your name
asterisk# cat extensions.conf
[default]
...
exten => _8XX,1,AgentLogin(${EXTEN})
...
[agents]
exten => _8XX,1,AgentRequest(${EXTEN})
     same => n,Hangup()

Использование агентов в очередях

asterisk# cat queues.conf
[general]
persistentmembers = yes

[queue1]
strategy=rrmemory
member => Local/801@agents
member => Local/802@agents
member => Local/803@agents
server*CLI> queue show queue1

server*CLI> agent show online

Интерфейсы взаимодействия с внешними программами

Приложение System

server# cat extensions.conf
[default]
...
exten => 398,1,Authenticate(1234)
exten => 398,n,System(/usr/bin/sudo /sbin/init 6)
...

Приложение SHELL

# mkdir /var/www/html/asterisk/

# cat /var/www/html/asterisk/addrbook.txt
Иван Иванов<+74951234561>
Петр Петров<+74951234562>
# cat /usr/local/bin/get-customer-callerid-all.sh
#!/bin/sh

PHONE=$1

ADDR_BOOK=/var/www/html/asterisk/addrbook.txt

grep $PHONE $ADDR_BOOK || echo $PHONE
# cat /etc/asterisk/extensions.conf
...
exten => _4XX,n,ExecIf($["${CALLERID(name)}"=""]?Set(CALLERID(all)=${SHELL(/usr/local/bin/get-customer-callerid-all.sh ${CALLERID(num)})}))
...

Asterisk AGI

Пример на SHELL

# cat /usr/share/asterisk/agi-bin/multi_playback.sh
#!/bin/sh

LOG=/tmp/multi_playback.log
SAMPLE_COUNT=0

:>$LOG

while read ARG && [ "$ARG" ]
do
        echo $ARG >> $LOG
        if echo $ARG | grep -q 'agi_arg_'
        then
                SAMPLE_NAME=`echo $ARG | sed -E 's/.*: (.*)$/\1/'`
                echo EXEC Playback $SAMPLE_NAME
                SAMPLE_COUNT=$(($SAMPLE_COUNT+1))
        fi
done

echo SET VARIABLE SAMPLE-COUNT $SAMPLE_COUNT

exit 0
# cat extensions.conf
...
exten => 313,1,AGI(multi_playback.sh,beep,hello-world,beep)
exten => 313,n,Verbose(1,SAMPLE-COUNT ${SAMPLE-COUNT})
exten => 313,n,Hangup()
...

Пример на PHP

# cd /usr/local/

# wget http://val.bmstu.ru/unix/voip/phpagi-2.20.tgz

# tar -xvf phpagi-2.20.tgz

# cat /usr/share/asterisk/agi-bin/example.php
#!/usr/bin/php
<?php
require('/usr/local/phpagi-2.20/phpagi.php');

$agi = new AGI();

$agi->answer();

$agi->stream_file("hello-world");

$agi->hangup();
?>

Asterisk AMI

# cat manager.conf
[general]
enabled = yes
port = 5038
;bindaddr = 127.0.0.1
;bindaddr = 0.0.0.0

#include "manager.d/*.conf"
# cat manager.d/admin.conf
[admin]
secret = admin
read = all
write = all
# asterisk -rx "module reload manager"

# asterisk -rx "manager show connected"

# asterisk -rx "manager show commands"

# telnet 127.0.0.1 5038
Action: Login
ActionID: 1
Username: admin
Secret: admin

Action: Originate
Channel: sip/403
Context: default
Exten: 301
Callerid: 301
Priority: 1

Action: Logoff

Asterisk ARI

Настройка доступа к ARI

# cat /etc/asterisk/http.conf
[general]
enabled=yes
;bindaddr=127.0.0.1
;bindaddr=0.0.0.0
bindport=8088
# cat /etc/asterisk/ari.conf
[general]
enabled = yes
pretty = yes
;allowed_origins = http://ari.asterisk.org
;allowed_origins = chrome-extension://hlnmjkbpmnbgeondjeceaomhafdacmlj

[asterisk]
type = user
read_only = no
password = asterisk

Управление Asterisk через ARI

# curl http://localhost:8088/ari/endpoints?api_key=asterisk:asterisk

Мониторинг Asterisk через ARI

debian9# curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -

# apt install -y nodejs npm

# npm install -g wscat

# wscat -c "ws://localhost:8088/ari/events?api_key=asterisk:asterisk&app=my-first-app" 
*CLI> ari show apps

# curl -v -u asterisk:asterisk -X POST "http://localhost:8088/ari/applications/my-first-app/subscription?eventSource=endpoint%3ASIP"

*CLI> ari show app my-first-app

ARI Stasis

exten => 307,1,Answer()
exten => 307,n,Stasis(my-first-app)
exten => 307,n,Hangup()
# curl -v -u asterisk:asterisk -X GET "http://localhost:8088/ari/channels"
...
    "id": "1513594816.47",
...
# ID=1513594816.47

# curl -v -u asterisk:asterisk -X POST "http://localhost:8088/ari/channels/$ID/play?media=sound:hello-world"

# curl -v -u asterisk:asterisk -X POST "http://localhost:8088/ari/channels/$ID/redirect?endpoint=SIP%2F403"

XMPP

!!! При использовании GSSAPI надо добавить метод PALIN

# asterisk -x 'module show' | grep xmpp

# cat xmpp.conf
[general]
debug=no

[aster]
type=client
serverhost=server.corpX.un
;username=administrator@corpX.un
;username=admin@corpX.un
secret=Pa$$w0rd
port=5222
;usetls=yes
;usetls=no
*CLI> module reload res_xmpp

*CLI> xmpp show connections

*CLI> xmpp show buddies
# cat extensions.conf
[default]
...
exten => 306,1,Answer()
exten => 306,n,JabberSend(aster,user3@corpX.un,Hello World)
exten => 306,n,Hangup()
...

;exten => _4XX,1,Set(MY-CALLED-USER-ID=${SIPPEER(${EXTEN},chanvar[MY-USER-ID])})
;exten => _4XX,1,Set(MY-CALLED-USER-ID=${PJSIP_ENDPOINT(${EXTEN},MY-USER-ID)})

exten => _4XX,n,Set(MY-CALLED-USER-STATUS=${JABBER_STATUS(aster,${MY-CALLED-USER-ID}/Spark)})

exten => _4XX,n,GotoIf($[${MY-CALLED-USER-STATUS} > 2]?busy)

exten => _4XX,n,JabberSend(aster,${MY-CALLED-USER-ID},Вам звонит ${CALLERID(all)})

;exten => _4XX,n,Dial(SIP/${EXTEN})
;exten => _4XX,n,Dial(PJSIP/${EXTEN})
exten => _4XX,n,Hangup()

exten => _4XX,n(busy),Playback(tt-allbusy)
exten => _4XX,n,Hangup()
...

Интеграция с Microsoft AD и LDAP

Выгружаем данные из Microsoft AD через LDAP

# apt install ldap-utils

# cat /root/create_exten_mail_cidname_table.sh
#!/bin/sh

IFS=' '

ldapsearch -x -D "cn=Administrator,cn=Users,dc=corp15,dc=un" -w 'Pa$$w0rd' -H ldap://ad.corp15.un -b "dc=corp15,dc=un" "(telephoneNumber=4*)" cn telephoneNumber mail \
| perl -p00e 's/\r?\n //g' |
while read s
do
        echo $s | grep -vq '^dn:' && continue
        read fn cn
        echo $fn | grep -q '::' && cn=`echo $cn | base64 -d`
        read fn tn
        read fn email
        echo $tn $email $cn
done
# /root/create_exten_mail_cidname_table.sh | tee exten_mail_cidname_table.txt
401 user1@corp15.un Иван Иванович Иванов
402 user2@corp15.un Петр Петрович Петров
403 user3@corp15.un Сидор Сидорович Сидоров
404 user4@corp15.un Василий Муркович Кошкин

Добавляем исходные данные для Provisioning

Создаем файл конфигурации CHAN SIP

# cat /root/create_ast_users_conf.sh
#!/bin/sh

IFS=' '

cat $1|
while read exten mail name
do
        echo "[$exten]"
        echo "type=friend"
        echo "fullname=$name"
        echo "setvar=MY-USER-ID=$mail"
        secret=`cat $2 | grep "^$exten" | cut -d' ' -f2`
        echo "secret=$secret"
        echo "host=dynamic"
        echo
done
# /root/create_ast_users_conf.sh exten_mail_cidname_table.txt exten_secret_proxy_mac_model_table.txt | tee /etc/asterisk/users.conf
[401]
type=friend
fullname=Иван Иванович Иванов
setvar=MY-USER-ID=user1@corp15.un
secret=tpassword401
host=dynamic
...
# cat /etc/asterisk/sip.conf
[general]
...
#include "/etc/asterisk/users.conf"
...

Создаем файл конфигурации PJSIP

# cat create_ast_pjsip_wizard.sh
#!/bin/sh

IFS=' '

cat $1|
while read exten mail name
do
        password=`cat $2 | grep "^$exten" | cut -d' ' -f2`
        echo "[$exten]"
        echo "type=wizard"
        echo "accepts_auth=yes"
        echo "accepts_registrations=yes"
        echo "transport=udp-transport-1"
        echo "inbound_auth/username=$exten"
        echo "inbound_auth/password=$password"
        echo "endpoint/allow=alaw"
        echo "endpoint/context=default"
        echo "endpoint/set_var=MY-USER-ID=$mail"
        echo "endpoint/callerid=${name}<${exten}>"
        echo "aor/max_contacts=1"
        echo "aor/remove_existing=yes"
        echo
done
# /root/create_ast_pjsip_wizard.sh exten_mail_cidname_table.txt exten_secret_proxy_mac_model_table.txt | tee /etc/asterisk/pjsip_wizard.conf

# service asterisk restart

Использование sourceforge asterisk AD perl scripts

  • из AD берутся номера телефонов и ФИО
  • secret для SIP телефонов задается ст статически в sip.conf
# apt install libnet-ldap-perl

# cat users.pl
...
$ADcontroller="ad.corp15.un";
$ADDC="DC=corp15,DC=un";
$ADuser="Administrator";
$ADpass='Pa$$w0rd';
$dialplan="default";
...
# /root/users.pl > /etc/asterisk/users.conf

# cat /etc/asterisk/users.conf
[401]
cid_number = 401
fullname = Ivan I. Ivanov
type = peer

[402]
...
# cat /etc/asterisk/sip.conf
[general]
...
#include "/etc/asterisk/users.conf"

[401]
secret=tpassword401
type=user
host=dynamic

[402]
...

Provisioning

# cat exten_secret_proxy_mac_model_table.txt
401 tpassword401 server.corpX.un 000000000000 Softphone
402 tpassword402 server.corpX.un 000000000000 Softphone
403 tpassword403 server.corpX.un 000E08C190C2 SPA3102
404 tpassword404 server.corpX.un BCC34221709A KX-HDVXXX
...
403 tpassword403 server.corp8.un 000E08C190A2 SPA3102
403 tpassword403 server.corp6.un BCC34221709A KX-HDVXXX
403 tpassword403 server.corp3.un 080023F67118 KX-HDVXXX
403 tpassword403 server.corp1.un 000E08C190A8 SPA3102
403 tpassword403 server.corp4.un 000E08C190B6 SPA3102
403 tpassword403 server.corp2.un BCC3422170AA KX-HDVXXX
403 tpassword403 server.corp7.un 080023E421CD KX-HDVXXX
403 tpassword403 server.corp5.un 000E08C190C2 SPA3102
403 tpassword403 server.corp9.un 000E08C38F1D SPA3102
403 tpassword403 server.corp10.un 080023BF61CD KX-HDVXXX
403 tpassword403 server.corp11.un 000E08C389BF SPA3102
403 tpassword403 server.corp12.un 080023BF61CC KX-HDVXXX
# cat create_prov_phones_conf.sh
#!/bin/sh

wwwdir=/var/www/html/

while read pn secret sipproxy mac model
do
        if [ "$model" = KX-HDVXXX ]
        then
#               echo $pn $secret $mac $model
                cat > ${wwwdir}kx-hdv-$mac.cfg <<FIN
# Panasonic SIP Phone Standard Format File #

## SIP Settings
PHONE_NUMBER_1="$pn"
SIP_AUTHID_1="$pn"
SIP_PASS_1="$secret"
SIP_PRXY_ADDR_1="$sipproxy"
SIP_RGSTR_ADDR_1="$sipproxy"
DIAL_PLAN_1="*xx|[1-4]xx|0xxxxx|8xxxxxxxxxx"

FIN
        elif [ "$model" = SPA3102 ]
        then
#               echo $pn $secret $mac $model
                cat > ${wwwdir}spa-$mac.cfg <<FIN
<flat-profile>
  <Proxy_1_>$sipproxy</Proxy_1_>
  <User_ID_1_>$pn</User_ID_1_>
  <Password_1_>$secret</Password_1_>
  <Dial_Plan_1_>( xxx | 8xxxxxxxxxx | 0xxxxx | *xx )</Dial_Plan_1_>
</flat-profile>

FIN
        fi
done
# /root/create_prov_phones_conf.sh < exten_secret_proxy_mac_model_table.txt

# ls /var/www/html/

Интеграция с CRM

Безопасность Asterisk

Поддерживаемые версии

Список проблем безопасности

Использование TLS

server# cat server.crt server.key > /etc/asterisk/server.crtkey

server# cat sip.conf
[general]
...
tlsenable=yes
tlsbindaddr=0.0.0.0:5061
tlscertfile=/etc/asterisk/server.crtkey
; tlscafile=/var/www/html/ca.crt ;need if use clietns certs
tlscipher=ALL
tlsclientmethod=tlsv1
tlsdontverifyserver=no
...
[402]
...
transport=tls
encryption=yes
...
# service asterisk restart

Сокрытие версии

# cat sip.conf
[general]
...
useragent=Microsoft Lync
...

Использование хешей паролей для каналов типа user

http://www.voip-info.org/wiki/view/Asterisk+sip+md5secret

server# echo -n "402:corp:tpassword402" | md5sum

server# cat sip.conf
[general]
...
realm=corp
...
[402]
;secret=tpassword402
md5secret=29c91aa064cf462f5146b7ee81e7ba49
...

Зашита от несанкционированного использования

WebRTC

Настройка сервера

# cat server.crt server.key > /etc/asterisk/server.crtkey

# cat /etc/asterisk/http.conf
[general]
enabled=yes
bindaddr=0.0.0.0
bindport=8088
tlsenable=yes
tlsbindaddr=0.0.0.0:8089
tlscertfile=/etc/asterisk/server.crtkey
# cat /etc/asterisk/sip.conf
[general]
transport=udp,wss
...

[webrtc](!)
avpf = yes
force_avp = yes
icesupport = yes
encryption = yes
dtlsenable = yes
dtlsverify = no
dtlssetup = actpass
dtlscertfile = /etc/asterisk/server.crtkey

[401](webrtc)
...

!!! Проверить и принять сертификат

https://server.corpX.un:8089/ws

Настройка клиента sipml5

Display Name: 401
Private Identity*: 401
Public Identity*: sip:401@server.corpX.un
Password: tpassword401
Realm*: server.corpX.un
WebSocket Server URL: wss://server.corpX.un:8089/ws
ICE Servers: []

Установка клиента sipml5

# cd /var/www/html/

# wget http://val.bmstu.ru/unix/voip/sipml5-master.zip

# unzip sipml5-master.zip

https://server.corpX.un/sipml5-master/call.htm

Дополнительные материалы

Распознавание речи в Asterisk с использованием Yandex SpeechKit HTTP API

https://habr.com/post/225179/ 

key=f609cf87-d8a9-48c3-b11b-e20054ec3bb3

Можно использовать для Raspberry -  arecord aplay 
plughw:1,0 - где 1 микрофон USB камеры - видно в cat /proc/asound/cards

#!/usr/bin/php
<?php
system("arecord --buffer-time=1000000 -f dat -r 16000 -d 4 -D plughw:1,0 send.wav");

///skip
?>

Ок.
Работает распознавание одной строкой из шела, после записи в файл:

curl "asr.yandex.net/asr_xml?key=f609cf87-d8a9-48c3-b11b-e20054ec3bb3&uuid=01ae13cb744628b58fb536d496daa177&topic=notes&lang=ru-RU" -H "Content-Type: audio/x-wav" --data-binary "@test.waw"

Получаем текст, который нужно распарсить, сравнить с базой и выполнить скрипт:

<?xml version="1.0" encoding="utf-8"?>
<recognitionResults success="1">
        <variant confidence="0">раз раз раз раз раз</variant>
</recognitionResults>

Михаил Калинин.

Принудительный провижининг

#add to sip_notify.conf

[spa-resync]
Event=>resync
Content-Length=>0

[spa-report]
Event=>report
Content-Length=>0

[spa-reboot]
Event=>reboot
Content-Length=>0

[spa-restart]
Event=>restart
Content-Length=>0

restart asterisk
# service asterisk restart

run sip notify against the extension and see the result
# asterisk -r
asterisk1*CLI> sip debug peer 401
asterisk1*CLI> sip notify spa-resync 401

HUDlite

http://yum.trixbox.org/centos/5/RPMS/repodata/repoview/__nogroup__.group.html

Убедитесь что  trixbox repository выбран.
yum search hud

yum install hudlite-server.i386

yum install tbm-hudadmin

Создайте  директорию  /etc/asterisk/hud 

Создайте пустой файл user.xml в этой директории: cat > user.xml 

Выйдите из директории hud и модифицируйте права chmod –R 766 hud


HUDlite Admin программа будет исследовать ваши настройки и автоматически создавать учетные записи и пароли для ваших пользователей. Вы можете по желанию сменить пароли созданные автоматически и добавить мобильные номера телефонов  и адрес электронной почты ваших пользователей.



Конфигурация HUDLite клиента.

[Download HUDlite client here]

Приинсталляции выберите автозапуск при HUDlite клиента. Примите пользовательскую лицензию. Далее Вам нужно ввести HUDимя пользователя и пароль. Вы можете получить имя пользователя в  HUDlite административной панели. Если ваше имя пользователя 200 ваше имя пользователя будет sip200. Ваш пароль будет восемь случайных символов. Вы  можете изменить пароли по желанию в HUDliteadmin.
Далее введите имя сервера, пароль для обращения к серверу password (общий для всех), и серверный порт.

    Имя сервера IPaddressвашего trixbox.
    Сервер пароль 'password'
    Сервер порт 6600

Если вы пользуетесь MicrosoftOutlookвыберите инсталяцию с разрешением HUDliteиспользовать Ваш список контактов для callerIDи для установки функции ClicktoDialв Outlook. После этого выберите инсталяцию TAPIдрайвера. Это позволит вам выполнять функцию clicktodialиспользуя любую TAPIиспользуемую приложениями.
HUDliteтеперь инсталирован. Вы должны видеть все доступные номера в HUDокне.

Чистка регистрации в AstDB

asterisk*CLI> sip show peers
Name/username              Host            Dyn Nat ACL Port     Status
...
00000X/voip1                172.16.1.X       D   N      1024     Unmonitored

asterisk*CLI> database show

asterisk*CLI> database showkey SIP/Registry/00000X

asterisk*CLI> database deltree SIP/Registry/00000X

server# /etc/init.d/asterisk restart

Сборка asterisk из исходных текстов

Версия 16

# apt install libedit-dev uuid-dev libxml2-dev libsqlite3-dev

# wget https://downloads.asterisk.org/pub/telephony/asterisk/asterisk-16-current.tar.gz

# cd /usr/local/src

# tar -xvzf /root/asterisk-16-current.tar.gz

# cd asterisk-16.3.0/

# ./configure --with-jansson-bundled

# cd contrib/scripts

# ./install_prereq install

# ./install_prereq install-unpackaged

# cd -

# make menuselect

# make

# make install

# make samples

# asterisk

# asterisk -rvvv

Версия 1.8

Задача: Добавление поддержки imap хранилища голосовой почты

Ubuntu

root@server:~# apt-get install libncurses5-dev libssl-dev libxml2-dev
root@server:~# cd /usr/src

root@server:/usr/src# wget ftp://ftp.cac.washington.edu/mail/imap.tar.Z
root@server:/usr/src# wget http://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-1.6.2.19.tar.gz

FreeBSD

[server:~] # pkg install perl5 bison m4 gmake gcc libtool libltdl libxml2 speex unixODBC gsm 

[server:~] # cd /usr/src/
[server:/usr/src] # fetch ftp://ftp.cac.washington.edu/mail/imap.tar.Z
[server:/usr/src] # fetch http://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-1.6.2.19.tar.gz

Ubuntu/FreeBSD

server:/usr/src# gunzip imap.tar.Z
server:/usr/src# tar -xvf imap.tar
server:/usr/src# tar -xvf asterisk-1.6.2.19.tar.gz

server:/usr/src# cd imap-2007f/

root@server:/usr/src/imap-2007f# make slx EXTRACFLAGS="-I/usr/include/openssl"
или
[server:/usr/src/imap-2007f] # make bsf EXTRACFLAGS="-I/usr/include/openssl"

server:/usr/src/imap-2007f# cd ../asterisk-1.6.2.19
server:/usr/src/asterisk-1.6.2.19# ./configure --with-imap=/usr/src/imap-2007f/ --prefix=/usr/local/asterisk/ --disable-xmldoc
server:/usr/src/asterisk-1.6.2.19# make menuconfig
server:/usr/src/asterisk-1.6.2.19# make
server:/usr/src/asterisk-1.6.2.19# make install clean
server:/usr/src/asterisk-1.6.2.19# make samples

server:~# mkdir -p /usr/local/asterisk/var/db/asterisk/

server:~# /usr/local/asterisk/sbin/asterisk

server:~# /usr/local/asterisk/sbin/asterisk -rvvvvvv

Преобразование mp3 файлов в формат Asterisk

# lame --decode Knockin_on_Heavens_Door.mp3

# sox -V Knockin_on_Heavens_Door.mp3.wav -r 8000 -c 1 Knockin_on_Heavens_Door.mp3.raw

# cp Knockin_on_Heavens_Door.mp3.raw /var/lib/asterisk/moh/

# cp Knockin_on_Heavens_Door.mp3.raw /usr/local/share/asterisk/moh/

# cat musiconhold.conf
...
[default]
mode=files
directory=moh
...
# cat extensions.conf
...
exten => 306,1,Answer
exten => 306,2,MusicOnHold()
...
сервис_asterisk.txt · Последние изменения: 2019/12/09 16:05 — val