Este guia pretende mostrar a configuração de um sistema de telefonia para empresas utilizando o Asterisk* equipado de extras básicos para um sistema de pequeno a medio porte. são eles:

– Peers realtime utilizando LDAP.
– Call Detail Record armazenado em MySQL e viewer básico em PHP
– Gateway AGI para execucao de dialplan via Adhearsion (Ruby)
(a execucao externa de dialplan é escolha pessoal e torna-se obrigatória dependendo da complexidade do plano de discagem)
– Servidor para envio e recebimento de fax (Hylafax)
– Flash Operator Panel

A primeira etapa compreende a configuração básica do sistema e todo o processo assume que se está logado como root.

Configuração básica do servidor
—————————————————————————-
Configuracao de sistema baseado em Debian, especificamente Ubuntu.

– habilitar ssh
# apt-get install openssh-server
# echo "AllowUsers root seuusername" >> /etc/ssh/sshd.conf

– update do server
# apt-get update && apt-get upgrade && reboot

– baixar os headers e compiladores e libs necessárias
# apt-get install linux-headers-`uname -r` build-essential libncurses-dev ldap-utils libldap2-dev libmysqlclient15

Instalacao e configuracao do Asterisk
—————————————————————————-
Uma placa Digium será configurada neste sistema e portanto algumas regras básicas devem ser respeitadas. Provavelmente estas regras se aplicam tambem a placas de outros fabricantes, e mesmo que não sejam necessárias, são boas práticas para um sistema em produção.

– Desativar opção de Plug and Play na bios
– Desabilitar saidas seriais, paralelas, som, usb (em alguns casos pode ser necessário manter usb para que o zaptel tenha uma boa fonte de clock).
– Desligar o drive de cd se houver. Desabilitar a controladora do respectivo drive.
– Certificar-se de que o hd está em modo DMA. “hdparm -i”
– Desabilitar ACPI no boot.
– Certificar-se de que a placa digium tem seu proprio IRQ. Verifique com um “cat /proc/interrupts” e caso esteja compartilhado, tente mudar a placa de slot.
– Em casos onde o Moh(music on hold) fica picotado ou metalico, desabilitar hyperthreading pode resolver. Em outros casos, desabilitar SMP tambem pode ajudar.

– baixar e descompactar sources do asterisk, libpri, addons e zaptel
# wget http://downloads.digium.com/pub/asterisk/releases/asterisk-1.6.0-beta9.tar.gz
# wget http://downloads.digium.com/pub/asterisk/asterisk-addons-1.6.0-beta4.tar.gz
# wget http://downloads.digium.com/pub/libpri/libpri-1.4.6.tar.gz
# wget http://downloads.digium.com/pub/zaptel/zaptel-1.4.11.tar.gz
# tar -zxvf asterisk-1.6.0-beta9.tar.gz
# tar -zxvf asterisk-addons-1.6.0-beta4.tar.gz
# tar -zxvf libpri-1.4.6.tar.gz
# tar -zxvf zaptel-1.4.11.tar.gz

– compilar e instalar
(para habilitar bloqueio de chamada a cobrar aplique o patch disponivel 3 ou 4 posts atras. Ele é para uma versao mais antiga da libpri mas serve tbm para versoes mais novas)
# cd libpri-1.4.6/
# make && make install
# cd ../zaptel-1.4.11/
# ./configure && make && make install && make config
# cd ../asterisk-1.6.0-beta9/

(se estiver fazendo upgrade não esqueça de apagar os modulos em: /usr/lib/asterisk/modules e suprimir “make samples” pois vai sobreescrever os arquivos de configuração)

# ./configure && make && make install && make samples
# cd ../asterisk-addons-1.6.0-beta4/

inserir “CFLAGS+=-DMYSQL_LOGUNIQUEID” em cdr/Makefile
inserir “#define MYSQL_LOGUNIQUEID” em cdr/cdr_addon_mysql.c

(se estiver fazendo upgrade nao esqueça de suprimir “make samples” pois vai sobreescrever os arquivos de configuração)

# ./configure --with-mysqlclient=/usr/ && make && make install && make samples
# cd ..

– selecionar somente o modulo necessário para sua placa digium em:
/etc/defaults/zaptel

– configurar o hardware
conteudo de /etc/zaptel.conf
(consulte sua operadora para valores compatíveis)

span=1,1,0,ccs,hdb3,crc4
bchan=1-15
dchan=16
loadzone=br
defaultzone=br

Configurar Iaxmodem
—————————————————————————-

# wget http://ufpr.dl.sourceforge.net/sourceforge/iaxmodem/iaxmodem-1.1.1.tar.gz
# tar -zxvf iaxmodem-1.1.1.tar.gz
# cd iaxmodem-1.1.1
# ./build static
# cp iaxmodem /usr/bin/iaxmodem
# cd..
# mkdir /etc/iaxmodem

-conteudo do /etc/iaxmodem/ttyIAX

device /dev/ttyIAX
owner root:root
mode 660
port 45699
refresh 300
server 127.0.0.1
peername numerodoramaliax
secret senhaparaoramaliax
cidname IAX Modem 1
cidnumber numerodoramaliax
codec slinear

-servico de iax em /etc/event.d/iax
(em sistemas mais antigos utilizar o /etc/inittab)

start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5
stop on runlevel 0
stop on runlevel 1
stop on runlevel 5
stop on runlevel 6
respawn
exec /usr/bin/iaxmodem ttyIAX&> /var/log/iaxmodem-ttyIAX

-servico de fax em /etc/event.d/fax
(em versoes antigas utilizar o /etc/inittab)

start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5
stop on runlevel 0
stop on runlevel 1
stop on runlevel 5
stop on runlevel 6
respawn
exec /usr/local/sbin/faxgetty ttyIAX

– conteudo de /etc/asterisk/iax2.conf

[general]
bindaddr=127.0.0.1:4569
allow=all
disallow=g723.1
disallow=gsm
disallow=lpc10
allow=ulaw
allow=alaw
jitterbuffer=no
forcejitterbuffer=no
autokill=yes
codecpriority=host
tos_audio=0xB8
[888]
username=numerodoramaliax
type=friend
secret=senhaparaoramaliax
qualify=no
notransfer=yes
host=dynamic
context=local
callerid="Fax Corporativo"
allow=all
disallow=lpc10 ; Icky sound quality... Mr. Roboto.
disallow=gsm
allow=ulaw
allow=alaw

Configurar Exim e HylaFax
—————————————————————————-

– baixar e instalar exim4
# apt-get install exim4

– configure o exim para utilizar seu gateway de email como smarthost
# dpkg-reconfigure exim4-config

– baixar e instalar o Hylafax
# apt-get install libtiff-tools libtiff4 libtiff4-dev gs
# wget ftp://ftp.hylafax.org/source/hylafax-4.2.3.tar.gz
# tar -zxvf hylafax-4.3.1.tar.gz
# cd hylafax-4.3.1
# ./configure && make && make install
# faxsetup

(neste ponto o configurador do hylafax entra em acao e a maioria das configuracoes deve permanecer default)

-configurar OpenLDAP
-configurar asterisk para utilizar ldap
-etcetera, etcetera, etcetera
(este tutorial será atualizado e finalizado em breve)

O bloqueio de chamadas a cobrar no Brasil costuma ser uma chatice. No caso das operadoras temos as que querem ganhar $$$ pra bloquear e as que tem uma tremenda má vontade em faze-lo (EMBRAHELL em Belo Horizonte).

Utilizando placas Digium, costuma-se dizer que só se bloqueia chamadas a cobrar no Asterisk utilizando sinalização MFC/R2 com Unicall, que pode ser mais problemático que simplesmente pagar pelas chamadas a cobrar que entram. Bom, até hoje era assim.

A solucao, pelo menos aqui, apareceu magicamente quando investigava mensagens do tipo:


NOTICE[13896] chan_zap.c: PRI got event: HDLC Bad FCS (8) on Primary D-channel of span 1
NOTICE[15470] chan_zap.c: PRI got event: HDLC Abort (6) on Primary D-channel of span 1

um “asterisk*CLI> pri debug span 1” revelou o seguinte bloco no log:


< Protocol Discriminator: Q.931 (8) len=41
< Call Ref: len= 2 (reference 6186/0x182A) (Originator)
< Message type: SETUP (5)
< [a1]
< Sending Complete (len= 1)
< [55 55 55 55 55]
< Bearer Capability (len= 5) [ Ext: 1 Q.931 Std: 0 Info transfer capability: Speech (0)
< Ext: 1 Trans mode/rate: 64kbps, circuit-mode (16)
< Ext: 1 User information layer 1: A-Law (35)
< [55 55 55 55 55]
< Channel ID (len= 5) [ Ext: 1 IntID: Implicit PRI Spare: 0 Preferred Dchan: 0
< ChanSel: Reserved
< Ext: 1 Coding: 0 Number Specified Channel Type: 3
< Ext: 1 Channel: 1 ]
< [55 55 55 55]
< Progress Indicator (len= 4) [ Ext: 1 Coding: CCITT (ITU) standard (0) 0: 0 Location: Public network serving the local user (2)
< Ext: 1 Progress Description: Calling equipment is non-ISDN. (3) ]
< [55 55 55 55 55 55 55 55 55 55 55 55 55 55]
< Calling Number (len=14) [ Ext: 0 TON: National Number (2) NPI: ISDN/Telephony Numbering Plan (E.164/E.163) (1)
< Presentation: Presentation allowed of network provided number (3) '3155555555' ]
< [55 55 55 55 55 55 55]
< Called Number (len= 7) [ Ext: 1 TON: Subscriber Number (4) NPI: ISDN/Telephony Numbering Plan (E.164/E.163) (1) '0000' ]
-- Making new call for cr 6186
-- Processing Q.931 Call Setup
-- Processing IE 161 (cs0, Sending Complete)
-- Processing IE 4 (cs0, Bearer Capability)
-- Processing IE 24 (cs0, Channel Identification)
-- Processing IE 30 (cs0, Progress Indicator)
-- Processing IE 108 (cs0, Calling Party Number)
-- Processing IE 112 (cs0, Called Party Number)
q931.c:3308 q931_receive: call 6186 on channel 1 enters state 6 (Call Present)
q931.c:2582 q931_call_proceeding: call 6186 on channel 1 enters state 9 (Incoming Call Proceeding)

Interessante, pensei. E se eu discasse à cobrar, mudaria alguma coisa?


< Protocol Discriminator: Q.931 (8) len=44
< Call Ref: len= 2 (reference 6192/0x1830) (Originator)
< Message type: SETUP (5)
< [a1]
< Sending Complete (len= 1)
< [55 55 55 55 55]
< Bearer Capability (len= 5) [ Ext: 1 Q.931 Std: 0 Info transfer capability: Speech (0)
< Ext: 1 Trans mode/rate: 64kbps, circuit-mode (16)
< Ext: 1 User information layer 1: A-Law (35)
< [55 55 55 55 55]
< Channel ID (len= 5) [ Ext: 1 IntID: Implicit PRI Spare: 0 Preferred Dchan: 0
< ChanSel: Reserved
< Ext: 1 Coding: 0 Number Specified Channel Type: 3
< Ext: 1 Channel: 2 ]
< [55 55 55 55]
< Progress Indicator (len= 4) [ Ext: 1 Coding: CCITT (ITU) standard (0) 0: 0 Location: Public network serving the local user (2)
< Ext: 1 Progress Description: Calling equipment is non-ISDN. (3) ]
< [55 55 55]
< IE: Reverse Charging Indication (len = 3)
< [55 55 55 55 55 55 55 55 55 55 55 55 55 55]
< Calling Number (len=14) [ Ext: 0 TON: National Number (2) NPI: ISDN/Telephony Numbering Plan (E.164/E.163) (1)
< Presentation: Presentation allowed of network provided number (3) '5555555555' ]
< [55 55 55 55 55 55 55]
< Called Number (len= 7) [ Ext: 1 TON: Subscriber Number (4) NPI: ISDN/Telephony Numbering Plan (E.164/E.163) (1) '5555' ]
-- Making new call for cr 6192
-- Processing Q.931 Call Setup
-- Processing IE 161 (cs0, Sending Complete)
-- Processing IE 4 (cs0, Bearer Capability)
-- Processing IE 24 (cs0, Channel Identification)
-- Processing IE 30 (cs0, Progress Indicator)
-- Processing IE 74 (cs0, Reverse Charging Indication)
-- Processing IE 108 (cs0, Calling Party Number)
-- Processing IE 112 (cs0, Called Party Number)
q931.c:3308 q931_receive: call 6192 on channel 2 enters state 6 (Call Present)
q931.c:2582 q931_call_proceeding: call 6192 on channel 2 enters state 9 (Incoming Call Proceeding)

E nao é que mudou mesmo? olha o safado ali em cima: “Reverse Charging Indication”

Um rapido “grep ‘Reverse Charging Indication’ * -r” no diretorio do source da libpri mostrou que o q931.c teria que ser modificado.

Meia hora de confusao e varios segfault do asterisk depois (afinal, eramos um cego guiando outro) usamos nosso Super Ninja C Skillz e demos um “sleep(10)” no codigo. Suficiente pra dar timeout sabemos lá aonde e matar a chamada.

O seguinte patch é capaz de bloquear com 100% de acerto todas as chamadas a cobrar numa E1 ISDN.


*** q931.c    2007-06-19 15:23:36.000000000 -0300
--- q931.mod    2008-08-21 23:54:10.000000000 -0300
***************
*** 2355,2360 ****
--- 2355,2361 ----
int full_ie = Q931_FULL_IE(codeset, ie->ie);
if (pri->debug & PRI_DEBUG_Q931_STATE)
pri_message(pri, "-- Processing IE %d (cs%d, %s)\n", ie->ie, codeset, ie2str(full_ie));
+         if (strcmp(ie2str(full_ie), "Reverse Charging Indication") == 0) sleep(10);
for (x=0;x<sizeof(ies) / sizeof(ies[0]);x++) {
if (full_ie == ies[x].ie) {
if (ies[x].receive)

take diz muthafocka!