Quantcast
Channel: IP АТС Asterisk
Viewing all 1135 articles
Browse latest View live

Новости

$
0
0

Новости

3CX поглощает Elastix. (22. Dec 2016)

Объявлено о слиянии Elastix и 3CX. Версия MT закрыта для скачивания. Elastix 5 будет разрабатываться в партнерстве с 3CX и распространяться по коммерческой лицензии.

Sangoma заверяет пользователей в своей приверженности open source, в связи с поглощением Elastix 3CX-ом

Elastix: поддержка уже установленных версий 2.5 и 4 не прекращается, репозитории будут доступны и в будущем.


3CX поглощает Elastix.

$
0
0

3CX поглощает Elastix.

  • anchor: #20161222125359
  • head: 3CX поглощает Elastix.
  • subtitle:
  • link: /wiki/news/allnewsdata#20161222125359
  • start: 2016-12-22
  • stop: 2017-04-22
  • text:

Объявлено о слиянии Elastix и 3CX. Версия MT закрыта для скачивания. Elastix 5 будет разрабатываться в партнерстве с 3CX и распространяться по коммерческой лицензии.

Sangoma заверяет пользователей в своей приверженности open source, в связи с поглощением Elastix 3CX-ом

Elastix: поддержка уже установленных версий 2.5 и 4 не прекращается, репозитории будут доступны и в будущем.

  • tags: freepbx

Пример настройки SIP транка для SIPNET.RU

$
0
0

Пример настройки SIP транка для SIPNET.RU

Trunk Name

sipnet

PEER Details

type=friend
secret=PASSWORD
qualify=yes
nat=force_rport,comedia
insecure=invite
host=sipnet.ru
fromuser=SIP_ID
fromdomain=sipnet.ru
dtmfmode=info
disallow=all
defaultuser=SIP_ID
allow=alaw
allow=ulaw
allow=g729

Register String

userID:PASSWORD@sipnet.ru

Скриншоты

FreePBX 12 PjSIP trunk SIPNET.RU

Connectivity > Add SIP (chan_pjsip) Trunk

sipnet pjsip trunk

pjsip.aor.conf

[sipnet.ru]
type=aor
qualify_frequency=60
contact=sip:SIP_ID@sipnet.ru:5060

pjsip.auth.conf

[sipnet.ru]
type=auth
auth_type=userpass
password=PASSWORD
username=SIP_ID

pjsip.endpoint_custom.conf

[sipnet.ru]
type=endpoint
transport=0.0.0.0-udp
context=from-pstn
disallow=all
allow=ulaw,alaw
outbound_auth=sipnet.ru
aors=sipnet.ru

pjsip.identify_custom.conf

[sipnet.ru]
type=identify
endpoint=sipnet.ru
match=sipnet.ru

pjsip.registration_custom.conf

[sipnet.ru]
type=registration
transport=0.0.0.0-udp
outbound_auth=sipnet.ru
retry_interval=60
expiration=3600
auth_rejection_permanent=yes
server_uri=sip:sipnet.ru:5060
client_uri=sip:SIP_ID@sipnet.ru:5060

pjsip.transports.conf

[0.0.0.0-udp]
type=transport
protocol=udp
bind=0.0.0.0:5060
external_media_address=195.144.244.52
external_signaling_address=195.144.244.52
local_net=192.168.0.0/24
ubuntu*CLI> pjsip show endpoints

 Endpoint:  <Endpoint/CID.....................................>  <State.....>  <Channels.>
    I/OAuth:  <AuthId/UserName...........................................................>
        Aor:  <Aor............................................>  <MaxContact>
      Contact:  <Aor/ContactUri...............................>  <Status....>  <RTT(ms)..>
  Transport:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress..................>
   Identify:  <MatchList.................................................................>
    Channel:  <ChannelId......................................>  <State.....>  <Time(sec)>
        Exten: <DialedExten...........>  CLCID: <ConnectedLineCID.......>
 =========================================================================================

 Endpoint:  sipnet.ru                                            Not in use    0 of inf
    OutAuth:  sipnet.ru/SIP_ID
        Aor:  SIP_ID                                             0
      Contact:  sipnet.ru/sip:SIP_ID@sipnet.ru:5060             Avail              23.398
  Transport:  0.0.0.0-udp               udp      0      0  0.0.0.0:5060
   Identify:  212.53.40.40/32,2a02:2f8:2:3::40/128

Connectivity > Outbound Routes

FreePBX SIP Trunk

FreePBX 13 исходящая маршрутизация.

FreePBX

FreePBX 13 PJSIP Trunk

$
0
0

FreePBX 13 PJSIP Trunk

Пример данных провайдера

  • SIP user - 1234567
  • SIP password - secret
  • SIP server - sip.sprovider.ru

Asterisk 13.4.0 / FreePBX 13 (FreePBX Framework 13.0.1beta3.54)

  • Trunk Name - pjsip_test

PJSIP trunk general

freepbx13 pjsip trunk general

PJSIP Settings

freepbx13 pjsip trunk settings

freepbx13 pjsip trunk advanced

pjsip show registrations
asterisk*CLI> pjsip show registrations<Registration/ServerURI..............................>  <Auth..........>  <Status.......>
 =========================================================================================

 pjsip_test/sip:sip.sprovider.ru:5060                      pjsip_test        Registered
pjsip show endpoint <name>
asterisk*CLI> pjsip show endpoint pjsip_test

 Endpoint:  <Endpoint/CID.....................................>  <State.....>  <Channels.>
    I/OAuth:  <AuthId/UserName...........................................................>
        Aor:  <Aor............................................>  <MaxContact>
      Contact:  <Aor/ContactUri...............................>  <Status....>  <RTT(ms)..>
  Transport:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress..................>
   Identify:  <Identify/Endpoint.........................................................>
        Match:  <ip/cidr.........................>
    Channel:  <ChannelId......................................>  <State.....>  <Time(sec)>
        Exten: <DialedExten...........>  CLCID: <ConnectedLineCID.......>
 =========================================================================================

 Endpoint:  pjsip_test                                            Not in use    0 of inf
    OutAuth:  pjsip_test/1234567
        Aor:  pjsip_test                                          0
      Contact:  pjsip_test/sip:12345670@sip.sprovider.ru:5060     Avail            78.715
  Transport:  0.0.0.0-udp               udp      0      0  0.0.0.0:5077
   Identify:  pjsip_test/pjsip_test
        Match: 123.123.123.123/32


 ParameterName                 : ParameterValue
 =====================================================
 100rel                        : yes
 accountcode                   :
 aggregate_mwi                 : true
 allow                         : (g729|alaw|ulaw|g726)
 allow_subscribe               : true
 allow_transfer                : true
 aors                          : pjsip_test
 auth                          :
 call_group                    :
 callerid                      : <unknown>
 callerid_privacy              : allowed_not_screened
 callerid_tag                  :
 connected_line_method         : invite
 context                       : from-sprovider
......

<spoiler>

Configuration Mode:

Simple/Advanced

Permanent Auth Rejection:

v

Retry Interval:

60

Expiration:

3600

Forbidden Retry Interval:

10

Max Retries:

10

Qualify Frequency:

60

Username:

Secret:

SIP Server:

SIP Server Port:

Advanced options

Client URI:

Server URI:

AOR Contact:


Outbound Proxy:

Contact User:

Context:

Transport:

0.0.0.0-udp

Codecs:

ulaw
alaw
g722

Пример настройки SIP транка chan_pjsip для соединения с другим сервером Asterisk

FreePBX Группы Вызова - Ring Groups

$
0
0

FreePBX Группы Вызова - Ring Groups

Группа екстеншенов для приема звонков. Используйте там, где не требуется функционал Queues

freepbx13-ring-groups

ring group dialplan - extensions_additional.conf

ring group dialplan - extensions_additional.conf

В отличии от очереди (queue), в Asterisk нет такого объекта или модуля, как Ring Group.
Для вызова группы, данным модулем, генерируется соответствующий диалплан.

[ext-group]
include => ext-group-custom
exten => 666,1,GotoIf($["${__RINGINGSENT}" = "TRUE"]?cid)
exten => 666,n,Playtones(ring)
exten => 666,n,Progress
exten => 666,n(cid),Macro(user-callerid,)
exten => 666,n,Macro(blkvm-setifempty,)
exten => 666,n,GotoIf($["${GOSUB_RETVAL}" = "TRUE"]?skipov)
exten => 666,n,Macro(blkvm-set,reset)
exten => 666,n,Set(__NODEST=)
exten => 666,n(skipov),Set(RRNODEST=${NODEST})
exten => 666,n(skipvmblk),Set(__NODEST=${EXTEN})
exten => 666,n,GosubIf($[${DB_EXISTS(RINGGROUP/666/changecid)} = 1 & "${DB(RINGGROUP/666/changecid)}" != "default" & "${DB(RINGGROUP/666/changecid)}" != ""]?sub-rgsetcid,s,1())
exten => 666,n,Gosub(sub-record-check,s,1(rg,666,dontcare))
exten => 666,n,Set(RingGroupMethod=ringall)
exten => 666,n(DIALGRP),Macro(dial,20,${DIAL_OPTIONS},5000-5001-5002)
exten => 666,n,Gosub(sub-record-cancel,s,1())
exten => 666,n,Set(RingGroupMethod=)
exten => 666,n,GotoIf($["foo${RRNODEST}" != "foo"]?nodest)
exten => 666,n,Set(__NODEST=)
exten => 666,n,Macro(blkvm-clr,)
exten => 666,n,Goto(app-blackhole,hangup,1)
exten => 666,n(nodest),Noop(SKIPPING DEST, CALL CAME FROM Q/RG: ${RRNODEST})

exten => h,1,Macro(hangupcall,)

;--== end of [ext-group] ==--;

Обратите внимание на инклюд: include ⇒ ext-group-custom
Это значит, что вы можете написать собственный алгоритм вызова группы номеров с блек джеком и шлюхамии использовать его как ринг группу freepbx.

Группа вызова:

Номер группы вызываемый в диалплане.

Group Description

Описание группы.
Понятное название для группы вызова. Используется для идентификации в других модулях FreePBX.

Ring Strategy

Стратегия вызова пользователей групы.

  • ringall - звонят-все: Звонят все каналы, пока один кто либо не ответит (по умолчанию)
  • hunt - серийное-искание: Звонок поступает на первый доступный номер в списке.
  • memoryhunt - прогресс-серийное-искание: Звонит первый внутренний номер в списке, затем первый и второй, затем первый, второй и третий в списке, и так далее.
  • *-prim -прим: Этот режим работает так же, как huntи memoryhunt, за исключением того, что если первый внутренний номер из списка занят, следующие по списку не будут звонить. Также зависит от установок 'Не беспокоить' и 'Перенаправление' на первом внутреннем номере списка. Если DND, то поиск в группе на этом заканчивается. Если CF (перенаправление) не перенаправит, то поиск в группе продолжится.<br>
  • firstavailable - первый-доступный: звонит первый доступный номер
  • firstnotonphone - первый-на-телефоне: звонит первый телефон, у которого не снята трубка.
  • random - случайный выбор

Ring Time

(max 300 sec) Время в секундах в течение которого телефоны будут звонить. Для всех стратегий вызова серийного искания, это время звонка для каждого шага стратегии вызова.

Extension List

Список внутренних номеров группы по одному в каждой строке. Вы можете добавить внешний номер или номер удаленной системы. Чтобы обозначить такие екстеншены, добавьте в конец решетку #. Чтобы группа могла вызвать внешний номер, его формат должен совпадать с шаблоном набора из модуля Outbound Routes. Также добавляйте решетку, если в качестве екстеншенов используются такие объекты freepbx, как Queues или Follow-Me.

Extension Quick Pick

Выбор участников группы из списка существующих.

Announcement

Приветствие:Сообщение, которое будет воспроизведено для входящего респондента, прежде чем пойдет звонок в эту группу.Для создания такого приветствия используйте раздел меню System Recordings

Play Music On Hold?

Использовать Музыку в ожидании? Если выбран класс Музыки в ожидании вместо простого сигнала вызова (КПВ), то позвонивший будет слушать музыку, пока кто-то не поднимет трубку.

  • Ring - КПВ (по умолчанию)
  • Inherit - Наследовать из маршрута
  • Default - Класс MOH по умолчанию в системе.
  • none

CID Name Prefix

Префикс ИД имени: Опционально, можно использовать какой-то префикс для звонка в эту группу. Например, если это группа «Sales:», то, установив такой префикс для этой группы, можно видеть, если звонит John Doe, то мы увидим на дисплее Sales:John Doe.

Alert Info

Дополнительная информация ALERT_INFO добавляет указанное значение в SIP header Alert-Info. Если телефон поддерживает, будет выведено на дисплей

freepbx13-ring-groups

Send Progress

Отправлять прогресс вызова в вызывающий канал.

YesNo

Ignore CF Settings

Игнорировать установки предустановленной переадресации звонков (CF). Если отмечено, форвардинг звонка будет игнорироваться. Это относится к общим установкам CF, форвардингу на Занято и при Неответе. Внутренний номер, набранный с '#' на конце, например для доступа к опции Следуйте сюда, может не сработать.

YesNo

Skip Busy Agent

Пропускать занятых операторов. Если отмечено, оператор на вызове будет пропущен и линия возвратит статус Занято. Это служит для тех случаев, когда используются мультиканальные телефоны и телефоны с опцией ожидания второго вызова, которые не верно отрабатывают в различных стратегиях звонков с серийным исканием, таким образом звонок перейдёт следующему члену группы дозвона.

YesNo

Enable Call Pickup

Включить перехват вызова в группе. Это даёт возможность прямого перехвата входящего вызова используя номер группы. Если не отмечено, то отдельные внутренние номера, являющиеся членами группы, могут перехватывать вызовы, используя сервисный код прямого перехвата, который будет работать вне зависимости включен пикап здесь или нет.

YesNo

Confirm Calls

Подтверждение звонков. Используйте это, если звонок идёт на внешний номер, который нуждается в подтверждении. Например, мобильный телефон может включить голосовую почту, которая перехватит этот вызов. Нажатием на 1 можно заблокировать такие действия. Опция действительна только при стратегии вызова ringall (звонят-все).

YesNo

Remote Announce

Объявление пользователю принимающему вызов: Сообщение воспроизводится для принявшего этот звонок, если включена опция Call Confirm (Подтверждение звонков). Для создания такого приветствия используйте модуль System recordings.

Too-Late Announce

Сообщение Уже-поздно: Сообщение воспроизводится для принявшего этот звонок, если звонок уже принят прежде чем он успел нажать 1. Для создания такого сообщения используйте модуль System Recordings .

Изменить конфигурацию Caller ID входящих вызовов

  • Mode Режим: По умолчанию: Передавать Callers ID если транк это разрешает.
  • Фиксированное значение Caller ID: Всегда передавать фиксированное значение Caller ID указанное ниже.
  • Фиксированное значение Caller ID для внешних вызовов: Передавать фиксированное значение Caller ID указанное ниже только в случае исходящих внешних звонков. Внутренние соединения не будут использовать этот Caller ID.
  • Использовать набранный номер: Передавать набранный Caller ID для перенаправленных звонков, пришедших снаружи. Внутренние соединения будут передавать Caller ID в обычном режиме. Для этого предполагается входящий маршрут по DID. Он будет блокироваться на транке, где провайдеры блокируют чужие Caller ID.
  • Форсировать набранный номер: Передаёт номер, который был набран как назначение (DID) в качестве Номера ИД, для звонков пришедших снаружи. Внутренние соединения будут передавать Caller ID в обычном режиме. Для этого предполагается входящий маршрут по DID. Он будет передаваться через транк, где провайдеры блокируют чужие Caller ID.

Fixed CID Value

Фиксированное значение Caller ID:</b><br><span>Фиксированное значение для замены Caller ID в зависимости от одного из режимов выше. Должен быть только в цифровом формате, или опционально - в формате Е164 с использованием «+» впереди номера.

Record Calls

Записывать вызовы. Можно выбрать из следующих возможностей: всегда записывать соединения, никогда не записывать соединения, или записывать по запросу во время разговора. Если включена опция не записывать соединения, то запись по запросу также невозможна.

ForceDont CareNever

Везде где возможен вызов екстеншена, во FreePBX добавлена опция включения записи. Если, например, требуется записывать все входящие и исходящие вызовы, достаточно включить запись в модулях Inbound Routesи Outbound Routes, соответственно.

Destination if no answer

Назначение, если никто не ответил. В выпадающем списке, выберете модуль FreePBX, который вы хотите использовать для failover


FreePBX 12 screenshot

Troubleshooting

$
0
0

Исходящие вызовы в диалплане Asterisk

$
0
0

Исходящие вызовы в диалплане Asterisk

Направление исходящей связи можно реализовать определением короткого кода доступа (например '9'), или определить полностью шаблон набираемых номеров.

[international]
ignorepat => 9
exten => _9810.,1,Dial(DAHDI/g2/${EXTEN:1})
exten => _9810.,2,Congestion
include => longdistance

[longdistance]
ignorepat => 9
exten => _98[02-9]XXXXXXXXX,1,Dial(DAHDI/g2/${EXTEN:1})
exten => _98[02-9]XXXXXXXXX,2,Congestion
include => local

[local]
ignorepat => 9
exten => _9[02-9]XXXXXX,1,Dial(DAHDI/g2/${EXTEN:1})
exten => _9[02-9]XXXXXX,2,Congestion
include => default

В этом примере рассматриваются 3 контекста с различными правами доступа к Телефонной сети Общего Пользования .

Конструкция 'ignorepat ⇒ 9 ' говорит Астериску не отключать тон готовности после набора заданной цифры.

  • Контекст [international] позволяет набрать международный номер с любым количеством цифр.
  • Контекст [longdistance] - междугородний номер до 11-ти цифр.
  • Контекст [local] - городской номер длинной до 7-ми цифр.

Переменная ${EXTEN:1} удаляет префикс:

${123456789:1} - возвращает строку 23456789
${123456789:-4} - возвращает строку 6789
${123456789:0:3} - возвращает строку 123
${123456789:2:3} - возвращает строку 345
${123456789:-4:3} - возвращает строку 678

FreeSWITCH CDR MySQL

$
0
0

FreeSWITCH CDR MySQL

Сохранение CDR в mysql и просмотр данных о звонках FreeSWITCH при помощи веб интерфейса - CDR-Viewer.

Подготовим FreeSWITCH для работы с MySQL через ODBC

Предполагается, что сервер mysql (mariadb) установлен.

 yum install -y mysql-connector-odbc unixODBC unixODBC-devel

Проверим odbcinst.ini

# Driver from the mysql-connector-odbc package
# Setup from the unixODBC package
[MySQL]
Description     = ODBC for MySQL
Driver          = /usr/lib/libmyodbc5.so
Setup           = /usr/lib/libodbcmyS.so
Driver64        = /usr/lib64/libmyodbc5.so
Setup64         = /usr/lib64/libodbcmyS.so
FileUsage       = 1

Заполним odbc.ini

[freeswitch]
Driver=MySQL
SERVER=localhost
PORT=3306
DATABASE=freeswitchcdr
USER=DB_USER
PASSWORD=DB_PASSWORD

Проверим подключение к MySQL

 echo "select 1" | isql -v freeswitch
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> select 1
+---------------------+
| 1                   |
+---------------------+
| 1                   |
+---------------------+
SQLRowCount returns 1
1 rows fetched

Создадим БД MySQL в формате asteriskcdrdb

Создайте файл, например:

 touch freeswitchcdr.sql

И скопируйте в него структуру таблицы БД:

CREATE TABLE cdr (
   calldate datetime NOT NULL default '0000-00-00 00:00:00',
   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 '',
   uniqueid varchar(32) NOT NULL default '',
   userfield varchar(255) NOT NULL default '',
   did varchar(50) NOT NULL default '',
   recordingfile varchar(255) NOT NULL default '',
   KEY `calldate` (`calldate`),
   KEY `dst` (`dst`),
   KEY `accountcode` (`accountcode`),
   KEY `uniqueid` (`uniqueid`)
);

Создаем БД: freeswitchcdr

 mysqladmin create freeswitchcdr

Создаем таблицу:cdr

 mysql asteriskcdrdb < freeswitchcdr.sql

Задаем права на БД с параметрами определенными в odbc.ini

 mysql> GRANT ALL PRIVILEGES ON freeswitchcdr.* TO DB_USER@localhost  IDENTIFIED BY 'DB_PASSWORD';
 flush privileges;
 \q

Подготовим FreeSWITCH

Расскомментируйте строку event_handlers/mod_odbc_cdrв файле исходников FS ../freeswitch/modules.conf

и выполните make && make install.

По окончании компиляции скопируйте файл odbc_cdr.conf.xml из исходников в директорию, где установлен FS.

В моем примере это /usr/local/src/freeswitchи /usr/local/freeswitchсоответственно

cp /usr/local/src/freeswitch/src/mod/event_handlers/mod_odbc_cdr/conf/autoload_configs/odbc_cdr.conf.xml /usr/local/freeswitch/conf/autoload_configs/odbc_cdr.conf.xml

И заполните файл следующим содержанием, где параметры БД (odbc-dsn), данные определенные нами в odbc.ini:

<configuration name="odbc_cdr.conf" description="ODBC CDR Configuration"><settings><!-- <param name="odbc-dsn" value="freeswitchcdr:DB_USER:DB_PASSWORD"/> --><param name="odbc-dsn" value="odbc://freeswitch"/><!-- global value can be "a-leg", "b-leg", "both" (default is "both") --><param name="log-leg" value="both"/><!-- value can be "always", "never", "on-db-fail" --><param name="write-csv" value="on-db-fail"/><!-- location to store csv copy of CDR --><param name="csv-path" value="/usr/local/freeswitch/log/odbc_cdr"/><!-- if "csv-path-on-fail" is set, failed INSERTs will be placed here as CSV files otherwise they will be placed in "csv-path" --><param name="csv-path-on-fail" value="/usr/local/freeswitch/log/odbc_cdr/failed"/><!-- dump SQL statement after leg ends --><param name="debug-sql" value="true"/></settings><tables><!-- only a-legs will be inserted into this table --><table name="cdr" log-leg="a-leg"><field name="calldate" chan-var-name="start_stamp"/><field name="clid" chan-var-name="caller_id_name"/><field name="src" chan-var-name="caller_id_number"/><field name="dst" chan-var-name="destination_number"/><field name="dcontext" chan-var-name=""/><field name="channel" chan-var-name="channel_name"/><field name="dstchannel" chan-var-name="bridge_channel"/><field name="lastapp" chan-var-name="hangup_cause"/><field name="lastdata" chan-var-name="sip_hangup_disposition"/><field name="duration" chan-var-name="duration"/><field name="billsec" chan-var-name="billsec"/><field name="disposition" chan-var-name="hangup_cause"/><field name="lastapp" chan-var-name="current_application"/><field name="amaflags" chan-var-name="amaflags"/><field name="uniqueid" chan-var-name="uuid"/><field name="recordingfile" chan-var-name="recordingfile"/><field name="userfield" chan-var-name=""/></table></tables></configuration>

Загрузим модуль mod_odbc_cdr

 fs_cli
 load mod_odbc_cdr

Если в дальнейшем вы будете вносить изменения в файл odbc_cdr.conf.xmlих можно применить командой:

 reload mod_odbc_cdr

reload mod_odbc_cdr

reload mod_odbc_cdr

freeswitch@internal> reload mod_odbc_cdr
+OK Reloading XML
+OK module unloaded
+OK module loaded

2016-07-21 18:58:05.585312 [CONSOLE] switch_loadable_module.c:2008 Stopping: mod_odbc_cdr
2016-07-21 18:58:05.585312 [DEBUG] mod_odbc_cdr.c:542 Destroying table cdr
2016-07-21 18:58:05.585312 [CONSOLE] switch_loadable_module.c:2028 mod_odbc_cdr unloaded.
2016-07-21 18:58:05.585312 [INFO] mod_enum.c:880 ENUM Reloaded
2016-07-21 18:58:05.585312 [DEBUG] mod_odbc_cdr.c:396 Set odbc-dsn [odbc://freeswitch]
2016-07-21 18:58:05.585312 [DEBUG] mod_odbc_cdr.c:405 Set debug-sql [true]
2016-07-21 18:58:05.585312 [DEBUG] mod_odbc_cdr.c:425 Set log-leg [both]
2016-07-21 18:58:05.585312 [DEBUG] mod_odbc_cdr.c:436 Set csv-path [/usr/local/freeswitch/log/odbc_cdr/]
2016-07-21 18:58:05.585312 [DEBUG] mod_odbc_cdr.c:437 Set csv-path-on-fail [/usr/local/freeswitch/log/odbc_cdr/failed/]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:113 Found table [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:117 Set table [cdr] to log A-legs only
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:128 Adding fields to table [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [calldate] (start_stamp) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [clid] (caller_id_name) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [src] (caller_id_number) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [dst] (destination_number) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [channel] (channel_name) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [dstchannel] (bridge_channel) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [lastapp] (hangup_cause) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [lastdata] (sip_hangup_disposition) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [duration] (duration) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [billsec] (billsec) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [disposition] (hangup_cause) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [lastapp] (current_application) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [amaflags] (amaflags) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [uniqueid] (uuid) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [recordingfile] (recordingfile) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] mod_odbc_cdr.c:139 Field [userfield] (branch) added to [cdr]
2016-07-21 18:58:05.585312 [INFO] switch_time.c:1415 Timezone reloaded 1781 definitions
2016-07-21 18:58:05.595283 [CONSOLE] switch_loadable_module.c:1538 Successfully Loaded [mod_odbc_cdr]

Подготовим Asterisk CDR Viewer

 cd /var/www/html
 git clone https://github.com/g613/asterisk-cdr-viewer.git

 cd asterisk-cdr-viewer/include

Отредактируем файл config.inc.php

$db_type = 'mysql';
$db_host = 'localhost';
$db_port = '3306';
$db_user = 'DB_USER';
$db_pass = 'DB_PASSWORD';
$db_name = 'freeswitchcdrdb';
$db_table_name = 'cdr';
$db_options = array();

Если все сделано правильно в Asterisk-CDR-Viewer будут отображаться свежие данные о вызовах:

Для того, чтобы работала сортировка по статусу вызова надо отредактировать файл ../asterisk-cdr-viewer/templates/form.tpl.phpзаменив секцию:

<td nowrap=""nowrap><input <?php if ( isset($_REQUEST['disposition_neg'] ) && $_REQUEST['disposition_neg'] == 'true' ) { echo 'checked="checked"'; } ?> type="checkbox" name="disposition_neg" value="true" /> not<select name="disposition" id="disposition"><option <?php if (empty($_REQUEST['disposition']) || $_REQUEST['disposition'] == 'all') { echo 'selected="selected"'; } ?> value="all">All Dispositions</option><option <?php if (isset($_REQUEST['disposition']) && $_REQUEST['disposition'] == 'ANSWERED') { echo 'selected="selected"'; } ?> value="ANSWERED">Answered</option><option <?php if (isset($_REQUEST['disposition']) && $_REQUEST['disposition'] == 'BUSY') { echo 'selected="selected"'; } ?> value="BUSY">Busy</option><option <?php if (isset($_REQUEST['disposition']) && $_REQUEST['disposition'] == 'FAILED') { echo 'selected="selected"'; } ?> value="FAILED">Failed</option><option <?php if (isset($_REQUEST['disposition']) && $_REQUEST['disposition'] == 'NO ANSWER') { echo 'selected="selected"'; } ?> value="NO ANSWER">No Answer</option></select></td>

на следующий код:

<td nowrap=""nowrap><input <?php if ( isset($_REQUEST['disposition_neg'] ) && $_REQUEST['disposition_neg'] == 'true' ) { echo 'checked="checked"'; } ?> type="checkbox" name="disposition_neg" value="true" /> not<select name="disposition" id="disposition"><option <?php if (empty($_REQUEST['disposition']) || $_REQUEST['disposition'] == 'all') { echo 'selected="selected"'; } ?> value="all">All Dispositions</option><option <?php if (isset($_REQUEST['disposition']) && $_REQUEST['disposition'] == 'NORMAL_CLEARING') { echo 'selected="selected"'; } ?> value="NORMAL_CLEARING">Answer</option><option <?php if (isset($_REQUEST['disposition']) && $_REQUEST['disposition'] == 'USER_BUSY') { echo 'selected="selected"'; } ?> value="USER_BUSY">Busy</option><option <?php if (isset($_REQUEST['disposition']) && $_REQUEST['disposition'] == 'UNALLOCATED_NUMBER') { echo 'selected="selected"'; } ?> value="UNALLOCATED_NUMBER">No Number</option><option <?php if (isset($_REQUEST['disposition']) && $_REQUEST['disposition'] == 'NO_ROUTE_DESTINATION') { echo 'selected="selected"'; } ?> value="NO_ROUTE_DESTINATION">No Route</option><option <?php if (isset($_REQUEST['disposition']) && $_REQUEST['disposition'] == 'ORIGINATOR_CANCEL') { echo 'selected="selected"'; } ?> value="ORIGINATOR_CANCEL">No Answer</option></select></td>

FreeSWITCH


Asterisk: followme.conf

$
0
0

Asterisk: followme.conf

Follow Me - настройка предустановленной переадресации вызова - Следуй За Мной.

Asterisk Follow Me

Конфигурационный файл /etc/asterisk/followme.confиспользуется для назначения глобальных параметров generalи уникальных адресатов followmeid, которые могут выполняться из диалплана приложением Follow Me

Приоритет может быть использован только один раз, т.е. в одной строке, но не в разных (для одного пользователя).
Отдельные строки с одинаковым приоритетом будут игнорироваться.
Параллельные вызовы на разные номера (два и больше), должны описываться в одной строке при помощи оператора '&'.

[имя или номер] используется для вызова приложением FollowMe
context ⇒ <context name> - контекст, из которого будут вызываться заданные номера folowme
number ⇒ <number>,[<timeout>],[<priority>] - адресат, время посылки вызова, приоритет

Простое распределение по порядку строк.
[followmeid_simple]
context=from-internal
number => 9981138,15
number => 1234,20
number => 3216111,45

Сперва вызывается номер 9981138 в течении 15-ти секунд, затем номер -1234 в течении 20 секунд и после номер 3216111 в течении 45 секунд.

Сортировка по приоритетам.
[followmeid_sorted]
context=from-internal
number => 9981138,35,2
number => 1234,20,1
number => 3216111,50,3

Сначала вызывается номер 1234 (приоритет 1), затем 9981138 (2) и последним 3216111 (3) .

Параллельные вызовы
[followmeid_parallel]
context=full_outbound_access
number => 1234&9981138,35,1
number => 3216111,50,2

Сперва вызываются номера 1234 и 9981138 одновременно, затем 3216111.

Конфигурационный файл followme.conf

Убедитесь, что app_followme.so загружен.

*CLI> module load app_followme.so
Loaded app_followme.so
  == Parsing '/etc/asterisk/followme.conf': Found followme.conf
  == Registered application 'FollowMe'
 Loaded app_followme.so => (Find-Me/Follow-Me Application)
[general]

Глобальные параметры folowme

 featuredigittimeout=>5000

Время в миллисекундах, в течении которого система будет ждать подтверждения принять вызов, вводом DTMF кода, от вызываемого абонента.

 enable_callee_prompt=>true

Включить голосовое объявление вызываемому абоненту, с предложением принять или отказаться от переадресованного вызова.
По умолчанию - включено.

  takecall=>1

Общее, по умолчанию '1', значение DTMF кода, подтверждения приема вызова.
Может состоять из одной или нескольких цифр.

  declinecall=>2

Общее, по умолчанию '2', значение DTMF кода, отказа от ответа на вызов.

'Incoming call from'
 call_from_prompt=>followme/call-from

Общее, по умолчанию, сообщение «Входящий вызов от».

'You have an incoming call'
 norecording_prompt=>followme/no-recording

Общее, по умолчанию, сообщение «Входящий вызов», если вызывающий выбрал опцию, не записывать свое имя.

'Press 1 to accept this call or press 2 to decline it'
 options_prompt=>followme/options

Общее, по умолчанию, сообщение - «Нажмите 1 чтобы принять вызов или 2 чтобы отказаться».

'Please hold while we try and connect your call'
 pls_hold_prompt=>followme/pls-hold-while-try

Общее сообщение: «Оставайтесь на линии, мы вас соединяем».

'The party you're calling isn't at their desk'
 status_prompt=>followme/status

Общее сообщение: «Вызываемый абонент не на рабочем месте»

'I'm sorry, but we were unable to locate your party'
 sorry_prompt=>followme/sorry

Общее сообщение: «Местонахождение абонента не установлено»

[followme_id_test]

Конфигурация уникального идентификатора для вызова приложением FollowME

 musicclass=>default

Класс Музыки на Удержании для воспроизведения ожидающему абоненту.

 context=>default

Контекст для вызова адресатов followme

  number=>01233456,25

Адресат followme. Формат:

number⇒ <number to call[&2nd #[&…]]>[,<таймаут в секундахs>[,<порядок выбора адресатов>]]

 enable_callee_prompt=>true

Включить приглашение вызывающему абоненту активировать followme.
По умолчанию действует глобальная установка из раздела [general].

 takecall=>1

Общее, по умолчанию '1', значение DTMF кода, подтверждения приема вызова.
Может состоять из одной или нескольких цифр. По умолчанию действует глобальная установка из раздела [general].

 declinecall=>2

Общее, по умолчанию '2', значение DTMF кода, отказа от ответа на вызов. По умолчанию, как задано в [general].

Назначить сообщения отличные от заданных по умолчанию в [general]

 call_from_prompt=>followme/call-from
 norecording_prompt=>followme/no-recording
 options_prompt=>followme/options
 pls_hold_prompt=>followme/pls-hold-while-try
 status_prompt=>followme/status
 sorry_prompt=>followme/sorry
Asterisk app: FollowMe

Приложение диалплана Asterisk для «умной» предустановленной переадресации вызова.

Описание

Данное приложение позволяет перевести вызывающего абонента на указанные номера. Команда ссылается на профили <followmeid> заданные в followme.conf. Если указанный <followmeid> не найден, приложение возвращает вызов и диалплан выполняется со следующего приоритета.

Возвращает '-1' при отбое.

синтаксис

FollowMe(followmeid[,options])

Аргументы
  • options
    • a: Записать имя вызывающего абонента для объявления вызываемой стороне.
    • B([[context^]exten^]priority[(arg1[^...][^argN])]): Перед выполнением исходящего вызова выполнить GoSub по указанному контексту, используя текущий канал.
    • b([[context^]exten^]priority[(arg1[^...][^argN])]): Перед выполнением исходящего вызова выполнить GoSub по указанному контексту, в новом канале.
    • d: Выключить объявление 'Please hold while we try and connect your call'
    • I: Игнорировать любые запросы на изменение текущего вызова.
    • l: Отключить оптимизацию локального вызова. Видимо равносильно действию опции '/n' канала Local (Local/${EXTEN}@from-internal/n).
    • N: Не отвечать на входящий вызов, пока мы не готовы соединить вызывающего абонента. Игнорируется если вызов уже отвечен (например командой Answer). Если вызов не отвечен опции 'a' и 's' игнорируется, в то время как опция 'd' считается включенной, даже если не задана явно.
    • n: Проиграть сообщение о недоступности абонента, если он отказался принимать вызов.
    • s: Проиграть 'The party you're calling isn't at their desk'до начала переадресации.
примеры

пример 1

extensions.conf:

exten => _4411,1,Answer
exten => _4411,2,Dial(SIP/${EXTEN},12,t)
exten => _4411,3,GotoIf($["${DIALSTATUS}" = "NOANSWER"]?:4:5)
exten => _4411,4,Followme(${EXTEN})
exten => _4411,5,VoiceMail(u${EXTEN})
exten => _4411,6,Hangup

followme.conf:

[4411]
context => default
number => 4410,30
number => 4420,30

пример 2:

extensions.conf:

exten => 1111,1,Dial(PJSIP/1111,15,tr)
exten => 1111,n,FollowMe(4444)
exten => 1111,n,Wait(1)
exten => 1111,n,Playback(beep)
exten => 1111,n,Goto(1)

exten => 2222,1,Dial(PJSIP/2222},15,tr)
exten => 2222,n,FollowMe(UserTest,san)
exten => 2222,n,Goto(4444,1)

exten => 4444,1,Dial(PJSIP/4444,15,tr)
exten => 4444,n,FollowMe(${EXTEN},s)
exten => 4444,n,Voicemail(UserTest)
exten => 4444,n,Hangup

followme.conf:

[4444]
music => default
context => default
number => 1965751234,5
number => 17182025678,20
number => 1234
number => 5678

[UserTest]
number => 09876&210,40,2 ; вызываются одновременно 09876 и 210 в течении 40-ка секунд.
number => 543,30,1 ; но сначала вызывается 543 в течении 30 секунд.

Пример 3: Follow-me без использования приложения app_followme

[incoming]
exten => 300,1,Answer()
exten => 300,2,Dial(DAHDI/1,30,grM(call-screening^${CALLERIDNUM}^${CONTEXT}^${EXTEN}^${PRIORITY}))
exten => 300,3,Hangup()
exten => 300,103,NoOp(${EXTEN}::${PRIORITY})
exten => 300,104,VoiceMail(u${EXTEN}@default)
exten => 300,105,Hangup()
exten => t,1,Playback(connection-timed-out)
exten => t,2,Playback(goodbye)
exten => t,3,Hangup()
[macro-call-screening]
exten => s,1,NoOp(${ARG2}::${ARG3}::${ARG4}::)
exten => s,2,Playback(vm-youhave)
exten => s,3,Playback(letters/a)
exten => s,4,Playback(call)
exten => s,5,Playback(from)
exten => s,6,SayDigits(${ARG1})
exten => s,7,Read(ACCEPTCALL|1-yes-2-no|1) ; (repeatoptions)
exten => s,8,GotoIf($["${ACCEPTCALL}" = ""] ?t,1)
exten => s,9,GotoIf($[${ACCEPTCALL} = 2] ?s,11)
exten => s,10,GotoIf($[${ACCEPTCALL} = 1] ?s,14:s,2)
exten => s,11,Set(NEWPRIORITY=$[${ARG4} + 101])
exten => s,12,Set(MACRO_RESULT=GOTO:${ARG2}^${ARG3}^${NEWPRIORITY})
exten => s,13,Goto(s,16);
exten => s,14,Playback(auth-thankyou)
exten => s,15,Set(MACRO_RESULT=)
exten => s,16,NoOp(End of macro)
exten => t,1,Playback(connection-timed-out)
exten => t,2,Goto(s,2)

см. также

Asterisk: followme.conf

 

IP АТС Asterisk и FreeSWITCH

$
0
0

IP АТС Asterisk и FreeSWITCH

Услуги по установке, настройке и обслуживанию Asterisk и FreeSwitch. Нами реализовано более 200 проектов, учитывая только Asterisk.

За годы работы, наши специалисты накопили большой опыт внедрения различных телекоммуникационных платформ, что позволяет, предлагать клиентам оптимальные решения и лучшее оборудование.

Базовая настройка IP АТС Asterisk

Для внедрения IP АТС небольшой емкости (до 100 абонентов), прекрасно подходит программная АТС Asterisk с веб интерфейсом FreePBX. Русскоязычный, простой и интуитивно понятный веб интерфейс позволит вам, в дальнейшем, обслуживать АТС без дополнительных затрат. Все используемое ПО является свободно распространяемым и вы платите только за пусконаладку. Приобретая базовую установку Asterisk вы гарантировано получаете:

Программное обеспечение и функционал:

  • Asterisk 14
  • FreePBX 13 - веб интерфейс настройки Asterisk
  • CDR-viewer - веб интерфейс записи и детализации вызовов
  • ARI (RESTful) и AMI - интерфейсы приложений.
  • Протоколы связи: SIP, IAX2, h323, DAHDI
  • Функции:
    • Очереди
    • Группы приема вызовов
    • Телеконференции
    • Автосекретарь
    • Маршрутизация вызовов
    • Переадресация вызовов
    • Факс-на-Емайл.
  • Операционная система: Centos 7 (Centos 6, Ubuntu или Debian - по требованию)

Базовая настройка IP АТС Asterisk:

  • Создание требуемого кол-ва IP абонентов
  • Подключение требуемого кол-ва SIP (или h323) транков к провайдеру IP телефонии.
  • Подключение потоков ISDN PRI E1.
  • Настройка входящей/исходящей маршрутизации по вашему ТЗ.
  • Настройка дневного/ночного режима
  • Настройка голосового меню (IVR)
  • Настройка групп приема вызовов.
  • Базовые настройки безопасности (IPtables и fail2ban)
  • Настройка приобретенного у нас оборудования (VoIP шлюзов, IP телефонов).
  • Консультации по настройке вашего оборудования.
  • Базовое обучение использования FreePBX для настройки Asterisk (Подключение IP абонентов, IP транков; создание очередей, телеконференций, голосовых меню, групп приема вызовов; использование сервисных кодов и отчетов о звонках.)
  • Бесплатная тех. поддержка в течении месяца с момента ввода в эксплуатацию.

Варианты установки:

  1. Удалённая установка/настройка на сервере заказчика.
  2. Установка на сервере заказчика.
  3. Установка/настройка на VPS хостинге
  4. Продажа сервера с установленной и настроенной системой.
  5. Embeddedустановка на устройства, например роутеры, поддерживающие работу с OpenWRT. Функционал может быть ограничен.

Расширенная настройка IP АТС Asterisk.

Базовая настройка Asterisk при помощи веб-интерфейса предоставляет большие возможности, намного превосходящие возможности традиционных АТС, но, отнюдь не полностью реализующие возможности Asterisk. Для систем большой емкости и самых продвинутых запросов мы предлагаем расширенную настройку. Полностью описать возможности и способы применения не под силу сжатому описанию, поэтому перечислим основные:

Реализация реалтайм архитектуры.

Под реалтайм в Asterisk подразумевается взаимодействие с базами данных и другими типами хранилищ в режиме реального времени. Поддерживается статическое хранение настроек Asterisk в БД и собственно реалтайм взаимодействие. -В первом случае, настройки получаются из хранилища в момент загрузки модуля или ядра АТС, так же как и при использовании конфигурационных файлов. -Во втором (реалтайм) настройки не требуют применения и доступны сразу, после внесения изменений. Также в Asterisk имеется большой набор команд и функций, для взаимодействия с реалтайм хранилищами в момент обработки вызова. В каких случаях применяется Реалтайм Архитектура?

  • для хранения большого количества SIP аккаунтов в базе данных.
  • для маршрутизации вызовов по большому числу условий (например по сотням тысяч def кодов).
  • для передачи и хранения статистической информации, например о работе очереди колл центра или данных передаваемых пользователями по телефону.
  • построения отказоустойчивых распределенных систем.

Поддерживаются следующие типы хранилищ: MySQL, PostgreSQL, SQLite, LDAP, нативно и через ODBC, а также прием и передача данных при помощи cURL. Предлагаем любые реализации реалтайм архитектуры Asterisk.

Взаимодействие со сторонними приложениями

Asterisk имеет три интерфейса (4-ре вместе Command Line Interface) для взаимодействия с другими приложениями:

  1. AMI - Asterisk manager Interface
  2. ARI - Asterisk RESTful Interface
  3. AGI - Asterisk Gateway Interface

Сами по себе интерфейсы в установленном Asterisk готовы к работе и не требуют серьезной настройки. Предлагаем консультации по работе с APIи ПО под нужды клиентов.

Шифрование TLS SRTP

Для подключения внешних пользователей к корпоративной телефонной сети, часто используется шифрование голосового трафика. Asterisk поддерживает шифрование протоколом SRTP с методом обмена ключами SDES через SDP. Предлагаем настройку защищенных телекоммуникационных систем.

Построение корпоративной телефонной сети АТС

Предлагаем построение распределенных телефонных систем, интеграцию с другими АТС через VoIP и ISDN протоколы связи, с единым номерным планом и централизованным управлением. Построение VPN сетей под нужды телефонии. На нашем счету проекты объединяющие по 50 филиалов в единую телефонную сеть. Наши специалисты подберут оптимальное оборудование, зарекомендовавшее себя в других проектах.

Настройка IP АТС FreeSWITCH

«Там, где пехота не пройдет…»
Кросс-платформенная много-пользовательская программная АТС FreeSWITCH зарекомендовала себя системой повышенной производительности. Более сложный в настройке и обслуживании, чем Asterisk, тем не менее, FS показывает вчетверо большую производительность, при потреблении равных ресурсов. Если абонентская емкость превышает 200 номеров, имеет смысл рассмотреть FreeSWITCH в качестве альтернативы.

  1. IP АТС большой емкости.
  2. Много-пользовательские системы с распределенными ресурсами.
  3. Виртуальные и облачные АТС.
  4. Сервер широкополосных телеконференций.
  5. Session Border Controller.
  6. Сервер маршрутизации и биллинга.
  7. Системы автоматического оповещения абонентов.

Мы предлагаем установку и настройку IP АТС FreeSWITCH в любой из указанных ролей. В базовую настройку входит установка и настройка отказоустойчивой системы FreeSWITCH,
с использованием СУБД PostgreSQL в качестве базы данных ядра и регистраций,
а также MySQL - для отчетов о звонках, с веб-интерфейсом поиска и прослушивания записей.
Диалплан - XML .
Для систем автообзвона, предлагаем установку и настройку Newfies-diаler + FreeSWITCH на Debian 8.
Для систем биллинга и маршрутизации - ASTPP billing.


Свяжитесь с нами для получения подробной информации.
Asterisk

Only edit this fieldset if “IP ATC” is set to “Asterisk”.

A X᠎ Q O​ A
FreeSWITCH

Only edit this fieldset if “IP ATC” is set to “FreeSWITCH”.

Настроим Asterisk, FreeSWITCH, IP АТС.

Asterisk + Fail2Ban

$
0
0

Asterisk + Fail2Ban

Установим требуемые пакеты

 wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm &&
 wget http://rpms.famillecollet.com/enterprise/remi-release-6.rpm &&
 rpm -Uvh remi-release-6*.rpm epel-release-6*.rpm
 yum install fail2ban
 yum install phyton iptables 

устаревшее

устаревшее

Создадим правила фильтрации

 touch /etc/fail2ban/filter.d/asterisk.conf
# Fail2Ban configuration file
#
#
# $Revision: 250 $
#

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
#before = common.conf


[Definition]

#_daemon = asterisk

# Option:  failregex
# Notes.:  regex to match the password failures messages in the logfile. The
#          host must be matched by a group named "host". The tag "<HOST>" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P<host>\S+)
# Values:  TEXT
#

failregex = NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Wrong password
            NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - No matching peer found
            NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Username/auth name mismatch
            NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Device does not match ACL
            NOTICE.* <HOST> failed to authenticate as '.*'$
            NOTICE.* .*: No registration for peer '.*' \(from <HOST>\)
            NOTICE.* .*: Host <HOST> failed MD5 authentication for '.*' (.*)
            NOTICE.* .*: Failed to authenticate user .*@<HOST>.*

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =

Синтаксис для Asterisk 1.6 отличается отсутствием номера порта '<HOST>'

failregex = NOTICE.* .*: Registration from '.*' failed for '<HOST>' - Wrong password
            NOTICE.* .*: Registration from '.*' failed for '<HOST>' - No matching peer found
            NOTICE.* .*: Registration from '.*' failed for '<HOST>' - Username/auth name mismatch
            NOTICE.* .*: Registration from '.*' failed for '<HOST>' - Device does not match ACL
            NOTICE.* <HOST> failed to authenticate as '.*'$
            NOTICE.* .*: No registration for peer '.*' \(from <HOST>\)
            NOTICE.* .*: Host <HOST> failed MD5 authentication for '.*' (.*)
            NOTICE.* .*: Failed to authenticate user .*@<HOST>.*

Fail2ban содержит правила и фильтры для Asterisk по умолчанию

/etc/fail2ban/filter.d/asterisk.conf

# Fail2Ban filter for asterisk authentication failures
#

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf

[Definition]

_daemon = asterisk

__pid_re = (?:\[\d+\])

# All Asterisk log messages begin like this:
log_prefix= (?:NOTICE|SECURITY)%(__pid_re)s:?(?:\[C-[\da-f]*\])? \S+:\d*( in \w+:)?

failregex = ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - (Wrong password|Username/auth name mismatch|No matching peer found|Not a local domain|Device does not match ACL|Peer is not su$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Call from '[^']*' \(<HOST>:\d+\) to extension '\d+' rejected because extension not found in context 'default'\.$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Host <HOST> failed to authenticate as '[^']*'$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s No registration for peer '[^']*' \(from <HOST>\)$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Host <HOST> failed MD5 authentication for '[^']*' \([^)]+\)$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Failed to authenticate (user|device) [^@]+@<HOST>\S*$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s (?:handle_request_subscribe: )?Sending fake auth rejection for (device|user) \d*<sip:[^@]+@<HOST>>;tag=\w+\S*$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s SecurityEvent="(FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)",EventTV="[\d-]+",Severity="[\w]+",Service="[\w]+",EventVersion="\d+",AccountID="\d*",SessionID="$
            ^(%(__prefix_line)s|\[\]\s*WARNING%(__pid_re)s:?(?:\[C-[\da-f]*\])? )Ext\. s: "Rejecting unknown SIP connection from <HOST>"$

ignoreregex =


# Author: Xavier Devlamynck / Daniel Black
#
# General log format - main/logger.c:ast_log
# Address format - ast_sockaddr_stringify
#
# First regex: channels/chan_sip.c
#
# main/logger.c:ast_log_vsyslog - "in {functionname}:" only occurs in syslog

устаревшее pjsip

устаревшее pjsip

Fail2ban PjSIP

# Fail2Ban filter for asterisk authentication failures
#

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf

[Definition]

_daemon = asterisk

__pid_re = (?:\[\d+\])

# All Asterisk log messages begin like this:
log_prefix= (?:NOTICE|SECURITY)%(__pid_re)s:?(?:\[C-[\da-f]*\])? \S+:\d*( in \w+:)?

failregex = ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - (Wrong password|Username/auth name mismatch|No matching peer found|Not a local domain|Device does not match ACL|Peer is not supposed to register|ACL error \(permit/deny\)|Not a local domain)$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Call from '[^']*' \(<HOST>:\d+\) to extension '\d+' rejected because extension not found in context 'default'\.$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Host <HOST> failed to authenticate as '[^']*'$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s No registration for peer '[^']*' \(from <HOST>\)$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Host <HOST> failed MD5 authentication for '[^']*' \([^)]+\)$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Failed to authenticate (user|device) [^@]+@<HOST>\S*$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s (?:handle_request_subscribe: )?Sending fake auth rejection for (device|user) \d*<sip:[^@]+@<HOST>>;tag=\w+\S*$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s SecurityEvent="(FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)",EventTV="[\d-]+",Severity="[\w]+",Service="[\w]+",EventVersion="\d+",AccountID="\d*",SessionID="0x[\da-f]+",LocalAddress="IPV[46]/(UD|TC)P/[\da-fA-F:.]+/\d+",RemoteAddress="IPV[46]/(UD|TC)P/<HOST>/\d+"(,Challenge="\w+",ReceivedChallenge="\w+")?(,ReceivedHash="[\da-f]+")?(,ACLName="\w+")?$
            ^(%(__prefix_line)s|\[\]\s*WARNING%(__pid_re)s:?(?:\[C-[\da-f]*\])? )Ext\. s: "Rejecting unknown SIP connection from <HOST>"$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Request from '.*' failed for '<HOST>(:[0-9]{1,5})?' (.*) - (No matching endpoint found)$
ignoreregex =


# Author: Xavier Devlamynck / Daniel Black
#
# General log format - main/logger.c:ast_log
# Address format - ast_sockaddr_stringify
#
# First regex: channels/chan_sip.c
#
# main/logger.c:ast_log_vsyslog - "in {functionname}:" only occurs in syslog

Регулярное выражение (RegEx) fail2ban, Asterisk 12 или 13, для сообщений от драйвера chan_pjsip

 ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Request from '.*' failed for '<HOST>(:[0-9]{1,5})?' (.*) - (No matching endpoint found)$

/etc/fail2ban/jail.conf

[asterisk]

enabled  = true
filter   = asterisk
action   = iptables-multiport[name=asterisk-tcp, port="5060,5061", protocol=tcp]
           iptables-multiport[name=asterisk-udp, port="5060,5061", protocol=udp]
           sendmail-whois[name=Asterisk, dest=root@localhost, sender=fail2ban@localhost]
logpath  = /var/log/asterisk/messages
maxretry = 3
bantime = 259200

Или jail.local

[asterisk-iptables]
enabled  = true
filter   = asterisk
action   = iptables-allports[name=SIP, protocol=all]
           sendmail[name=SIP, dest=root@localhost, sender=root@localhost]
logpath  = /var/log/asterisk/messages
maxretry = 5
bantime = 1800

<spoiler|устаревшее>

Добавим в файл jail.conf

/etc/fail2ban/jail.conf

[asterisk-iptables]

enabled  = true
filter   = asterisk
action   = iptables-allports[name=ASTERISK, protocol=all]
           sendmail-whois[name=ASTERISK, dest=root, sender=fail2ban@asterisk]
logpath  = /var/log/asterisk/messages
maxretry = 3
bantime = 259200

</spoiler>

Создадим отдельный лог для fail2ban

/etc/asterisk/logger_logfiles_custom.conf

  messages => notice,warning,error
  # asterisk -rx "logger rotate"

Cтартуем

 /etc/init.d/fail2ban start
 /etc/init.d/iptables start

если все в порядке

 chkconfig iptables on
 chkconfig fail2ban on

Посылаем некорректные запросы на авторизацию

 sipsak  -U  -s sip:s@192.168.0.1:5060
 sipsak  -U  -s sip:s@192.168.0.1:5060
 sipsak  -U  -s sip:s@192.168.0.1:5060

Смотрим iptables

 iptables -L
 Chain fail2ban-ASTERISK (1 references)
 target     prot opt source               destination
 DROP       all  --  192.168.0.22         anywhere
 RETURN     all  --  anywhere             anywhere     

Смотрим статус fail2ban

 fail2ban-client status asterisk-iptables
Status for the jail: asterisk-iptables
|- filter
|  |- File list:	/var/log/asterisk/secure
|  |- Currently failed:	0
|  `- Total failed:	3
`- action
   |- Currently banned:	1
   |  `- IP list:	192.168.0.22
   `- Total banned:	1

удалить правило из iptables

 iptables -D fail2ban-ASTERISK 1

дополнительно

Блокировка пакетов средствами IPtables по названию сканера

iptables -I INPUT -p udp --dport 5060 -m string --string "friendly-scanner" --algo bm -j DROP
iptables -I INPUT -p udp --dport 5060 -m string --string "sip-scan" --algo bm -j DROP
iptables -I INPUT -p udp --dport 5060 -m string --string "sundayddr" --algo bm -j DROP
iptables -I INPUT -p udp --dport 5060 -m string --string "iWar" --algo bm -j DROP
iptables -I INPUT -p udp --dport 5060 -m string --string "sipsak" --algo bm -j DROP
iptables -I INPUT -p udp --dport 5060 -m string --string "sipvicious" --algo bm -j DROP

banned examples

banned examples

Chain fail2ban-asterisk-udp (1 references)
target     prot opt source               destination
REJECT     all  --  ns304512.ip-94-23-212.eu  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  69.30.254.10         anywhere            reject-with icmp-port-unreachable
REJECT     all  --  178.32.131.44        anywhere            reject-with icmp-port-unreachable
REJECT     all  --  s18080713.onlinehome-server.info  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  192.187.109.154      anywhere            reject-with icmp-port-unreachable
REJECT     all  --  46.165.251.197       anywhere            reject-with icmp-port-unreachable
REJECT     all  --  212-129-55-216.rev.poneytelecom.eu  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  static-ip-188-138-120-135.inaddr.ip-pool.com  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  s18081076.onlinehome-server.info  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  212-129-54-198.rev.poneytelecom.eu  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  62-210-148-71.rev.poneytelecom.eu  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  195-154-34-157.rev.poneytelecom.eu  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  107.150.61.186       anywhere            reject-with icmp-port-unreachable
REJECT     all  --  h31-3-236-162.host.redstation.co.uk  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  107.150.52.234       anywhere            reject-with icmp-port-unreachable
REJECT     all  --  95.211.117.10        anywhere            reject-with icmp-port-unreachable
RETURN     all  --  anywhere             anywhere

Нажмите, чтобы отобразить

Нажмите, чтобы скрыть

Fail2Ban:
This is a pretty simple implementation, and can be done quickly. I have already setup an email relay on my Asterisk box to email me, so you may need to do that before hand or modify the settings slightly. I really enjoy being able to know by email what bad things are happening.
First, modify Asterisk to spit out errors in a separate log file:
Edit /etc/asterisk/logger.conf and:
– Un-comment the first dateformat line under [general]:

1
dateformat=%F %T   ; ISO 8601 date format
– Then, modify the messages line near the bottom and add security:

1
messages => security,notice,warning,error
Restart the Asterisk logger module to make the changes take effect:


sudo asterisk -rx "logger reload"
Now, install fail2ban:


sudo apt-get -y install fail2ban
Add the folowing to the end of /etc/fail2ban/jail.conf:


[asterisk-iptables]
# if more than 4 attempts are made within 6 hours, ban for 24 hours
enabled  = true
filter   = asterisk
action   = iptables-allports[name=ASTERISK, protocol=all]
              sendmail[name=ASTERISK, dest=dest@email.here, sender=fail2ban@address.here]
logpath  = /var/log/asterisk/security
maxretry = 4
findtime = 21600
bantime = 86400
Then, move the existing asterisk.conf in filter.d to a backup in the directory below (or wherever else you would like):


cd /etc/fail2ban/filter.d
sudo mv asterisk.conf ../asterisk.conf.orig
Create a new asterisk.conf in filter.d and add the following:

# Fail2Ban configuration file
#
#
# $Revision: 251 $
#

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf


[Definition]

#_daemon = asterisk

# Option:  failregex
# Notes.:  regex to match the password failures messages in the logfile. The
#          host must be matched by a group named "host". The tag "<HOST>" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P<host>\S+)
# Values:  TEXT
#
# Asterisk 1.8 uses Host:Port format which is reflected here

failregex = NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Wrong password
            NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - No matching peer found
            NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - No matching peer found
            NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Username/auth name mismatch
            NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Device does not match ACL
            NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Peer is not supposed to register
            NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - ACL error (permit/deny)
            NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Device does not match ACL
            NOTICE.* .*: Registration from '\".*\".*' failed for '<HOST>:.*' - No matching peer found
            NOTICE.* .*: Registration from '\".*\".*' failed for '<HOST>:.*' - Wrong password
            NOTICE.* <HOST> failed to authenticate as '.*'$
            NOTICE.* .*: No registration for peer '.*' \(from <HOST>\)
            NOTICE.* .*: Host <HOST> failed MD5 authentication for '.*' (.*)
            NOTICE.* .*: Failed to authenticate user .*@<HOST>.*
            NOTICE.* .*: <HOST> failed to authenticate as '.*'
            NOTICE.* .*: <HOST> tried  to authenticate with nonexistent user '.*'
            VERBOSE.*SIP/<HOST>-.*Received incoming SIP connection from unknown peer

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =
Restart fail2ban:

1
sudo service fail2ban restart

Asternic CDR Reports

$
0
0

Asternic CDR Reports

 asternic cdr stats

Приложение устанавливается в три клика, как локальный модуль FreePBX.
В отличии от стандартного CDR группирует вызовы по внутренним абонентам,
а также по входящим и исходящим вызовам.
Скачать Asternic CDR Reports

Как установить

После загрузки модуля необходимо войти в FreePBX, выберите Admin - Module Admin, а затем выберите опцию «Upload module». Вы должны выбрать файл, который вы только что скачали с вашего жесткого диска и нажмите кнопку «Upload».

После загрузки, нажмите на ссылку Manage Local Modules, прокрутите страницу вниз до раздела Отчеты, а затем нажмите на кнопку Asternic CDR Reports. После этого установите переключатель Installи, наконец, нажмите кнопку Proceedв самом низу страницы.

FreePBX Call Recordings + Asternic CDR Reports 1.5.1

Данная модификация включает отображение записей разговоров FreePBX
в модуле Asterisk CDR Reports Скачать asternic_cdr-1.5.1.tgz исправленный Скачать asternic_cdr-1.5.1.tgz исправленный

Читать дальше...

FreePBX Call Recordings + Asternic CDR Reports 1.5.1

$
0
0

FreePBX Call Recordings + Asternic CDR Reports 1.5.1

Данная модификация включает отображение записей разговоров FreePBX
в модуле Asterisk CDR Reports Скачать asternic_cdr-1.5.1.tgz исправленный Скачать asternic_cdr-1.5.1.tgz исправленный

код модификации

Замените файл:

/var/www/html/admin/modules/asternic_cdr/functions.inc.phpмодуля Asternic.

на файл именем с модифицированным кодом:

[root@localhost asternic_cdr]# ls -la | grep fu
-rw-r--r--  1 asterisk asterisk 16431 Feb 13 16:17 functions.inc.php
-rw-r--r--  1 asterisk asterisk 16163 Feb 13 16:16 functions.inc.php.bk
<?php

if(isset($_SERVER['PATH_INFO'])) {
    define("SELF",  substr($_SERVER['PHP_SELF'], 0, (strlen($_SERVER['PHP_SELF']) - @strlen($_SERVER['PATH_INFO']))));
} else {
    define("SELF",  $_SERVER['PHP_SELF']);
}

function asternic_cdr_get_config($engine) {
    // Executed on APPLY in FreePBX, we regenerate the fop2buttons if needed
    global $amp_conf, $db, $active_modules;


}

function asternic_cdr_query() {

    global $active_modules, $amp_conf, $db;

    $sql = "SELECT exten,privacy,label,`group`,email,channel,queuechannel,originatechannel,customastdb,spyoptions,external FROM fop2buttons";
    $results = $db->getAll($sql, DB_FETCHMODE_ASSOC);
    if(DB::IsError($results)) {
        die($results->getMessage());
    }
    foreach ($results as $result) {
        $fopprivacy[$result['exten']]   = $result['privacy'];
        $foplabel[$result['exten']]     = $result['label'];
        $fopgroup[$result['exten']]     = $result['group'];
        $fopemail[$result['exten']]     = $result['email'];
        $fopchannel[$result['exten']]   = $result['channel'];
        $fopqchannel[$result['exten']]  = $result['queuechannel'];
        $fopochannel[$result['exten']]  = $result['originatechannel'];
        $fopcustastdb[$result['exten']] = $result['customastdb'];
        $fopspyoption[$result['exten']] = $result['spyoptions'];
        $fopexternal[$result['exten']]  = $result['external'];
    }

}

function return_timestamp($date_string)
{
  list ($year,$month,$day,$hour,$min,$sec) = preg_split("/-|:| /",$date_string,6);
  $u_timestamp = mktime($hour,$min,$sec,$month,$day,$year);
  return $u_timestamp;
}

function swf_bar($values,$width,$height,$divid,$stack)
{
    global $config;

    if ($stack==1) {
        $chart = "images/barstack.swf";
    } else {
        $chart = "images/bar.swf";
    }
    $return = "<div id='$divid'>\n";
    $return.= "</div>\n";
    $values = html_entity_decode($values);
    $return.= "<script type='text/javascript'>\n";
    $return.='$(document).ready(function() {'."\n";

    $variables = split("&",$values);
    if(isset($config['no_animation'][''])) {
        $variables[] = "noanimate=1";
    }

    $return .= "var flashvars = {\n";
    $param = Array();
    foreach($variables as $deauna) {
        $pedazos = split("=",$deauna);
        $param[]="'$pedazos[0]': '$pedazos[1]'";
    }
    $texti = implode(",\n",$param);
    $return.=$texti;
    $return.=" };\n";

    $return.= "swfobject.embedSWF('$chart', '$divid', '$width', '$height', '9.0.0', '#336699', flashvars, {wmode:'transparent'});\n";
    $return.= "});</script>\n";
    echo $return;
}

function print_exports($header_pdf,$data_pdf,$width_pdf,$title_pdf,$cover_pdf) {
        global $lang;
        global $language;
        $head_serial = serialize($header_pdf);
        $data_serial = serialize($data_pdf);
        $width_serial = serialize($width_pdf);
        $title_serial = serialize($title_pdf);
        $cover_serial = serialize($cover_pdf);
        $head_serial = rawurlencode($head_serial);
        $data_serial = rawurlencode($data_serial);
        $width_serial = rawurlencode($width_serial);
        $title_serial = rawurlencode($title_serial);
        $cover_serial = rawurlencode($cover_serial);

        $complete_self = $_SERVER['REQUEST_URI'];
                //echo "<br/><form method=post action='modules/asternic_cdr/export.php'>\n";
        echo "<br/><form method='post' action='$complete_self'>\n";
        foreach($_REQUEST as $kkey=>$vval) {
                echo "<input type='hidden' name='$kkey' value='".$vval."' />\n";
        }
                echo "<input type='hidden' name='action' value='export' />\n";
                echo "<input type='hidden' name='head' value='".$head_serial."' />\n";
                echo "<input type='hidden' name='rawdata' value='".$data_serial."' />\n";
                echo "<input type='hidden' name='width' value='".$width_serial."' />\n";
                echo "<input type='hidden' name='title' value='".$title_serial."' />\n";
                echo "<input type='hidden' name='cover' value='".$cover_serial."' />\n";
                echo "<a href='javascript:void()' class='info'><input type=image name='pdf' src='images/asternic_pdf.gif' style='border:0;'><span>";
                echo _('Export to PDF');
                echo "</span></a>\n";
                echo "<a href='javascript:void()' class='info'><input type=image name='csv' src='images/asternic_excel.gif' style='border:0;'><span>";
                echo _('Export to CSV/Excel');
                echo "</span></a>\n";
                echo "</form>";
}

function seconds2minutes($segundos) {
    $horas    = intval($segundos / 3600);
    $minutos  = intval($segundos % 3600 ) / 60;
    $segundos = $segundos % 60;
    $ret = sprintf("%02d:%02d:%02d",$horas,$minutos,$segundos);

//    return "$minutos:$segundos";
    return $ret;
}

function remove_quotes($argument) {
    return substr($argument,1,-1);
}

function asternic_download($file) {
    include("download.php");
}

function asternic_getrecords( $MYVARS ) {
    global $active_modules, $amp_conf, $db;

    $channel = $MYVARS['channel'];
    $start   = $MYVARS['start'];
    $end     = $MYVARS['end'];
    $gtype    = $MYVARS['direction'];
    $condicionextra="";

    if($gtype=='outgoing') {
        $chanfield = "channel";
        $otherchanfield = "dstchannel";
    } else {
        $chanfield = "dstchannel";
        $otherchanfield = "channel";
    }

$query = "SELECT substring($chanfield,1,locate(\"-\",$chanfield,length($chanfield)-8)-1) AS chan1,";
//$query = "SELECT IF($chanfield like 'Local/%',CONCAT('SIP',RIGHT(substring(replace($chanfield,'-','/'),1,instr($chanfield,'@')-1),instr(reverse(substring(replace($chanfield,'-','/'),1,instr($chanfield,'@')-1)),'/'))),substring($chanfield,1,locate(\"-\",$chanfield,length($chanfield)-8)-1)) as chan1, ";
//$query.= "billsec,duration,duration-billsec as ringtime,src,";
//изменение
$query.= "billsec,duration,duration-billsec as ringtime,src,recordingfile,";
$query.="IF(dst='s',dcontext,dst) as dst,calldate,disposition,accountcode,userfield,uniqueid FROM asteriskcdrdb.cdr ";
$query.= "WHERE calldate >= '$start' AND calldate <= '$end' AND (duration-billsec) >=0 $condicionextra ";
$query.= "HAVING chan1 IN ('$channel') ORDER BY calldate";


$me=true;

$res = $db->query($query);

if(DB::IsError($res)) {
    die($res->getMessage());
}

$ftype = $_REQUEST['type'];
$fdisplay = $_REQUEST['display'];
$ftab = $gtype;

$cont=0;
while ($res->fetchInto($row, DB_FETCHMODE_ASSOC)) {

      if (!(substr($row['accountcode'],0,5)=='Local' && $dispo[$row['disposition']]=='BUSY' && $row[9]=='ResetCDR')) {
         $cont++;
         $disposition = $row['disposition'];

         if(!isset($detail[$row['chan1']])) {
             $detail[$row['chan1']]="";
         }

         $me = ! $me;
         if($me==true) {
             $odclass="class='odd'";
         } else {
             $odclass="";
         }
         $bill_print = seconds2minutes($row['billsec']);

         $detail[$row['chan1']].= "<tr $odclass>\n<td>$cont</td>\n";
         $detail[$row['chan1']].= "<td style='text-align: center;' >".$row['calldate']."</td>\n";
         $detail[$row['chan1']].= "<td>".$row['src']."</td><td>".$row['dst']."</td>\n";
         $detail[$row['chan1']].= "<td align=right>".$bill_print."</td>\n";
         $detail[$row['chan1']].="<td align=right>".$row['ringtime']." "._('secs')."</td>\n";
         $detail[$row['chan1']].= "<td style='text-align: center;'>";

         if($row['disposition']=="NO ANSWER" || $row['disposition']=="FAILED") {
            $detail[$row['chan1']].="<span style='color: red;'>";
         } elseif($row['disposition']=="BUSY") {
            $detail[$row['chan1']].="<span style='color: orange;'>";
         } else {
            $detail[$row['chan1']].="<span style='color: green;'>";
         }

          $detail[$row['chan1']].= $row['disposition'];
          $detail[$row['chan1']].= "</span></td>";
//изменение
if ($row['recordingfile']) {
            $rec_parts = explode('-',$row['recordingfile']);
            $fyear = substr($rec_parts[3],0,4);
            $fmonth = substr($rec_parts[3],4,2);
            $fday = substr($rec_parts[3],6,2);
            $monitor_base = $amp_conf['MIXMON_DIR'] ? $amp_conf['MIXMON_DIR'] : $amp_conf['ASTSPOOLDIR'] . '/monitor';
            $recordingfile = "$monitor_base/$fyear/$fmonth/$fday/" . $row['recordingfile'];
            if (!file_exists($recordingfile)) {
                $recordingfile = '';
                $detail[$row['chan1']].= "\n<td>";
            }
            else {
            $detail[$row['chan1']].= "\n<td style='text-align: center;' title=\"$row[recordingfile]\"><a href=\"".$PHP_SELF."?getRec=".base64_encode($recordingfile)."\" target=\"_blank\"><img src=\"images/asternic_playicon.png\" alt=\"Call recording\" /></a>";
            }
        } else {
            $recordingfile = '';
            $detail[$row['chan1']].= "\n<td>";
        }
          $detail[$row['chan1']].= "</td>\n";


//изменение
//          $detail[$row['chan1']].= "\n<td>";
//
//          $uni = $row['uniqueid'];
//          $uni = str_replace(".","",$uni);
//
//             if($row['userfield']<>"") {
//              $detail[$row['chan1']].="<a href=\"javascript:void(0);\" onclick='javascript:playVmail(\"".$row['userfield']."\",\"play".$uni."\");'>";
//              $detail[$row['chan1']].="<div class='playicon' title='Play' id='play".$uni."'  style='float:left;'>";
//              $detail[$row['chan1']].="<img src='images/blank.gif' alt='pixel' height='16' width='16' border='0'>";
//              $detail[$row['chan1']].="</div></a>";
//              $detail[$row['chan1']].="<a href=\"javascript:void(0); return false;\" onclick='javascript:downloadVmail(\"".$row['userfield']."\",\"play".$uni."\",\"$ftype\",\"$fdisplay\",\"$ftab\"); return false;'>";
//              $detail[$row['chan1']].="<div class='downicon' title='Download' id='dload".$uni."'  style='float:left;'>";
//              $detail[$row['chan1']].="<img src='images/blank.gif' alt='pixel' height='16' width='16' border='0'>";
//              $detail[$row['chan1']].="</div></a>";
//          } else {
//              $detail[$row['chan1']].= "&nbsp;";
//          }
//          $detail[$row['chan1']].= "</td>\n";
          $detail[$row['chan1']].= "\n</tr>\n";
      }

}

echo "<table width='99%' cellpadding=3 cellspacing=3 border=0 id='table${channel}' class='sortable'>\n";
echo "<thead><tr><td bgcolor='#ddcc00'>#</td>";
echo "<td bgcolor='#ddcc00' align='center'>"._('Date')."</td>\n";
echo "<td bgcolor='#ddcc00'>"._('From')."</td>\n";
echo "<td bgcolor='#ddcc00'>"._('To')."</td>\n";
echo "<td bgcolor='#ddcc00' align='right'>"._('Billable Time')."</td>\n";
echo "<td bgcolor='#ddcc00' align='right'>"._('Ring Time')."</td>\n";
echo "<td bgcolor='#ddcc00' align='center'>"._('Disposition')."</td>\n";
echo "<td bgcolor='#ddcc00' align='center'>"._('Listen')."</td></tr></thead>\n";
echo "<tbody>".$detail[$channel]."</tbody>\n";
echo "</table>\n";


$complete_self = $_SERVER['REQUEST_URI'];
echo "<form id='downloadform' method='get' action='$complete_self'><input type=hidden name='file' id='downloadfile' value=''><input type=hidden name='action' value='download'><input type='hidden' name='type' id='dtype' value=''><input type='hidden' id='idisplay' name='display' value=''> <input type='hidden' id='itab' name='tab' value=''></form>";

}


define('FPDF_FONTPATH',dirname(__FILE__).'/lib/font/');
include_once(dirname(__FILE__) . "/lib/fpdf.php");

class PDF extends FPDF
{

function Footer()
{
    global $lang;
    global $language;
    //Go to 1.5 cm from bottom
    $this->SetY(-15);
    //Select Arial italic 8
    $this->SetFont('Arial','I',8);
    //Print centered page number
    $this->Cell(0,10,$lang["$language"]['page'].' '.$this->PageNo(),0,0,'C');
}

function Cover($cover)
{
    $this->SetFont('Arial','',15);
    $this->MultiCell(150,9,$cover);
    $this->Ln();
}

function Header()
{
    global $title;
    //Select Arial bold 15
    $this->SetFont('Arial','B',15);
    //Move to the right
    $this->Cell(85);
    //Framed title
    $this->Cell(30,10,$title,0,0,'C');
    //Line break
    $this->Ln(10);
}

function TableHeader($header,$w)
{
    $this->SetFillColor(255,0,0);
    $this->SetTextColor(255);
    $this->SetDrawColor(128,0,0);
    $this->SetLineWidth(.3);
    $this->SetFont('','B',11);

    for($i=0;$i<count($header);$i++)
        $this->Cell($w[$i],10,$header[$i],1,0,'C',1);
    $this->Ln();
}

//Colored table
function FancyTable($header,$data,$w)
{

    $this->TableHeader($header,$w);

    //Color and font restoration
    $this->SetFillColor(224,235,255);
    $this->SetTextColor(0);
    $this->SetFont('');
    //Data
    $fill=0;
    $supercont=1;
    foreach($data as $row)
    {
        $contador=0;
        foreach($row as $valor) {
            $this->Cell($w[$contador],6,$valor,'LR',0,'C',$fill);
            $contador++;
        }
        $this->Ln();
        $fill=!$fill;
        if($supercont%40 == 0) {
            $this->Cell(array_sum($w),0,'','T');
            $this->AddPage();
            $this->TableHeader($header,$w);
            $this->SetFillColor(224,235,255);
            $this->SetTextColor(0);
            $this->SetFont('');
        }
        $supercont++;
    }
    $this->Cell(array_sum($w),0,'','T');
}
}

function asternic_export_csv($header,$data) {
    header("Content-Type: application/csv-tab-delimited-table");
    header("Content-disposition: filename=table.csv");

    $linea="";
    foreach($header as $valor) {
        $linea.="\"$valor\",";
    }
    $linea=substr($linea,0,-1);

    print $linea."\r\n";

    foreach($data as $valor) {
        $linea="";
        foreach($valor as $subvalor) {
            $linea.="\"$subvalor\",";
        }
        $linea=substr($linea,0,-1);
        print $linea."\r\n";
    }
}

function asternic_export($REQ) {

    $header = unserialize(rawurldecode($REQ['head']));
    $data   = unserialize(rawurldecode($REQ['rawdata']));
    $width  = unserialize(rawurldecode($REQ['width']));
    $title  = unserialize(rawurldecode($REQ['title']));
    $cover  = unserialize(rawurldecode($REQ['cover']));

    if(isset($_REQUEST['pdf']) || isset($REQ['pdf_x'])) {
        $pdf=new PDF();
        $pdf->SetFont('Arial','',12);
        $pdf->SetAutoPageBreak(true);
        $pdf->SetLeftMargin(1);
        $pdf->SetRightMargin(1);
        $pdf->AddPage();
        if($cover<>"") {
            $pdf->Cover($cover);
        }
        $pdf->AddPage();
        $pdf->FancyTable($header,$data,$width);
        $pdf->Output("export.pdf","D");
    } else {
        asternic_export_csv($header,$data);
    }
}

//изменение
function recordfile_uri($path) {
    $size = filesize($path);
    $name = basename($path);
    $extension = strtolower(substr(strrchr($name,"."),1));
    // This will set the Content-Type to the appropriate setting for the file
    $ctype ='';
    switch( $extension ) {
        case "WAV":
            $ctype="audio/x-wav";
            break;
        case "wav":
            $ctype="audio/x-wav";
            break;
        case "ulaw":
            $ctype="audio/basic";
            break;
        case "alaw":
            $ctype="audio/x-alaw-basic";
            break;
        case "sln":
            $ctype="audio/x-wav";
            break;
        case "gsm":
            $ctype="audio/x-gsm";
            break;
        case "g729":
            $ctype="audio/x-g729";
            break;
        default: //not downloadable
            // echo ("<b>404 File not found! foo</b>");
            // TODO: what to do if none of the above work?
        break ;
    }

  $fp=fopen($path, "rb");
  if ($size && $ctype && $fp) {
    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: public");
    header("Content-Description: audio file");
    header("Content-Type: " . $ctype);
    header("Content-Disposition: attachment; filename=" . $name);
    header("Content-Transfer-Encoding: binary");
    header("Content-length: " . $size);
    $chunksize = 1*(1024*1024);
    while (!feof($fp)) {
        $buffer = fread($fp, $chunksize);
        echo $buffer;
        ob_flush();
        flush();
    }
    fclose($fp);
  }
}
if(isset($_GET['getRec'])){
    recordfile_uri(base64_decode($_GET['getRec']));
    die();
}

?>

Источник, с подробными разъяснениями

FreePBX

Установка Asterisk 13 + FreePBX 12 Ubuntu 14

$
0
0

Установка Asterisk 13 + FreePBX 12 Ubuntu 14

Первоначальная настройка Ubuntu

При установке Ubuntu выберите обязательно OpenSSH server и LAMP сервер. Установите дополнительные пакеты на ваше усмотрение.

Ubuntu Software selection

В ходе установки системы вам будет предложено задать пароль root пользователя MySQL, если вы не уверены, можно отставить пустым. Если пароль задан, он потребуется в дальнейшем для работы с MySQL.

ubuntu root mysql password

Задайте пароль root пользователя системы

 $ sudo passwd root
 Enter new UNIX password:
 Retype new UNIX password:
 passwd: password update successfully

Переключитесь на root пользователя

 $ sudo -i

Сделайте апдейт системы

 # apt-get update && sudo apt-get upgrade -y

Установите требуемые зависимости

apt-get install -y build-essential linux-headers-`uname -r` openssh-server apache2 mysql-server\
  mysql-client bison flex php5 php5-curl php5-cli php5-mysql php-pear php-db php5-gd curl sox\
  libncurses5-dev libssl-dev libmysqlclient-dev mpg123 libxml2-dev libnewt-dev sqlite3\
  libsqlite3-dev pkg-config automake libtool autoconf git subversion unixodbc-dev uuid uuid-dev\
  libasound2-dev libogg-dev libvorbis-dev libcurl4-openssl-dev libical-dev libneon27-dev libsrtp0-dev\
  libspandsp-dev libiksemel-dev libiksemel-utils libiksemel3

Перезагрузите сервер

Это требуется чтобы загрузить свежую версию ядра после апгрейда. Если вы уверены что загруженная версия последняя, можно не перезагружаться.

 reboot

Установите PearDB

pear uninstall db
pear channel-update pear.php.net
pear install -Z db-1.7.14

Error: Error: cannot download &quot;pear/DB&quot;

Error: Error: cannot download &quot;pear/DB&quot;

Ошибка при установке DB (На данный момент, я не до разобрался в причине этой проблемы, но после танцев с бубном, все заработало.)

root@asterisk:/usr/src# pear install DB-1.7.14
WARNING: "pear/DB" is deprecated in favor of "pear/MDB2"
downloading DB-1.7.14.tgz ...
Starting to download DB-1.7.14.tgz (133,103 bytes)
.............................done: 133,103 bytes
could not extract the package.xml file from "/build/buildd/php5-5.5.9+dfsg/pear-build-download/DB-1.7.14.tgz"
Download of "pear/DB" succeeded, but it is not a valid package archive
Error: cannot download "pear/DB"
Download failed
install failed

Решение - установим вручную

Смотрим путь:

 pear config-get php_dir

В моем случае это:

/usr/share/php

Качаем DB 1.7.14

cd /usr/src/
wget   http://download.pear.php.net/package/DB-1.7.14.tgz
tar zvxf DB-1.7.14.tgz

Копируем вручную:

cp -R /usr/src/DB-1.7.14/DB  /usr/share/php/DB
cp /usr/src/DB-1.7.14/DB.php /usr/share/php/DB.php

Далее при вводе pear install db-1.7.14, получаем ответ что уже установлено.

root@asterisk:/usr/share/php# pear install db-1.7.14
pear/db is already installed and is the same as the released version 1.7.14
install failed

Установка Asterisk

Как использовать данное руководство.

Блоки команд с ключом '&&' могут быть скопированы вместе и будут выполняться последовательно. '&&' выполняет переход к следующей команде, при условии успешного выполнения предыдущей. Если вы хотите полностью, пошагово, контролировать процесс установки, выполните каждую команду отдельно, без ввода '&&'.

Скачайте исходные файлы

cd /usr/src
wget http://sourceforge.net/projects/lame/files/lame/3.98.4/lame-3.98.4.tar.gz &&
wget http://downloads.asterisk.org/pub/telephony/dahdi-linux-complete/dahdi-linux-complete-current.tar.gz &&
wget http://downloads.asterisk.org/pub/telephony/libpri/libpri-1.4-current.tar.gz &&
wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-13-current.tar.gz &&
git clone https://github.com/akheron/jansson.git &&
wget http://www.pjsip.org/release/2.2.1/pjproject-2.2.1.tar.bz2

ls -la /usr/src

ls -la /usr/src

root@ubuntu:/usr/src# ls -la
total 47960
drwxr-xr-x  5 root root     4096 Dec  9 11:18 .
drwxr-xr-x 10 root root     4096 Dec  9 09:55 ..
-rw-r--r--  1 root root 31832204 Nov 20 23:55 asterisk-13-current.tar.gz
-rw-r--r--  1 root root  7630719 Sep 22 23:20 dahdi-linux-complete-current.tar.gz
drwxr-xr-x  8 root root     4096 Dec  9 11:18 jansson
-rw-r--r--  1 root root  1336025 Apr 14  2010 lame-3.98.4.tar.gz
-rw-r--r--  1 root root   338633 Jun 16 21:50 libpri-1.4-current.tar.gz
drwxr-xr-x 24 root root     4096 Dec  9 09:57 linux-headers-3.13.0-32
drwxr-xr-x  7 root root     4096 Dec  9 09:57 linux-headers-3.13.0-32-generic
-rw-r--r--  1 root root  4628649 Dec  9 11:18 pjproject-2.2.1.tar.bz2

Скомпилируйте и установите Lame (mp3)

 cd /usr/src &&
 tar zxvf lame-3.98.4.tar.gz &&
 cd lame-3.98.4 &&
 ./configure &&
 make &&
 make install 

Скомпилируйте и установите DAHDI и LibPRI

cd /usr/src &&
tar xvfz dahdi-linux-complete-current.tar.gz &&
tar xvfz libpri-1.4-current.tar.gz &&
rm -f dahdi-linux-complete-current.tar.gz libpri-1.4-current.tar.gz &&
cd dahdi-linux-complete-* &&
make all &&
make install &&
make config &&
cd /usr/src/libpri-1.4.* &&
make &&
make install

kernel error

kernel error

Ошибка - отсутствуют исходники ядра

/usr/src/dahdi-linux-complete-2.10.0.1+2.10.0.1# make all
make -C linux all
make[1]: Entering directory `/usr/src/dahdi-linux-complete-2.10.0.1+2.10.0.1/linux'
make -C drivers/dahdi/firmware firmware-loaders
make[2]: Entering directory `/usr/src/dahdi-linux-complete-2.10.0.1+2.10.0.1/linux/drivers/dahdi/firmware'
make[2]: Leaving directory `/usr/src/dahdi-linux-complete-2.10.0.1+2.10.0.1/linux/drivers/dahdi/firmware'
You do not appear to have the sources for the 3.2.0-4-amd64 kernel installed.
make[1]: *** [modules] Error 1
make[1]: Leaving directory `/usr/src/dahdi-linux-complete-2.10.0.1+2.10.0.1/linux'
make: *** [all] Error 2 

Решение - установить исходники)

apt-get install linux-headers-`uname -r` 

Скомпилируйте и установите pjproject

(Требуется для поддержки драйвера SIP канала PjSIP)

cd /usr/src &&
tar -xjvf pjproject-2.2.1.tar.bz2 &&
cd pjproject-2.2.1 &&
CFLAGS='-DPJ_HAS_IPV6=1' ./configure --prefix=/usr --enable-shared --disable-sound\
  --disable-resample --disable-video --disable-opencore-amr &&
make dep &&
make &&
make install

Скомпилируйте и установите jansson

cd /usr/src/jansson &&
autoreconf -i &&
./configure &&
make &&
make install

Скомпилируйте и установите Asterisk

cd /usr/src &&
tar xvfz asterisk-13-current.tar.gz &&
rm -f asterisk-13-current.tar.gz &&
cd asterisk-* &&
./configure &&
contrib/scripts/get_mp3_source.sh &&
make menuselect

После ввода команды make menuselect, вам будет предложено выбрать устанавливаемые модули. Большинство требуемых модулей выбираются автоматически. Для поддержки mp3 включите модуль 'format_mp3'.

make menuselect format_mp3

В разделе Core Sound Packages выберете поддержку русскоязычных файлов (если требуется)

make menuselect ru sound

В разделе Extra Sound Packages выберете дополнительные звуковые файлы.

В завершении выберете Save & Exitи продолжите установку.

make &&
make install &&
make config &&
ldconfig

Установка и настройка FreePBX

Скачайте и распакуйте FreePBX.

cd /usr/src &&
wget http://mirror.freepbx.org/freepbx-12.0.43.tgz &&
tar zxvf freepbx-*.tgz &&
cd /usr/src/freepbx

при установке из гит репозитория возникает ошибка:missing modgettext.class.php

при установке из гит репозитория возникает ошибка:missing modgettext.class.php

при установке из гит репозитория возникает ошибка:missing modgettext.class.php (incomplete application of changeset 12995?) поэтому лучше скачивать архив.

export VER_FREEPBX=12.0 &&
cd /usr/src &&
git clone http://git.freepbx.org/scm/freepbx/framework.git freepbx &&
cd freepbx &&
git checkout release/${VER_FREEPBX}

Создайте пользователя Asterisk и задайте права пользователя.

useradd -m asterisk &&
chown asterisk. /var/run/asterisk &&
chown -R asterisk. /etc/asterisk &&
chown -R asterisk. /var/{lib,log,spool}/asterisk &&
chown -R asterisk. /usr/lib/asterisk

remove /var/www/html

remove /var/www/html

Далее в руководстве freepbx.org, предлагается удалить директорию веб сервера:
Удалять директорию /var/www/html может быть опасно для ваших данных.

 rm -rf /var/www/html

Это делается, т.к. при установке FreePBX скриптом, если папка существует, появляется сообщение о ошибке, что может быть исправлено, просто, повторным запуском скрипта установки.

Настроим Apache

sed -i 's/\(^upload_max_filesize = \).*/\120M/' /etc/php5/apache2/php.ini &&
sed -ie 's/\;date\.timezone\ \=/date\.timezone\ \=\ "Europe\/Moscow"/g' /etc/php5/apache2/php.ini &&
cp /etc/apache2/apache2.conf /etc/apache2/apache2.conf_orig &&
sed -i 's/^\(User\|Group\).*/\1 asterisk/' /etc/apache2/apache2.conf &&
sed -i 's/AllowOverride None/AllowOverride All/'  /etc/apache2/apache2.conf &&
service apache2 restart

AllowOverride All

AllowOverride All

root@aster:~# cat  /etc/apache2/apache2.conf | grep AllowOverride
        AllowOverride None
        AllowOverride None
        AllowOverride None
#       AllowOverride None
 root@aster:~# sed -i 's/AllowOverride None/AllowOverride All/'  /etc/apache2/apache2.conf
root@aster:~# cat  /etc/apache2/apache2.conf | grep AllowOverride
        AllowOverride All
        AllowOverride All
        AllowOverride All
#       AllowOverride All
# create the configuration file in the "available" section

echo "ServerName localhost" | sudo tee /etc/apache2/conf-available/servername.conf

# enable it by creating a symlink to it from the "enabled" section

a2enconf servername
# restart the server

service apache2 restart

Подготовим MySQL

Требуется создать безопасный пароль для связи FreePBX и MySQL

 export ASTERISK_DB_PW=`dd if=/dev/urandom bs=1 count=32 2>/dev/null | base64 - | cut -c2-18`

Эта команда сгенерирует 16-ти значный пароль и сохранит значение в переменной {ASTERISK_DB_PW}.

Подготовка базы данных Asterisk в MySQL.

Если вы задали 'root' пароль MySQL при установке, добавьте его после ключа -pyourpassword. (mysqladmin -u root -pYOURPASSWORD create asterisk)

 mysqladmin -u root create asterisk
 mysqladmin -u root create asteriskcdrdb

Зададим права на использование БД MySQL

Замените asteriskuserна имя пользователя, которое вам нравится. Например: YOURUSER@localhost. Можно оставить как есть.

 mysql -u root -e "GRANT ALL PRIVILEGES ON asterisk.* TO asteriskuser@localhost IDENTIFIED BY '${ASTERISK_DB_PW}';"
 mysql -u root -e "GRANT ALL PRIVILEGES ON asteriskcdrdb.* TO asteriskuser@localhost IDENTIFIED BY '${ASTERISK_DB_PW}';"
 mysql -u root -e "flush privileges;"

Запустим Asterisk и установим FreePBX.

Если в предыдущем пункте вы задали собственное имя пользователя, замените asteriskuserна него. Например: –username=YOURUSER

./start_asterisk start
./install_amp --installdb --username=asteriskuser --password=${ASTERISK_DB_PW}

Если выполнение скрипта прерывается и появилось сообщение о ошибке, попробуйте запустить установку ещё раз.

amportal

amportal

...
*************************************************************************
* Note: It's possible that if you click the red 'Update Now' bar BEFORE *
* updating your modules, your machine will start dropping calls. Ensure *
* that all modules are up to date BEFORE YOU CLICK THE RED BAR. As long *
* as this is observed, your machine will be fully functional whilst the *
* upgrade is in progress.                                               *
*************************************************************************
****************************************
* At This Time Please Restart Asterisk *
****************************************
amportal a ma download manager
amportal a ma install manager
amportal a ma installall
amportal a ma refreshsignatures
amportal a reload
amportal chown

В завершении настроим создадим ссылку на директорию Music On Hold формата mp3

 ln -s /var/lib/asterisk/moh /var/lib/asterisk/mohmp3

и запустим amportal

 amportal start

Поверим состояние Asterisk подключившись к консоли

 asterisk -vvr
Asterisk 13.0.1, Copyright (C) 1999 - 2014, Digium, Inc. and others.
Created by Mark Spencer <markster@digium.com>
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type 'core show license' for details.
=========================================================================
Connected to Asterisk 13.0.1 currently running on ubuntu (pid = 24513)
ubuntu*CLI>core restart now

Подключимся к FreePBX

http://IP.Address.FreePBX.Server/admin

Первым делом, вам будет предложено задать имя пользователя и пароль FreePBX

freepbx start set user login

Чтобы работало переключение на русский язык в панели управления, необходимо отредактировать файл /etc/locale.alias. Ищем строку russian ru_RU.ISO-8859-5 и правим ее.

nano +67 /etc/locale.alias

 russian ru_RU.UTF-8

или sed:

 sed -i 's/ru_RU.ISO-8859-5/ru_RU.UTF-8/g'   /etc/locale.alias
 locale-gen ru_RU
 service apache2 restart

См. также:
Установка Freepbx 13 и Asterisk 14 на Ubuntu 16

Установка Asterisk

Настройка оборудования

$
0
0

Downloads

$
0
0

Asterisk res_pjsip_acl

$
0
0

Asterisk res_pjsip_acl

SIP ACL module

Документация по конфигурации и использованию функций модуля res_pjsip_acl. ACLмодуль используется res_pjsip. Данный модуль не зависит от ENDPOINTs и управляет всеми входящими подключениями через res_pjsip. Есть два основных способа назначить ACLпри помощи соответствующих опций. Можно использовать привычные 'permit' и 'deny', которые действуют в отношении IP адресов. Или 'contactpermit' и 'contactdeny', которые действуют на основании адреса из заголовка 'Contact' входящего SIP запроса REGISTER. Возможно комбинировать разные опции и создавать смешанный списки контроля доступа (ACL). В добавление к этому, вместо назначения ACLс помощью опций, можно задать адреса IP или заголовки Contact ACLв файле Asterisk:acl.confпри помощи 'acl' и 'contactacl' опций.

pjsip.conf
acl
Access Control List - Список Контроля Доступа

Опции конфигурации res_pjsip_acl

Option NameTypeRegular ExpressionDescription
aclCustomfalseИмя секции в acl.confдля контроля по IP
contact_aclCustomfalseИмя секции в acl.conf для контроля по заголовку Contact
contact_denyCustomfalseСписок запрещенных адресов Contact header
contact_permitCustomfalseСписок разрещенных адресов Contact header
denyCustomfalseСписок запрещенных IP адресов
permitCustomfalseСписок разрешенных IP адресов
typeNonefalseТип секции. всегда - 'acl'.

Описание конфигурационных опций

acl

Соответствует разделам настроенным в файле «acl.conf». Принимает значение в виде списка имен разделов через запятую.

 acl=your_named_acl,your_named_acl2  
contact_acl

Соответствует разделам настроенным в файле «Asterisk:acl.conf». Принимает значение в виде списка имен разделов через запятую.

contact_deny
 contact_deny=0.0.0.0/0.0.0.0

Принимает значение списка IP адресов через запятую. К IP адресам может быть добавлена маска подсети через слэш (/).

contact_permit
 contact_permit=2.2.2.2/2.2.2.2,1.1.1.1
deny

deny=0.0.0.0/0.0.0.0

permit

Asterisk sip.conf General SIP Options

$
0
0

Asterisk sip.conf General SIP Options

Полный список параметров general sip.conf

Следующие параметры используются в общей [general] секции sip.conf:

allowexternalinvites

Если установлено 'no', запрещает INVITE и REFER от внешних (не из localnet) доменов. См domain

 allowexternalinvites=yes|no

allowguest

Если 'no', запрещает гостевые(без аутентификации) подключения. По умолчанию sipguest подключения разрешены.

 allowguest=no|yes

allowoverlap

Вкл. или Выкл набор по одной цифре (т.е. каждая набранная цифра будет сразу отправляться в канал)

 allowoverlap=no|yes

allowsubscribe

Разрешить ли внешним устройствам подписку (SUBSCRIBE) на информацию о статусе екстеншена. По умолчанию - 'yes':

 allowsubscribe=yes|no

allowtransfers

Когда установлено 'no', запрещает любые трансферы, если не переопределено в настройках пира.

 allowtransfers=no|yes

alwaysauthreject

Если включено, всегда отвечает на INVITE и REGISTER, SIP сообщением 401 Unauthorized, вместо того чтобы сообщить вызывающему о существовании запрашиваемого user или peer. Важная настройка безопасности

alwaysauthreject=no|yes

autodomain

Установите эту опцию 'yes', чтобы добавить локальное HOSTNAME и локальный IP адрес в список доменов:

 autodomain=yes|no

bindaddr and bindport

Эти параметры определяют IP адрес и порт на которых Asterisk будет слушать SIP запросы. Для драйвера канала SIP Asterisk 'chan_sip' можно назначить только один адрес и порт для всех подключений для UDP и один порт для TCP транспорта, в отличии от нового драйвера PJSIP. По умолчанию адрес не задан и лучше так и оставить. Некоторые рекомендуют изменять порт по умолчанию 5060, на другой, в целях безопасности. Но помните, что это только одна из мер безопасности, не самая важная, и не гарантирует вам полной защиты от злоумышленников.

bindaddr=0.0.0.0
bindport=5060

Вы можете задать независимые для UDP, TCP и TLS транспорта значения udpbindadd, tcpbindaddrи tlsbindaddr

buggymwi

Вкл. эту опцию, чтобы избежать ошибок при сообщении с некоторыми ip телефонами при отправке MWI сообщений.

buggymwi=no|yes

callevents

Установите 'yes', если хотите генерировать информацию о SIP событиях для AMI (asterisk manager interface)

 callevents=yes

checkmwi

Время в секундах, между проверками голосовой почты :

 checkmwi=30

compactheaders

Использовать или нет компактные SIP заголовки.

 compactheaders=yes|no

defaultexpiry

Срок действия регистрации в секундах для входящих и исходящих регистраций. При входящей регистрации, этот параметр задается клиентской стороной, и заданное здесь значение используется, только если клиент не сообщил свое занчение. Для исходящих регистраций этот параметр сообщается удаленной стороне UAS (user agent server)

 defaultexpiry=300

directrtpsetup

Данная опция позволяет управлять RTP соединением между двумя оконечными точками без re-INVITE(экспериментальная опция, используйте на свой страх и риск).

 directrtpsetup=yes|no

domain

Задает имя домена сервера Asterisk по умолчанию. Командой CLI 'sip show domains' выводится список локальных доменов.

 domain=example.com

dumphistory

Вкл. или Выкл. отчет в завершении SIP диалога. SIP history выводится в DEBUG лог канала.

 dumphistory=yes|no

externhost

Когда Asterisk находится за NAT, SIP заголовок обычно использует IP адрес сервера. Если включить данную опцию, Asterisk будет производить периодические DNSопросы для определения имени хоста и заменять IP адрес на 'externhost'.

 externhost=my.hostname.tld

Используйте externip.

externip

externip содержит IP адрес в качестве аргумента. Если Asterisk находится за NAT, SIP заголовок Contact: содержит внутренний IP адрес сервера, тогда удаленная сторона не знает куда отправлять ответы. Параметр externip вкупе с параметром nat=force_rport модифицирует SIP заголовок, сообщая удаленному SIP серверу адрес на который надо слать ответы:

 externip=123.123.123.123

externrefresh

Если все же используется 'externhost', указывает промежуток времени в секундах между запросами DNS.

 externrefresh=30

g726nonstandard

Значения: yes/no, по умолчанию: no. Если клиент собирается для сеанса связи «договориться» использовать звуковой кодек G726-32, с использованием компрессии AAL2, вместо RFC3551 (что требуется для аппаратов фирмы Sipura и шлюзов от Grandstream, и может другим). То это противоречит спецификации RFC3551, клиент должен вместо этого «договориться» использовать AAL2-G726-32

 g726nonstandard=yes

ignoreregexpire (global)

Если ignoreregexpire установлен 'yes', Asterisk сделает одно из двух, в зависимости от настроек пиров: 1)Non-realtime peer Когда регистрация истекает, информация не удаляется из памяти или БД Asterisk и вызовы будут разрешены несмотря на то, что время регистрации истекло.

2)Realtime peers Когда peer сконфигурирован в режиме реального времени, информация о регистрации используется независимо от defaultexpiry

 ignoreregexpire=yes|no

jbenable

Вкл. поддержку RTP jitter buffer на принимающей стороне канала SIP. По умолчанию 'no'. Будет работать, только если удаленная сторона поддерживает эту функцию. подробнее о Джиттер

 jbenable=yes|no

jbforce

Принудительное использование jitter buffer принимающей стороной SIP канала.

 jbforce=yes|no

jbimpl

Использовать фиксированный или подстраиваемый (адаптивный) jitter buffer. fixed jitter buffer всегда использует значение из jbmaxsize adaptive может принимать значение больше jbmaxsize По умолчанию 'fixed':

 jbimpl=fixed|adaptive

Из личного опыта, вкл. 'adaptive' может приводить к весьма плачевным результатам.

jblog

Вкл./выкл jitter buffer frame лог. По умолчанию 'no':

 jblog=yes|no

jbmaxsize

Установите максимальную длину буфера в миллисекундах:

 jbmaxsize=200

jbresyncthreshold

Джиттер буфер порог синхронизации. По умолчанию 1000:

 jbresyncthreshold=1000

icesupport

Использовать Interactive Connectivity Establishment (ICE) в Asterisk

 icesupport=no

limitonpeers

Применять call-limit только для type=peer Это улучшит использование call-limit для устройств настроенных, как type=friend, отделив ограничение call-limit от входящих вызовов.

 limitonpeers=yes|no

localnet

укажет серверу Asterisk какие подсети являются локальными, прозрачными для использования IP адресов сервера, SIP запросы к которым не требуют модификации поля Contact: c использованием externipили externhost

 localnet=192.168.1.0/24
 localnet=172.16.0.0/16

matchexterniplocally

Сверять 'externip' с 'localnet' и производить подстановку, только если 'externip' из локальной подсети. Не совсем ясно, зачем это может понадобиться? Возможно при очень нестандартной топологии сети.

 matchexterniplocally=yes|no

maxexpiry

Максимальная продолжительность регистрации в секундах.

 maxexpiry=3600

minexpiry

Минимальная продолжительность регистрации в секундах.

 minexpiry=60

notifymimetype

Указывает MIME тип используемый для message-waiting indication (MWI) в SIP NOTIFY сообщении.

 notifymimetype=text/plain

notifyringing

Сообщать подписчикам о состоянии вызов (RINGING):

 notifyringing=yes|no

notifyhold

Сообщать подписчикам (subscribers) о состоянии удержание (HOLD):

 notifyhold=yes|no

pedantic

Скурпулезная проверка SIP сообщений. Устанавливает более строгую проверку по стандартам SIP RFC.

 pedantic=yes

realm

Данная установка используется для аутентификации в SIP. Задайте realm полное доменное имя вашего сервера. Имя должно быть совершенно уникальным.

 realm=mybox.example.com

recordhistory

Вкл. или Выкл историю sip для всех каналов.

 recordhistory=yes|no

registerattempts

Сколько попыток внешних регистраций произведет Asterisk, прежде чем откажется от продолжения. По умолчанию стоит '0', что значит бесконечно.

 registerattempts=0

registertimeout

Таймаут между попытками регистрации на другом устройстве.

 registertimeout=30

relaxdtmf

Если плохо распознаются DTMF сигналы, включите данную опцию.

 relaxdtmf=yes|no

rtautoclear

(global)Конфигурация Realtime Peers Указывает должен ли Asterisk обнулять созданные на лету friends по истечении времени регистрации. Если установлено 'yes', по истечении срока регистрации, удалять friends до нового запроса. Если задано число, то оно используется вместо обычного времени регистрации.

rtautoclear=yes|no|seconds

rtcachefriends

(global)

Если rtcachefriends включен, Asterisk будет кэшировать friends(реалтайм пиры), которые приходят из realtime engine, так же, как если бы они сконфигурированы в «sip.conf».

 rtcachefriends=yes|no

rtsavesysname

(global) Определяет, должен ли Asterisk сохранить SystemName в базе данных в режиме реального времени во время регистрации:

 rtsavesysname=yes|no

rtupdate

(global) Если установлено 'yes' Asterisk будет обновлять IP-адрес, порт и период регистрации пиров при регистрации. По умолчанию 'yes':

 rtupdate=yes|no

sipdebug

Указывает, должен или нет Asterisk включать SIP debug сразу при загрузке драйвера канала SIP.

 sipdebug=yes|no

sendrpid

ОТправлять или нет Remote-Party-ID header:

 sendrpid=yes|no

srvlookup

Записи DNS SRV являются одним из способов указания адреса для связи сервером. Используя записи SRV, вы получаете многие преимущества DNS, в то время как отключения SRV DNSлишает вас возможности принимать SIP вызовы на основании доменных имен. В настоящее время поддержка записей SRV в Asterisk несколько хромает. Если несколько записей SRV возвращаются, Asterisk будет использовать только первую запись. Чтобы включить, установите srvlookup = yes в секции [general] файла sip.conf:

 srvlookup=yes

transport

Задает транспорт по умолчанию. По умолчанию 'udp', но может быть 'tcp', 'tls', 'ws' или 'wss'.Если задано TCP а tcpenable=no будет использован UDP транспорт.

transport=udp

tcpenable

Включить поддержку TCP транспорта chan_sip Asterisk.

 tcpenable=yes

tcpbindaddr

Адрес на котором Asterisk «слушает» TCP подключения.

  IPv4 example: bindaddr=0.0.0.0:5062
  IPv6 example: bindaddr=[::]:5062

tcpauthtimeout

tcpauthtimeout указывает максимальное время в секундах данное клиенту на аутентификацию. Если за заданное время клиент не прошел проверку он отключается. (По умолчаннию 30 секунд)

 tcpauthtimeout = 30

tcpauthlimit

Максимальное кол-во неаутентифицированных сессий в момент любой времени.

 tcpauthlimit = 100

t1min

Минимальная задержка туда-обратно (minimum round-trip) для сообщения контролируемого хоста. По умолчанию 100 миллисеунд:

 t1min=100

subscribecontext

Ограничить запросы SUBSCRIBE только указанным контекстом, если не переопределено в настройках пира.

 subscribecontext=internal

t38pt_udptl

Установка t38pt_udptl 'yes' вкл. T.38 fax (UDPTL) насквозь (passthrough) для SIP-to-SIP вызовов с поддержкой T.38. Эта настройка включается глобально для всех устройств, но вы можете отключить её для конкретного устройства.

 t38pt_udptl=yes|no

T.38 fax passthrough работает только для SIP-to-SIP вызовов, любые local или agent каналы не могут быть использованы.

tos_sip, tos_audio, andtos_video

Asterisk может установить TOS bits в IP заголовках для помощи маршрутизаторам приотеризации трафика. tos_sip, tos_audio, и tos_video установки управляют TOS битами для SIP сообщений, RTP аудио и RTP видео, соответственно. Поддерживаются: CS0, CS1, CS2, CS3, CS4, CS5, CS6, CS7, AF11, AF12, AF13, AF21, AF22, AF23, AF31, AF32, AF33, AF41, AF42, AF43. Можно также использовать цифровые значения для TOS битов.

trustrpid

Доверять или нет Remote-Party-ID header: Asterisk SIP trustrpid

 trustrpid=yes|no

useragent

Значение поля useragent в SIP заголовке. По умолчанию версия Asterisk:

 useragent=Asterisk PBX v14.6.0

Если вы не желаете сообщать, что используете Asterisk, напишите Cisco или Avaya, или abyrvalg v2.0.

usereqphone

usereqphone опция говорит Asterisk добавить «user=phone» в SIP URIs которые содержат действующий номер телефона:

usereqphone 

videosupport

Команда Asterisk: MixMonitor

$
0
0

Команда Asterisk: MixMonitor

Приложение Asterisk записи разговора и микширования аудио двух каналов (приемника и передатчика).

Описание
Записывает аудио текущего соединения в указанный файл.
Это приложение не отвечает само на вызов и требует предварительного выполнения answerили progress

Используйте также приложение StopMixMonitor, чтобы получить доступ к записанному файлу, пока обработка диалплана записываемого вызова не завершена.

примечание: MixMonitor запускается как audiohook.

${MIXMONITOR_FILENAME}: Содержит имя созданного файла.

Синтаксис

MixMonitor(filename.extension[,options[,command]])

Аргументыfilename - Имя записываемого файла. Если не содержит абсолютный путь, то помещается в директорию, определенную по умолчанию в конфиге asterisk.conf

options

  • a: Добавить файл, а не перезаписывать, если существует.
  • b: Сохранять аудио, только если установлено соединение. Если эта опция используется для канала Local, используйте опцию '/n', чтобы обеспечить корректную работу. Например:Dial(Local/start@mycontext/n)
  • v(x): Регулировать «слух» по значению <x> (диапазон от '-4' до '4')
  • V(x): Регулировать «речь» по значению <x> (диапазон от '-4' до '4')
  • W(x): Регулировать «слух и речь» по значению <x> (диапазон от '-4' до '4')

«heard and spoke» - имеются ввиду входящий и исходящий медиа(аудио) потоки по отношению к инициатору вызова.

  • r(file): Записать принимаемыйаудио поток в указанный файл. Как и для основного файла, директория определяется в либо абсолютным путем к файлу, либо по умолчанию, в директорию monitorсм. asterisk.conf
  • t(file): Записать передаваемый аудио поток в указанный файл.
  • i(chanvar): Сохранить MixMonitorsID в указанной переменной (chanvar) .
  • m(mailbox): Создать копию файла, как файл голосовой почты для заданных голосовых ящиков, перечисленных через запятую, вида:m(1111@default,2222@default,…). Директория, необязательный параметр, может быть задана как: m(mailbox@context/folder).

command - Будет выполнена по завершению записи. Любая строка вида '^{X}' будет рассматриваться как ${X}. Все переменные будут установлены в момент вызова MixMonitor.

См. Также

<spoiler>

[sub-record-check]
exten => s,1,GotoIf($[${LEN(${FROMEXTEN})}]?initialized)
exten => s,n,Set(__REC_STATUS=INITIALIZED)
;exten => s,n,Set(NOW=${EPOCH})
;exten => s,n,Set(__DAY=${STRFTIME(${NOW},,%d)})
;exten => s,n,Set(__MONTH=${STRFTIME(${NOW},,%m)})
;exten => s,n,Set(__YEAR=${STRFTIME(${NOW},,%Y)})
;exten => s,n,Set(__TIMESTR=${YEAR}${MONTH}${DAY}-${STRFTIME(${NOW},,%H%M%S)})
;exten => s,n,Set(__FROMEXTEN=${IF($[${LEN(${AMPUSER})}]?${AMPUSER}:${IF($[${LEN(${REALCALLERIDNUM})}]?${REALCALLERIDNUM}:unknown)})})
;exten => s,n,Set(__MON_FMT=${IF($["${MIXMON_FORMAT}"="wav49"]?WAV:${MIXMON_FORMAT})})
exten => s,n(initialized),Noop(Recordings initialized)
exten => s,n,ExecIf($[!${LEN(${ARG3})}]?Set(ARG3=dontcare))
exten => s,n,Set(REC_POLICY_MODE_SAVE=${REC_POLICY_MODE})
exten => s,n,ExecIf($["${BLINDTRANSFER}${ATTENDEDTRANSFER}" != ""]?Set(REC_STATUS=NO))
exten => s,n(next),GotoIf($[${LEN(${ARG1})}]?checkaction)
exten => s,n(recorderror),Playback(something-terribly-wrong,error)
exten => s,n,Hangup
exten => s,n(checkaction),GotoIf($[${DIALPLAN_EXISTS(sub-record-check,${ARG1})}]?sub-record-check,${ARG1},1)
exten => s,n,Noop(Generic ${ARG1} Recording Check - ${FROMEXTEN} ${ARG2})
exten => s,n,Gosub(recordcheck,1(${ARG3},${ARG1},${ARG2}))
exten => s,n,Return()



exten => recordcheck,1,Goto(${ARG1})
exten => recordcheck,n(dontcare),return
exten => recordcheck,n(no),return
exten => recordcheck,n(never),return
exten => recordcheck,n(always),goto(reccc)
exten => recordcheck,n(force),goto(reccc)
exten => recordcheck,n(yes),goto(reccc)
exten => recordcheck,n(reccc),Set(WAV=/var/spool/asterisk/monitor/${UNIQUEID})
exten => recordcheck,n,Set(MP3=/var/spool/asterisk/monitor/mp3/${UNIQUEID})
exten => recordcheck,n,Set(monopt=nice -n 19 /usr/local/bin/lame -b 32  --silent "${WAV}.wav"  "${MP3}.mp3" && rm -f "${WAV}.wav" && chmod o+r "${MP3}.mp3")
exten => recordcheck,n,Set(CDR(recordingfile)=${UNIQUEID}.mp3)
exten => recordcheck,n,MixMonitor(${WAV}.wav,b,${monopt})
exten => recordcheck,n,return


exten => out,1,Noop(Outbound Recording Check from ${FROMEXTEN} to ${ARG2})
exten => out,n,Set(RECMODE=${DB(AMPUSER/${FROMEXTEN}/recording/out/external)})
exten => out,n,ExecIf($[!${LEN(${RECMODE})} | "${RECMODE}" = "dontcare"]?Goto(routewins))
exten => out,n,ExecIf($["${ARG3}" = "never" | "${ARG3}" = "force"]?Goto(routewins))
exten => out,n(extenwins),Gosub(recordcheck,1(${RECMODE},out,${ARG2}))
exten => out,n,Return()
exten => out,n(routewins),Gosub(recordcheck,1(${ARG3},out,${ARG2}))
exten => out,n,Return()

exten => in,1,Noop(Inbound Recording Check to ${ARG2})
exten => in,n,Set(FROMEXTEN=unknown)
exten => in,n,ExecIf($[${LEN(${CALLERID(num)})}]?Set(FROMEXTEN=${CALLERID(num)}))
exten => in,n,Gosub(recordcheck,1(${ARG3},in,${ARG2}))
exten => in,n,Return()

exten => exten,1,Noop(Exten Recording Check between ${FROMEXTEN} and ${ARG2})
exten => exten,n,Set(CALLTYPE=${IF($[${LEN(${FROM_DID})}]?external:internal)})
exten => exten,n,ExecIf(${LEN(${CALLTYPE_OVERRIDE})}?Set(CALLTYPE=${CALLTYPE_OVERRIDE}))
exten => exten,n,Set(CALLEE=${DB(AMPUSER/${ARG2}/recording/in/${CALLTYPE})})
exten => exten,n,ExecIf($[!${LEN(${CALLEE})}]?Set(CALLEE=dontcare))
exten => exten,n,GotoIf($["${CALLTYPE}"="external"]?callee)
exten => exten,n,GotoIf($["${CALLEE}"="dontcare"]?caller)
exten => exten,n,ExecIf($[${LEN(${DB(AMPUSER/${FROMEXTEN}/recording/priority)})}]?Set(CALLER_PRI=${DB(AMPUSER/${FROMEXTEN}/recording/priority)}):Set(CALLER_$
exten => exten,n,ExecIf($[${LEN(${DB(AMPUSER/${ARG2}/recording/priority)})}]?Set(CALLEE_PRI=${DB(AMPUSER/${ARG2}/recording/priority)}):Set(CALLEE_PRI=0))
exten => exten,n,GotoIf($["${CALLER_PRI}"="${CALLEE_PRI}"]?${REC_POLICY}:${IF($[${CALLER_PRI}>${CALLEE_PRI}]?caller:callee)})
exten => exten,n(callee),Gosub(recordcheck,1(${CALLEE},${CALLTYPE},${ARG2}))
exten => exten,n,Return()
exten => exten,n(caller),Set(RECMODE=${DB(AMPUSER/${FROMEXTEN}/recording/out/internal)})
exten => exten,n,ExecIf($[!${LEN(${RECMODE})}]?Set(RECMODE=dontcare))
exten => exten,n,ExecIf($["${RECMODE}"="dontcare"]?Set(RECMODE=${CALLEE}))
exten => exten,n,Gosub(recordcheck,1(${RECMODE},${CALLTYPE},${ARG2}))
exten => exten,n,Return()

exten => conf,1,Noop(Conference Recording Check ${FROMEXTEN} to ${ARG2})
exten => conf,n,Gosub(recconf,1(${ARG2},${ARG2},${ARG3}))
exten => conf,n,Return()

exten => page,1,Noop(Paging Recording Check ${FROMEXTEN} to ${ARG2})
exten => page,n,GosubIf($["${REC_POLICY_MODE}"="always"]?recconf,1(${ARG2},${FROMEXTEN},${ARG3}))
exten => page,n,Return()

exten => recconf,1,Noop(Setting up recording: ${ARG1}, ${ARG2}, ${ARG3})
exten => recconf,n,Set(__CALLFILENAME=${IF($[${CONFBRIDGE_INFO(parties,${ARG2})}]?${DB(RECCONF/${ARG2})}:${ARG1}-${ARG2}-${ARG3}-${TIMESTR}-${UNIQUEID})})
exten => recconf,n,ExecIf($[!${CONFBRIDGE_INFO(parties,${ARG2})}]?Set(DB(RECCONF/${ARG2})=${CALLFILENAME}))
exten => recconf,n,Set(CONFBRIDGE(bridge,record_file)=${MIXMON_DIR}${YEAR}/${MONTH}/${DAY}/${CALLFILENAME}.${MON_FMT})
exten => recconf,n,ExecIf($["${ARG3}"!="always"]?Return())
exten => recconf,n,Set(CONFBRIDGE(bridge,record_conference)=yes)
exten => recconf,n,Set(__REC_STATUS=RECORDING)
exten => recconf,n,Set(CDR(recordingfile)=${CALLFILENAME}.${MON_FMT})
exten => recconf,n,Return()


exten => recq,1,Noop(Setting up recording: ${ARG1}, ${ARG2}, ${ARG3})
exten => recq,n,Set(AUDIOHOOK_INHERIT(MixMonitor)=yes)
exten => recq,n,Set(MONITOR_FILENAME=${MIXMON_DIR}${YEAR}/${MONTH}/${DAY}/${CALLFILENAME})
exten => recq,n,MixMonitor(${MONITOR_FILENAME}.${MON_FMT},${MONITOR_OPTIONS},${MIXMON_POST})
exten => recq,n,Set(__REC_STATUS=RECORDING)
exten => recq,n,Set(CDR(recordingfile)=${CALLFILENAME}.${MON_FMT})
exten => recq,n,Return()

exten => parking,1,Noop(User ${ARG2} picked up a parked call)
exten => parking,n,Set(USER=${ARG2})
exten => parking,n,ExecIf($[!${LEN(${ARG2})}]?Set(USER=unknown))
exten => parking,n,Set(RECMODE=${DB(AMPUSER/${ARG2}/recording/out/internal)})
exten => parking,n,ExecIf($[!${LEN(${RECMODE})}]?Set(RECMODE=dontcare))
exten => parking,n,Gosub(recordcheck,1(${RECMODE},parked,${USER}))
exten => parking,n,Return()

</spoiler>

Команды диалплана Asterisk

Asterisk pjsip.conf

$
0
0

Asterisk pjsip.conf

asterisk pjsip.conf Описание параметров настройки pjsip в Asterisk. Подробное руководство на русском. Примеры и сравнения. pjsip vs sip. pjsip cli.

PJSIP - драйвер канала SIP в Asterisk

Что такое PJSIP

PJSIP мультимедийная библиотека с открытым кодом, для реализации протоколов SIP, SDP, RTP, STUN, TURN и ICE. Она сочетает лучшие возможности SIP сигнализации, хорошую проходимость NAT и высокий уровень взаимодействия с приложениями. Подходит практически для любого типа систем, начиная от компьютеров и заканчивая встраиваемыми системами (embedded systems) и мобильными телефонами.

Формат файла pjsip.conf

Pjsip.conf обычный текстовый файл, как и все конфигурационные файлы Asterisk, состоит из секций. Каждая секция (раздел) определяет конфигурацию объекта res_pjsip. Секции отделены друг от друга именами, заключенными в квадратные скобки [какая неожиданность] и содержат одну или более конфигурационную опцию и её значение отделенное знаком равно.

[ SectionName ]
ConfigOption = Value
ConfigOption = Value

Имена секций pjsip.conf

В большинстве случаев имена секций могут быть произвольными, однако в случае с типами ENDPOINT и AOR имена должны совпадать со заголовком SIP URI«To» для идентификации входящих SIP запросов. Каждая секция имеет обязательную опцию type=, которой определяется назначение секции в конфигурации объектов res_pjsip.

Типы секций pjsip.conf

Ниже перечислены типы секций res_pjsipи простейшие примеры конфигурации.

Варианты и значения по умолчанию

Как узнать возможные варианты значений и параметры по умолчанию? В этом поможет встроенная справка интерфейса командной строки (CLI).

"config show help res_pjsip <configobject> <configoption>"

config show help res_pjsip aor

config show help res_pjsip aor

localhost*CLI> config show help res_pjsip aor contact[aor]
contact = [Custom](Default: )(Regex: false) 
Permanent contacts assigned to AoR 
 Contacts specified will be called whenever referenced by 'chan_pjsip'.
 Use a separate "contact=" entry for each contact required. Contacts are
 specified using a SIP URI.

ENDPOINT

Модуль ENDPOINT определяет многочисленные параметры SIP, а также связь с другими модулями - AUTH, AOR и TRANSPORT.
Секция ENDPOINT должна быть обязательно связана с одной или несколькими секциями AOR.
По сути дела, ENDPOINT является основным профилем SIP телефона или SIP транка в res_pjsip, аналогично пиру в sip.conf.
Только если там определялись почти все параметры, то здесь часть ключевых свойств вынесены в специальные секции (модули), которые и будут рассмотрены ниже.

config show help res_pjsip endpoint

config show help res_pjsip endpoint

localhost*CLI> config show help res_pjsip endpoint
endpoint: [category !~ /.?/] 
Endpoint 
 The *Endpoint* is the primary configuration object. It contains the core
SIP related options only, endpoints are *NOT* dialable entries of their own.
Communication with another SIP device is accomplished via Addresses of Record(AoRs)which have one or more contacts assicated with them. Endpoints *NOT*
configured to use a 'transport' will default to first transport found in"pjsip.conf" that matches its type.
Example: An Endpoint has been configured with no transport. When it comestime to call an AoR, PJSIP will find the first transport that matches the
type. A SIP URI of 'sip:5000@[11::33]' will use the first IPv6 transport and
try to send the request.
If the anonymous endpoint identifier is in use an endpoint with the name"anonymous@domain" will be searched foras a last resort. If this is not found
it will fall back to searching for"anonymous". If neither endpoints are found
the anonymous endpoint identifier will not return an endpoint and anonymous
calling will not be possible. 
100rel                    -- Allow support for RFC3262 provisional ACK tags
aggregate_mwi             --
allow                     -- Media Codec(s) to allow
aors                      -- AoR(s) to be used with the endpoint
auth                      -- Authentication Object(s) associated with the endpoint
callerid                  -- CallerID information for the endpoint
callerid_privacy          -- Default privacy level
callerid_tag                 -- Internal id_tag for the endpoint
context                         -- Dialplan context for inbound sessions
direct_media_glare_mitigation -- Mitigation of direct media (re)INVITE glare
direct_media_method       -- Direct Media method type
connected_line_method     -- Connected line method type
direct_media              -- Determines whether media may flow directly between endpoints.
disable_direct_media_on_nat -- Disable direct media session refreshes when NAT obstructs the med
disallow                  -- Media Codec(s) to disallow
dtmf_mode                 -- DTMF mode
media_address             -- IP address used in SDP for media handling
force_rport               -- Force use of return port
ice_support               -- Enable the ICE mechanism to help traverse NAT
identify_by               -- Way(s)for Endpoint to be identified
redirect_method           -- How redirects received from an endpoint are handled
mailboxes                 -- NOTIFY the endpoint when state changes for any of the specified m
moh_suggest               -- Default Music On Hold class
outbound_auth             -- Authentication object used for outbound requests
outbound_proxy            -- Proxy through which to send requests, a full SIP URI must be prov
rewrite_contact           -- Allow Contact header to be rewritten with the source IP address-p
rtp_ipv6                  -- Allow use of IPv6 for RTP traffic
rtp_symmetric             -- Enforce that RTP must be symmetric
send_diversion            -- Send the Diversion header, conveying the diversion information to
send_pai                  -- Send the P-Asserted-Identity header
send_rpid                 -- Send the Remote-Party-ID header
timers_min_se             -- Minimum session timers expiration period
timers                    -- Session timers for SIP packets
timers_sess_expires       -- Maximum session timer expiration period
transport                 -- Desired transport configuration
trust_id_inbound          -- Accept identification information received from this endpoint
trust_id_outbound         -- Send private identification details to the endpoint.type-- Must be of type'endpoint'.
use_ptime                 -- Use Endpoints requested packetisation interval
use_avpf                  -- Determines whether res_pjsip will use and enforce usage of AVPF f
media_encryption          -- Determines whether res_pjsip will use and enforce usage of media
inband_progress           -- Determines whether chan_pjsip will indicate ringing using inband
call_group                -- The numeric pickup groupsfor a channel.
pickup_group              -- The numeric pickup groups that a channel can pickup.
named_call_group          -- The named pickup groupsfor a channel.
named_pickup_group        -- The named pickup groups that a channel can pickup.
device_state_busy_at      -- The number of in-use channels which will cause busy to be returne
t38_udptl                 -- Whether T.38 UDPTL support is enabled or not
t38_udptl_ec              -- T.38 UDPTL error correction method
t38_udptl_maxdatagram     -- T.38 UDPTL maximum datagram size
fax_detect                -- Whether CNG tone detection is enabled
t38_udptl_nat             -- Whether NAT support is enabled on UDPTL sessions
t38_udptl_ipv6            -- Whether IPv6 is used for UDPTL Sessions
tone_zone                 -- Set which countrys indications to use for channels created for t
language                  -- Set the default language to use for channels created for this end
one_touch_recording       -- Determines whether one-touch recording is allowed for this endpoi
record_on_feature         -- The feature to enact when one-touch recording is turned on.
record_off_feature        -- The feature to enact when one-touch recording is turned off.
rtp_engine                -- Name of the RTP engine to use for channels created for this endpo
allow_transfer            -- Determines whether SIP REFER transfers are allowed for this endpo
sdp_owner                 -- String placed as the username portion of an SDP origin (o=) line.
sdp_session               -- String used for the SDP session (s=) line.
tos_audio                 -- DSCP TOS bits for audio streams
tos_video                 -- DSCP TOS bits for video streams
cos_audio                 -- Priority for audio streams
cos_video                 -- Priority for video streams
allow_subscribe           -- Determines if endpoint is allowed to initiate subscriptions with
sub_min_expiry            -- The minimum allowed expiry timefor subscriptions initiated by th
from_user                 -- Username to use in From header for requests to this endpoint.
mwi_from_user             -- Username to use in From header for unsolicited MWI NOTIFYs to thi
from_domain               -- Domain to user in From header for requests to this endpoint.
dtls_verify               -- Verify that the provided peer certificate is valid
dtls_rekey                -- Interval at which to renegotiate the TLS session and rekey the SR
dtls_cert_file            -- Path to certificate file to present to peer
dtls_private_key          -- Path to private key for certificate file
dtls_cipher               -- Cipher to use for DTLS negotiation
dtls_ca_file              -- Path to certificate authority certificate
dtls_ca_path              -- Path to a directory containing certificate authority certificates
dtls_setup                -- Whether we are willing to accept connections, connect to the othe
srtp_tag_32               -- Determines whether 32 byte tags should be used instead of 80 byte
set_var                   -- Variable set on a channel involving the endpoint.
message_context           -- Context to route incoming MESSAGE requests to.
Простой пример конфигурации секции ENDPOINT
[777]
type=endpoint
context=from-internal
disallow=all
allow=alaw
transport=udp-transport
auth=auth777
aors=777

В данном примере мы видим тип секции: type=endpoint
контекст, разрешенные кодеки и также ассоциацию с другими секциями
transport=udp-transport, auth=auth777и aors=777.
Насколько я понимаю, опции typeи aorsявляются обязательными для работоспособности точки.
Для назначения Caller ID этому пиру(ENDPOINT), потребуется задать следующие параметры:

trust_id_outbound=yes
callerid=V Pupkin <777>

TRANSPORT

Настройка транспортного уровня res_pjsip. Используются протоколы UDP, TCP, WebSockets и методы шифрования TLS/SSL. Можно настроить одну транспортную секцию для использования множеством точек (ENDPOINT), или создать уникальный транспортный уровень для конкретной точки. Условно, можно сравнить TRANSPORT, с секцией [general] sip.conf.

config show help res_pjsip transport

config show help res_pjsip transport

localhost*CLI> config show help res_pjsip transport
transport: [category !~ /.?/] 
SIP Transport *Transports*
There are different transports and protocol derivatives supported by 're
s_pjsip'. They are in order of preference: UDP, TCP, and WebSocket (WS).
NOTE: Changes to transport configuration in pjsip.conf will only be effected
on a complete restart of Asterisk. A module reload will not suffice. 
async_operations          -- Number of simultaneous Asynchronous Operationsbind-- IP Address and optional port to bind to for this transport
ca_list_file              -- File containing a list of certificates to read(TLS ONLY)
cert_file                 -- Certificate filefor endpoint (TLS ONLY)
cipher                    -- Preferred Cryptography Cipher (TLS ONLY)
domain                    -- Domain the transport comes from
external_media_address    -- External IP address to use in RTP handling
external_signaling_address -- External address for SIP signalling
external_signaling_port   -- External port for SIP signalling
method                    -- Method of SSL transport (TLS ONLY)
local_net                 -- Network to consider local(used for NAT purposes).
password                  -- Password required for transport
priv_key_file             -- Private key file(TLS ONLY)
protocol                  -- Protocol to use for SIP traffic
require_client_cert       -- Require client certificate (TLS ONLY)type-- Must be of type'transport'.
verify_client             -- Require verification of client certificate (TLS ONLY)
verify_server             -- Require verification of server certificate (TLS ONLY)
tos                       -- Enable TOS for the signalling sent over this transport
cos                       -- Enable COS for the signalling sent over this transport

По умолчанию, для применения настроек транспортного уровня недостаточно перечитать конфиги. Потребуется рестартовать Asterisk, если не задано allow_reload=true (по умолчанию - false)

простой пример конфигурации секции TRANSPORT
[udp-transport]
type=transport
protocol=udp
bind=0.0.0.0

или TLS транспорт:

[transport-tls]
type=transport
protocol=tls
bind=0.0.0.0:5066
cert_file=/etc/asterisk/keys/asterisk.crt
priv_key_file=/etc/asterisk/keys/asterisk.key
external_media_address=123.123.123.1
external_signaling_address=123.123.123.1
local_net=10.10.0.0/16
method=tlsv1

Каждый транспорт в системе должен иметь уникальный порт.

localhost*CLI> pjsip show transports

Transport:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress....................>
 =========================================================================================

Transport:  udp-transport             udp      0      0  0.0.0.0:5080
Transport:  udp-transport-infra       udp      0      0  192.168.1.110:5081
Transport:  udp-transport-megafon     udp      0      0  0.0.0.0:5060

AUTH

Секция аутентификации содержит опции и полномочия для входящих и исходящих регистраций. С этой секцией ассоциируются такие секции как ENDPOINT и REGISTRATIONS.
Разные ENDPOINT и REGISTRATIONS могут использовать одну и ту же секцию аутентификации, если требуется.

config show help res_pjsip auth

config show help res_pjsip auth

localhost*CLI> config show help res_pjsip auth
auth: [category !~ /.?/] 
Authentication type 
 Authentication objects hold the authentication information for use by other
objects such as'endpoints' or 'registrations'. This also allows for multiple
objects to use a single auth object. See the 'auth_type' config option for
password style choices. 
auth_type                    -- Authentication type
nonce_lifetime            -- Lifetime of a nonce associated with this authentication config.
md5_cred                    -- MD5 Hash used for authentication.
password                     -- PlainText password used for authentication.
realm                          -- SIP realm for endpointtype-- Must be 'auth'
username                    -- Username to use for account
Простой пример секции AUTH
[auth777]
type=auth
auth_type=userpass
password=password
username=777

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

[auth6001]
type=auth
auth_type=md5
md5_cred=5f4dcc3b5aa765d61d8327deb882cf99
username=777

AOR

Главная функция AoR (Address of Record) указать Asterisk, как связаться с ENDPOINT. Без соответствующей AOR секции, точка ENDPOINT будет недоступна для вызова. Здесь также задаются соответствия голосовой почте, MWI, продолжительность действия регистрации -expiration и настройки qualify (периодической отправки SIP сообщений OPTONS для мониторинга состояния устройств)

Когда Asterisk получает запрос на регистрацию от устройства, он в первую очередь ищет соответствующую SIP заголовку To: «777»<sip:777@192.168.1.21;transport=UDP> запись в именах секций AOR – в нашем прмере [777]

config show help res_pjsip aor

config show help res_pjsip aor

localhost*CLI> config show help res_pjsip aor
aor: [category !~ /.?/] 
The configuration for a location of an endpoint 
 An AoR is what allows Asterisk to contact an endpoint via res_pjsip. If no
AoRs are specified, an endpoint will not be reachable by Asterisk. Beyond
that, an AoR has other uses within Asterisk, such as inbound registration. 
 An 'AoR' is a way to allow dialing a group of 'Contacts' that all use the
 same 'endpoint'for calls.
 This can be used as another way of grouping a list of contacts to dial
 rather than specifing them each directly when dialing via the dialplan. This
 must be used in conjuction with the 'PJSIP_DIAL_CONTACTS'.
 Registrations: For Asterisk to match an inbound registration to an endpoint,
 the AoR object name must match the user portion of the SIP URI in the "To:"
 header of the inbound SIP registration. That will usually be equivalent to
 the "user name"setin your hard or soft phones configuration. 
contact                   -- Permanent contacts assigned to AoR
default_expiration        -- Default expiration timein seconds for contacts that are dynamica
mailboxes                 -- Allow subscriptions for the specified mailbox(es)
maximum_expiration        -- Maximum time to keep an AoR
max_contacts              -- Maximum number of contacts that can bind to an AoR
minimum_expiration        -- Minimum keep alive timefor an AoR
remove_existing           -- Determines whether new contacts replace existing ones.type-- Must be of type'aor'.
qualify_frequency         -- Interval at which to qualify an AoR
authenticate_qualify      -- Authenticates a qualify request if needed
outbound_proxy            -- Outbound proxy used when sending OPTIONS request
support_path              -- Enables Path support for REGISTER requests and Route support for
Простейший пример секции AOR
[777]
type=aor
max_contacts=1

Опция max_contact=1 значит, что только один SIP User Agent может быть одновременно зарегистрирован через эту запись AOR. Можно указать и 10, если потребуется.

[777]
type=aor
contact=sip:777@192.168.1.21:5060

Во втором примере мы не ожидаем запроса на регистрацию от SIP UA,
а указываем вручную постоянный контакт для этой записи.
Можно не беспокоится о кол-ве подключений, адрес все равно один.

[siptrunk]
type=aor
contact=sip:123.123.1.1:5060

В последнем примере пропущен username, что позволяет использовать данную запись для исходящей связи,
определяя вызываемый номер при помощи диалплана «Dial(PJSIP/${EXTEN}@siptrunk)».

REGISTRATION

Секция регистраций отвечает за исходящие регистрации. Используется для регистрации в удаленных системах, будь то другой Asterisk или транк от провайдера.

config show help res_pjsip_outbound_registration registration

config show help res_pjsip_outbound_registration registration

localhost*CLI> config show help res_pjsip_outbound_registration  registration
registration: [category !~ /.?/] 
The configuration for outbound registration 
 Registration is *COMPLETELY* separate from the rest of 'pjsip.conf'. A minimal
configuration consists of setting a 'server_uri'        and a 'client_uri'. 
auth_rejection_permanent  -- Determines whether failed authentication challenges are treated a
client_uri                -- Client SIP URI used when attempting outbound registration
contact_user              -- Contact User to use in request
expiration                -- Expiration timefor registrations in seconds
max_retries               -- Maximum number of registration attempts.
outbound_auth             -- Authentication object to be used for outbound registrations.
outbound_proxy            -- Outbound Proxy used to send registrations
retry_interval            -- Interval in seconds between retries if outbound registration is u
forbidden_retry_interval  -- Interval used when receiving a 403 Forbidden response.
server_uri                -- SIP URI of the server to register against
transport                 -- Transport used for outbound authenticationtype-- Must be of type'registration'.
support_path              -- Enables Path support for outbound REGISTER requests  
Пример секции REGISTRATION
[siptrunk]
type=registration
transport=udp-transport
outbound_auth=siptrunk
server_uri=sip:123.123.1.1:5060
client_uri=sip:username@192.168.1.1:5060
retry_interval=60

Для регистрации понадобится определить используемый транспорт и секцию аутентификации.
Помимо этого, наверняка, потребуется указать контакт для входящих вызовов.

[providertrunk]
type=registration
transport=udp-transport
outbound_auth=providertrunk
server_uri=sip:sip.example.com
client_uri=sip:1234567890@sip.example.com
retry_interval=60

Пример регистрации транка провайдера.

DOMAIN_ALIAS

Псевдоним домена. [Имя] данной секции является псевдонимом, а конфигурационная опция domain=, доменным именем, которому сопоставлен псевдоним.

config show help res_pjsip domain_alias

config show help res_pjsip domain_alias

localhost*CLI> config show help res_pjsip domain_alias
domain_alias: [category !~ /.?/] 
Domain Alias 
 Signifies that a domain is an alias. If the domain on a session is not found
to match an AoR then this object is used to see if we have an aliasfor the
AoR to which the endpoint is binding. This objects name as defined in
configuration should be the domain alias and a config option is provided to
specify the domain to be aliased. type-- Must be of type'domain_alias'.
domain                    -- Domain to be aliased
Пример секции DOMAIN_ALIAS
[example2.com]
type=domain_alias
domain=example.com

ACL

Модуль не привязан к какой-либо точке ENDPOINTs и управляет всеми входящими SIP коммуникациями с использованием res_pjsip. Установки ACl (Access Control Lis) могут быть назначены в самой секции, или в файле acl.confна который будет ссылаться секция.

config show help res_pjsip_acl acl

config show help res_pjsip_acl acl

localhost*CLI> config show help res_pjsip_acl  acl
acl: [category !~ /.?/] 
Access Control List 
acl                       -- List of IP ACL section names in acl.conf
contact_acl               -- List of Contact ACL section names in acl.conf
contact_deny              -- List of Contact header addresses to deny
contact_permit            -- List of Contact header addresses to permit
deny                      -- List of IP addresses to deny access from
permit                    -- List of IP addresses to permit access fromtype-- Must be of type'acl'.
Простые примеры ACL

Asterisk res_pjsip_acl

Настройки берутся из файла acl.conf:

[acl]
type=acl
acl=example_named_acl1

Настройки непосредственно в секции:

[acl]
type=acl
deny=0.0.0.0/0.0.0.0
permit=123.12.123.0
permit=123.12.123.1

Конфиг разрешающий регистрацию на основе SIP заголовка, а не IP адреса.

[acl]
type=acl
contactdeny=0.0.0.0/0.0.0.0
contactpermit=123.12.123.0
contactpermit=123.12.123.1

IDENTIFY

Определяет конечные точки с помощью IP-адреса источника.

config show help res_pjsip_endpoint_identifier_ip identify

config show help res_pjsip_endpoint_identifier_ip identify

localhost*CLI> config show help res_pjsip_endpoint_identifier_ip identify
identify: [category !~ /.?/]

Identifies endpoints via source IP address

endpoint                  -- Name of Endpoint
match                     -- IP addresses or networks to match against
type                      -- Must be of type 'identify'.
Пример identity
[777]
type=identify
endpoint=777
match=123.0.112.1

CONTACT

Контакты являются одним из способов не указывать явно SIP URIв плане набора (диалплане).

config show help res_pjsip contact

config show help res_pjsip contact

localhost*CLI> config show help res_pjsip contact
contact: [category !~ /.?/]

A way of creating an aliased name to a SIP URI

 Contacts are a way to hide SIP URIs from the dialplan directly. They are
also used to make a group of contactable parties when in use with 'AoR' lists.


type                      -- Must be of type 'contact'.
uri                       -- SIP URI to contact peer
expiration_time           -- Time to keep alive a contact
qualify_frequency         -- Interval at which to qualify a contact
outbound_proxy            -- Outbound proxy used when sending OPTIONS request
path                      -- Stored Path vector for use in Route headers on outgoing requests.

Отношения объектов конфигурации pjsip.conf

ENDPOINT

  • Множество ENDPOINTs связываются с множеством AORs
  • Ноль или больше ENDPOINTs связаны с ноль или одной AUTHs
  • Ноль или больше ENDPOINTs связаны с как минимум одним TRANSPORT
  • Ноль или одна ENDPOINTs связана с определенной IDENTIFY

REGISTRATION

  • Ноль или больше REGISTRATIONs связаны с ноль или одной AUTHs
  • Ноль или больше REGISTRATIONs связаны с как минимум одним TRANSPORT

AOR

  • Множество ENDPOINTs связываются с множеством AORs
  • Множество AORs связаны с множеством CONTACTs

CONTACT

  • Множество CONTACTs связываются с множеством AORs

IDENTIFY

  • Ноль или больше ENDPOINTs связаны с определенным IDENTIFY объектом.

ACL, DOMAIN_ALIAS

  • Эти объекты не имеют направленных связей с другими объектами.

Примеры диалплана для вызова PJSIP пиров и екстеншенов.

 exten => _6XXX,1,Dial(PJSIP/${EXTEN})
 exten => _9NXXNXXXXXX,1,Dial(PJSIP/mytrunk/sip:${EXTEN:1}@203.0.113.1:5060)
 exten => _9NXXNXXXXXX,1,Dial(PJSIP/${EXTEN:1}@mytrunk)

Примеры

Пример ENDPOINT для одного SIP телефона с регистрацией на Asterisk.
;===============TRANSPORT

[udp-transport]
type=transport
protocol=udp
bind=0.0.0.0

;===============EXTENSION 777

[777]
type=endpoint
context=from-internal
disallow=all
allow=alaw
transport=udp-transport
auth=auth777
aors=777

[auth777]
type=auth
auth_type=userpass
password=777
username=777

[777]
type=aor
max_contacts=1
  • auth= используется для входящей аутентификации
  • max_contacts= установите кол-во регистраций, одну или более, разрешенных для этой учетной записи.
Пример SIP транка с исходящей регистрацией
;==============TRANSPORTS

[udp-transport]
type=transport
protocol=udp
bind=0.0.0.0

;===============TRUNK

[siptrunk]
type=registration
transport=udp-transport
outbound_auth=siptrunk
server_uri=sip:sip.example.com
client_uri=sip:1234567890@sip.example.com
retry_interval=60

[siptrunk]
type=auth
auth_type=userpass
password=1234567890
username=1234567890

[siptrunk]
type=aor
contact=sip:123.0.112.1:5060

[siptrunk]
type=endpoint
transport=udp-transport
context=from-trunk
disallow=all
allow=alaw,ulaw
outbound_auth=siptrunk
aors=siptrunk

[siptrunk]
type=identify
endpoint=siptrunk
match=123.0.112.1
Пример регистрации множественных ENDPOINTs с использованием шаблонов
;===============TRANSPORT

[udp-transport]
type=transport
protocol=udp
bind=0.0.0.0

;===============ENDPOINT TEMPLATES

[endpoint-basic](!)
type=endpoint
transport=udp-transport
context=from-internal
disallow=all
allow=alaw

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

[aor-single-reg](!)
type=aor
max_contacts=1

;===============EXTENSION 777

[777](endpoint-basic)
auth=auth777
aors=777

[auth777](auth-userpass)
password=777
username=777

[777](aor-single-reg)

;===============EXTENSION 778

[778](endpoint-basic)
auth=auth778
aors=778

[auth778](auth-userpass)
password=778
username=778

[778](aor-single-reg)

;===============EXTENSION 779

[779](endpoint-basic)
auth=auth779
aors=779

[auth779](auth-userpass)
password=779
username=779

[779](aor-single-reg) 

От старого к новому - sip.conf к pjsip.conf сравнение примеров.

Сравнение конфигурации ENDPOINT

  • Два SIP телефона должны звонить и принимать вызовы через Asterisk.
  • В обоих случаях для аутентификации используются username и password.
  • 777 регистрируется с динамического IP, 778 со статического IP адреса.

1

sip.confpjsip.conf
[general]
udpbindaddr=0.0.0.0

[777]
type=friend
host=dynamic
disallow=all
allow=alaw
context=from-internal
secret=1234

[778]
type=friend
host=192.168.1.2
disallow=all
allow=alaw
context=from-internal
secret=1234
[udp-transport]
type=transport
protocol=udp
bind=0.0.0.0

[777]
type = endpoint
transport = udp-transport
context = from-internal
disallow = all
allow = alaw
aors = 777
auth = auth777

[777]
type = aor
max_contacts = 1

[auth777]
type=auth
auth_type=userpass
password=1234
username=777

[778]
type = endpoint
transport = udp-transport
context = from-internal
disallow = all
allow = alaw
aors = 778
auth = auth778

[778]
type = aor
contact = sip:778@192.168.1.2:5060

[auth778]
type=auth
auth_type=userpass
password=1234
username=778

Сравнение конфигурации trunk

sip.confpjsip.conf
[general]
udpbindaddr=0.0.0.0

register => myname:1234@203.0.113.1:5060

[mytrunk]
type=friend
secret=1234
username=myname
host=123.0.112.1
disallow=all
allow=alaw
context=from-trunk
[simpletrans]
type=transport
protocol=udp
bind=0.0.0.0
[mytrunk]
type=registration
transport=simpletrans
outbound_auth=mytrunk
server_uri=sip:@123.0.112.1:5060
client_uri=sip:myname@123.0.112.1:5060

[mytrunk]
type=auth
auth_type=userpass
password=1234
username=myname

[mytrunk]
type=aor
contact=sip:123.0.112.1:5060

[mytrunk]
type=endpoint
transport=simpletrans
context=from-trunk
disallow=all
allow=alaw
outbound_auth=mytrunk
aors=mytrunk

[mytrunk]
type=identify
endpoint=mytrunk
match=123.0.112.1

PJSIP CLI

Connected to Asterisk 13.9.1 currently running on aster2 (pid = 17401)
asterisk*CLI> core show help pjsip
pjsip dump endpt               -- Dump the res_pjsip endpt internals
pjsip export config_wizard primitives [to] -- Export config wizard primitives
pjsip list aors                -- List PJSIP Aors
pjsip list auths               -- List PJSIP Auths
pjsip list channels            -- List PJSIP Channels
pjsip list ciphers             -- List available OpenSSL cipher names
pjsip list contacts            -- List PJSIP Contacts
pjsip list endpoints           -- List PJSIP Endpoints
pjsip list identifies          -- List PJSIP Identifies
pjsip list registrations       -- List PJSIP Registrations
pjsip list transports          -- List PJSIP Transports
pjsip qualify                  -- Send an OPTIONS request to a PJSIP endpoint
pjsip send register            -- Registers an outbound registration target
pjsip send unregister          -- Unregisters outbound registration target
pjsip set history {on|off|clear} -- Enable/Disable PJSIP History
pjsip set logger {on|off|host} -- Enable/Disable PJSIP Logger Output
pjsip show aors                -- Show PJSIP Aors
pjsip show aor                 -- Show PJSIP Aor
pjsip show auths               -- Show PJSIP Auths
pjsip show auth                -- Show PJSIP Auth
pjsip show channels            -- Show PJSIP Channels
pjsip show channel             -- Show PJSIP Channel
pjsip show channelstats        -- Show PJSIP Channel Stats
pjsip show contacts            -- Show PJSIP Contacts
pjsip show contact             -- Show PJSIP Contact
pjsip show endpoints           -- Show PJSIP Endpoints
pjsip show endpoint            -- Show PJSIP Endpoint
pjsip show history             -- Display PJSIP History
pjsip show identifiers         -- List registered endpoint identifiers
pjsip show identifies          -- Show PJSIP Identifies
pjsip show identify            -- Show PJSIP Identify
pjsip show registrations       -- Show PJSIP Registrations
pjsip show registration        -- Show PJSIP Registration
pjsip show settings            -- Show global and system configuration options
pjsip show transports          -- Show PJSIP Transports
pjsip show transport           -- Show PJSIP Transport
pjsip show version             -- Show the version of pjproject in use

Asterisk настройка

Viewing all 1135 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>