Asterisk - программная АТС, если говорить коротко. Описывать возможности и историю не буду, если вы тут, значит уже в курсе.

Установка

Настройка

  • sip.conf

Настраивая клиентские приложения по протоколу SIP, вам нужно куда-то присоединится. Поэтому в Asterisk в sip.conf нужно завести этих клиентов. Например:

1
 [general]

составляем шаблон, чтобы не писать одно и то же многократно. Восклицательный знак даст системе понять, что это только шаблон, не более.

1
2
3
4
5
6
 [furuser](!)
 type=friend
 host=dynamic
 allow=gsm
 allow = ulaw
 context = phones 

создаём номер 1000 в сети, пароль к нему и добавляем уже созданный шаблон

1
2
 [1000](furuser)
 secret=password

АТС без выхода на внешнего провайдера - редкое явление. Поэтому добавим выход на примере sipnet.ru

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 [general]
 register = NUMBER:PASSWORD@sipnet.ru/номер в вашей сети
 language=ru
 dissalow=all
 allow=gsm
 transport=udp
   
 [furuser](!)
 type=friend
 host=dynamic
 allow=gsm
 allow = ulaw
 context = phones
   
 [1000](furuser)
 secret=PASSWORD
  
 [sipnet]
данные sipnet
 type=peer
 host = sipnet.ru
 defaultuser = NUMBER
 secret = PASSWORD
 contex = phones
 insecure=invite
 fromuser = NUMBER
 fromdomain = sipnet.ru
 nat = yes
 dtmfmode=rfc2833
 disallow=all
 allow=g729
 allow=ulaw
 allow=alaw
 allow=gsm

Замените данные своими и всё должно работать, конфиг привёл с собственного сервера.

  • Extension.conf

Конечно, без диал-плана работать это не будет. Вот пример:

1
2
3
[general]
;запрет гостей
allowguest = no

на номер 1000 придёт внешнее сообщение по-умолчанию (если настроен на входящие от того же sipnet)

1
2
3
[default]
 exten => s, n, Dial(SIP/1000,30)
 exten => s, n, Hangup()

в данном случае разрешаем выход вне, если телефон начинается с 7 или 8 и содержит 11 цифр (например, звонок на мобильный)

1
2
3
4
 [outgoing_calls]
 exten => _[7-8]XXXXXXXXXX, 1, Dial(SIP/sipnet/${EXTEN},120)
 exten => _[7-8]XXXXXXXXXX, n, PlayBack(noanswer)
 exten => _[7-8]XXXXXXXXXX, n, HangUp

разговоры внутри сети тоже нужно обозначить. m во второй строке намекнёт на проигрывание музыки из 3 строчки, в 3 строке пропишите путь к своей музыке. В 4 строке указано, что если номер занят или не отвечает, отправляем звонок на номер 1000

1
2
3
4
5
6
7
 [internal]
 exten => _XXXX, 1, Answer()
 exten => _XXXX, n, Dial(SIP/${EXTEN},30,m)
 exten => _XXXX, n, Playback(/opt/wail)
 exten => _XXXX, n, Dial(SIP/1000,30)
 exten => _XXXX, n, Busy(3)
 exten => _XXXX, n, Hangup()

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

1
 exten => 6245, 1, System(echo Privet | mail -s Privet YOUR_MAIL)

в этих строках указываем, что номера с контекстом phones (из sip.conf), будут доступны диалпланы интернал и аутгоинг

1
2
3
 [phones]
 include => internal
 include => outgoing_calls

Соответствие

X соответствует любому числу от 0 до 9

Z соответствует любому числу от 1 до 9

N соответствует любому числу от 2 до 9

[1237-9] соответствует любому числу или диапазону чисел, которые заключены в квадратные скобки (в данном случае: 1,2,3,7,8,9)

. специальный символ, соответствует одному или более символов (не только цифрам)

! специальный символ, соответствует отсутствию, одному или более символов (не только цифрам)

modules.conf

Asterisk - просто классное приложение в плане работы с разными устройствами. Но если их нет, зачем для них грузить модули? Ведь чем больше кода, тем больше шансов попасть на ошибку, к тому же больше расходуется память. Отключаем ненужное, вот мой список:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
 noload => app_adsiprog.so
 noload => app_alarmreceiver.so
 noload => app_amd.so
 noload => app_dictate.so
 noload => app_directory.so
 noload => app_dumpchan.so
 noload => app_externalivr.so
 noload => app_festival.so
 noload => app_flash.so
 noload => app_forkcdr.so
 noload => app_getcpeid.so
 noload => app_ices.so
 noload => app_image.so
 noload => app_lookupblacklist.so
 noload => app_lookupcidname.so
 noload => app_milliwatt.so
 noload => app_morsecode.so
 noload => app_nbscat.so
 noload => app_page.so
 noload => app_privacy.so
 noload => app_random.so
 noload => app_readfile.so
 noload => app_sayunixtime.so
 noload => app_senddtmf.so
 noload => app_sendtext.so
 noload => app_setcdruserfield.so
 noload => app_sms.so
 noload => app_speech_utils.so
 noload => app_talkdetect.so
 noload => app_test.so
 noload => app_url.so
 noload => app_zapateller.so
 noload => app_zapbarge.so
 noload => app_zapras.so
 noload => app_zapscan.so
 noload => cdr_custom.so
 noload => cdr_pgsql.so
 noload => chan_alsa.so
 noload => chan_dongle.so
 noload => chan_ooh323.so
 noload => chan_mgcp.so
 noload => chan_oss.so
 noload => chan_phone.so
 noload => chan_skinny.so
 noload => func_curl.so
 noload => func_md5.so
 noload => func_odbc.so
 noload => func_rand.so
 noload => func_realtime.so
 noload => func_sha1.so
 noload => pbx_ael.so
 noload => pbx_dundi.so
 noload => pbx_realtime.so
 noload => res_config_pgsql.so
 noload => res_convert.so
 noload => res_crypto.so
 noload => res_smdi.so
 noload => res_speech.so
 noload => codec_speex.so
 noload => func_version.so
 noload => chan_agent.so
 noload => func_curl.so
 noload => app_saycountpl.so
 noload => res_snmp.so
 noload => res_curl.so
 noload => res_config_ldap.so
 noload => res_config_sqlite.so
 noload => res_config_curl.so
 noload => res_calendar_caldav.so
 noload => res_calendar_ews.so
 noload => res_calendar_exchange.so
 noload => res_calendar_icalendar.so
 noload => cel_sqlite3_custom.so
 noload => cel_radius.so
 noload => cel_pgsql.so
 noload => cel_odbc.so
 noload => cdr_sqlite3_custom.so
 noload => cdr_radius.so
 noload => cdr_odbc.so
 noload => chan_unistim.so
 noload => chan_jingle.so
 noload => res_calendar_caldav.so
 noload => res_config_ldap.so
 noload => chan_vpb.so
 noload => pbx_lua.so
 noload => cdr_tds.so
 noload => cel_tds.so

Прослушка разговоров

Иногда нужно параллельно слышать разговор или принять в нём участие. Сделаем пару примеров, как это возможно. В данном случае мы указали номера 666 на прослушку и 667 на участие. EXTEN:3 как раз покажет, что нужно звонить на номер, не используя 666 или 667. итак, добавляем в extension.conf:

1
2
3
4
5
6
 [spying]
  exten => _666XXXX,1,ExtenSpy(${EXTEN:3},qv(+1))
  exten => _666XXXX,n,Hangup()
   
  exten => _667XXXX,1,ExtenSpy(${EXTEN:3},wqv(+1))
  exten => _667XXXX,n,Hangup()

Звоним на 6661000 и сможем слышать то, о чём говорят на 1000 номере…

Звонки с добавлением внутреннего номера

Ситуация не совсем приятная, но…. Итак, нужно с обычной АТС постепенно перейти на Asterisk. Подключиться к АТС по SIP нет возможности. Но в наличии шлюз CISCO SPA100. Аналоговый его порт подключаем к АТС, его самого вешаем на номер 500. Всё, что нужно, это чтобы при наборе внутреннего трёхзначного номера мы попадали на этот номер на АТС без всяких добавочных номеров. Решить это можно, передав код через наш шлюз. Диалплан в таком случае будет выглядеть примерно так:

1
2
3
 exten => _XXX,1,Answer()
 exten => _XXX,n,Dial(SIP/500,5,D(wwww${EXTEN}))
 exten => _XXX,n,Hangup()

Подключаем chan_dongle на примере ubuntu

Ставим нужные пакеты, иначе не соберётся

1
apt-get install asterisk-dev

Идём в темп

1
cd /tmp

Скачиваем свежую версию

1
wget -c https://asterisk-chan-dongle.googlecode.com/files/chan_dongle-1.1.r14.tgz

Разархивируем

1
tar zxvf chan_dongle-1.1.r14.tgz

Переходим в папку и собираем

1
2
3
cd chan_dongle-1.1.r14
./configure
make install

Копируем конфиг

1
cp etc/dongle.conf /etc/asterisk/

И редактируем его по своему усмотрению.

При отключении интернета клиенты из локальной сети так же отваливаются

Тут эта ошибка из-за вопросов с DNS (хотя казалось бы причём тут это?). Для начала закоментируйте register в sip.conf и можно увидеть, что клиенты стали цепляться. Решить можно так:

  • Поднять DNS в локальной сети, если его нет (dnsmasq или Bind)

  • указать в /etc/hosts nameserver и ваши DNS

Прозвон идёт, но нет гудка

Можно подставить гудок (ложный), добавив r. Например:

1
  same => n,Dial(SIP/${EXTEN}@sipout,,Tt'''r''')

Дампим траффик

1
 tcpdump -pvvvvvv -i eth0 -s0  udp port 5060

Конвертируем звуковые файлы

mpg123 -w file.wav file.mp3 sox -V file.wav -r 8000 -c 1 -t ul file.ulaw sox -V file.wav -r 8000 -c 1 -t al file.alaw sox -V file.wav -r 8000 -c 1 -t gsm file.gsm