OpenSIPs e Asterisk

De opensipsbrasil - wiki
Ir para navegação Ir para pesquisar
Precisando de recursos de númeração para fazer seus testes ? Contrate conosco em BRDVoz Ou talvez gostaria de uma consultoria no seu proejto ? Também estamos disponiveis em BRDSoft



Falta realizar os ajustes / testes para o NAT no mais esta tudo funcionado adequadamente a principio


Este tutorial é baseado em um tutorial similar porém utilizando Kamailio e Freeswtich, se quiser verificar o tutorial original acesse http://kb.asipto.com/freeswitch:kamailio-3.1.x-freeswitch-1.0.6d-sbc.

Para esta implementação utilizamos Debian 7.0 amd64 , OpenSIPS 1.9 e Asterisk 1.8.23

Funcionalidades

Este tutorial tem por objetivo atingir as seguintes funcionalidades.

  • Autenticação de usuário
  • Registro de usuário
  • Localização de usuário (encaminhamento de chamadas)
  • Roteamento de chamadas


Através do Asterisk estenderemos estas funcionalidades agregando.

  • Correio de voz (Voicemail)
  • Conferencia
  • SBC ( Pode ser utilizado para transcoding, esconder topologia, play de mensagens e tarifação )
  • Outros serviços de media (Anuncios, Ura's e coisas do tipo)

Definições

Para um melhor entendimento da solução vamos expor aqui algumas definições de nosso sistema.

  • Usuários locais terão ramais com 3 digitos (ex: 101, 102, 103)
  • Identidade do correio de voz será o mesmo do ramal
  • Serviços de media (acesso a voicemail e outros) receberão rotas de 4 digitos
  • Opensips e Asterisk utilizarão o mesmo servidor (Neste caso IP: 10.254.254.6)
  • Os serviços rodarão nas portas 5060 (opensips) , 5090 (Asterisk)

Funcionamento

A autenticação do usuário será realizada pelo OpenSIPs, quando uma chamada é autenticada então ela serguirá:

  • Se o usuário de destino não está online a chamada será enviada para o Asterisk para função de correio de voz
  • Se o usuário está online a chamada será encaminhada para o Asterisk, dest forma é possivel acionar funcionalidades como anuncios, definição de tempo de chamada, forçar codecs e outras funcionalidades.
  • Asterisk envia a chamada novamente para o OpenSIPs que verificará no location e entregará a chamada para o usuário.
  • Se a chamada não for atendida o Opensips irá re-encaminhar para o Asterisk direcionando para função de voicemail

OpenSIPs

Vamos iniciar o processo de instalação com o OpenSIPs, siga os procedimentos abaixo para evitar qualquer dificuldade.

Dependencias

Execute o comando abaixo para instalar todas as dependencias necessárias

apt-get install gcc make libncurses5-dev libnewt-dev libxml2-dev unixodbc \ 
unixodbc-dev libmysqlclient15-dev libxmlrpc-c3-dev libexpat1-dev zlib1g-dev \ 
m4 bison flex libpcre3-dev mysql-server vim apache2-mpm-prefork libapache2-mod-php5 \
 php5-mysql php5-xmlrpc php-pear  ngrep g++ libjpeg62-dev libssl-dev 


Durante a instalação o sistema irá lhe perguntar a senha de root para o servidor MySQL é importante que você se lembre da mesma posteriormente pois utilizaremos a mesma.

Compilando o OpenSIPs

Para manter um padrão onde os dados estao vamos utilizar o diretório /usr/src/ para o download de código fonte.

cd /usr/src/
wget -c http://opensips.org/pub/opensips/1.9.1/src/opensips-1.9.1_src.tar.gz
tar -xzvf opensips-1.9.1_src.tar.gz
cd opensips-1.9.1-tls/
make menuconfig

Neste ponto o sistema irá abrir uma tela com algumas opções para selecionar, Acesse a primeira opção do menu, no submenu acesse a segunda opção ( Configure excluded modules ), selecione os módulos db_mysql , dialplan , mi_xmlrpc , presence e presence_xml

Agora volte ao submenu, e selecione a opção Save Changes, volte para o menu principal e selecione Compile and Install OpenSips , deixe que o sistema execute suas funções.


Ao finalizar a compilação você retornará ao menu, va na opção Exit and Save all changes

Preparando a Configuração

Antes de darmos inicio ao arquivo de configuração, vamos ajustar algumas questões, o opensips instala os arquivos (se voce nao alterar o parametro) em /usr, consequentemente as configurações ficam em /usr/etc , eu por padrão faço um link para o diretório /etc, assim acesso as configurações em /etc/opensips

ln -s /usr/etc/opensips /etc/

No caso do debian o script de inicialização utiliza um arquivo extra de configuração

cp packaging/debian/opensips.default /etc/default/opensips

Para o script de inicialização execute o comando abaixo

cp packaging/debian/opensips.init /etc/init.d/opensips
chmod +x /etc/init.d/opensips
update-rc.d opensips defaults

Edite o arquivo /etc/default/opensips , a altere o parametro RUN_OPENSIPS para yes

Você pode notar que no arquivo é mensionado o usuário de execução do opensips como opensips, então vamos ter de criar este usuário ( e grupo )

groupadd opensips
mkdir /var/run/opensips
useradd -d /var/run/opensips/ -s /bin/false -g opensips opensips
chown -R opensips.opensips /var/run/opensips


Configurando o opensipsctl

O opensipsctl (e opensipsdbctl) utilizam o arquivo de configuração /etc/opensips/opensipsctlrc, abaixo segue o conteúdo do arquivo. (Sugiro que você faça um backup dos arquivos originais para ter uma copia, existem parametros que você pode estudar depois).

DBENGINE=MYSQL
DBHOST=localhost
DBNAME=opensips
DBRWUSER=opensips
DBRWPW="opensipsrw"
SIP_DOMAIN=10.254.254.6  ### caso voce esteja usando outro ip altere aqui


DBROOTUSER="root"
INSTALL_EXTRA_TABLES=ask
ALIASES_TYPE="DB"
MI_CONNECTOR=FIFO:/tmp/opensips_fifo
# VERIFY_ACL=1
# ACL_GROUPS="local ld int voicemail free-pstn"
# VERBOSE=1
# STORE_PLAINTEXT_PW=0
# NOHLPRINT=1
PID_FILE=/var/run/opensips/opensips.pid

Criando o banco de dados

Agora que temos nosso arquivo configurado vamos fazer a criação do banco de dados, execute o comando abaixo.

opensipsdbctl create opensips

O sistema irá lhe perguntar algumas coisas, responda Y (sim) para todas para que ele instale todas as tabelas, não usaremos todas elas, mas desta forma você fica com praticamente tudo criado para o caso de uma expansão dos recursos.


Instalando o RTP Proxy

cd /usr/src/
wget -c http://b2bua.org/chrome/site/rtpproxy-1.2.1.tar.gz
tar -xzvf rtpproxy-1.2.1.tar.gz
cd rtpproxy-1.2.1
./configure
make
make install
groupadd rtpproxy
useradd -d /var/run/rtpproxy -s /bin/true -g rtpproxy rtpproxy
mkdir /var/log/rtpproxy
mkdir /var/run/rtpproxy
chown -R rtpproxy.rtpproxy /var/log/rtpproxy
chown -R rtpproxy.rtpproxy /var/run/rtpproxy

Arquivo de inicialização

/etc/init.d/rtpproxy

#!/bin/bash
#
# Este script e de autoria de Mike Tesliuk
# qualquer falha no mesmo por favor informe 
# atraves do email mike (a) tesliuk.com
#
### BEGIN INIT INFO
# Provides:          rtpproxy
# Required-Start:    $syslog $network $local_fs $time
# Required-Stop:     $syslog $network $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start the RTPPROXY server
# Description:       Start the RTPPROXY server
### END INIT INFO

PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
USELOG=1
USER=rtpproxy
# Altere o ip abaixo para o ip de seu sistema
IPADDR="10.254.254.6"

. /lib/lsb/init-functions


start(){
        echo "Iniciando RTP PROXY "
        if [ -z $(pidof rtpproxy) ]; then
                if [ "${USELOG}" = "1" ]; then
                        echo "Iniciando com LOG"
                        /usr/local/bin/rtpproxy -l $IPADDR -s udp:127.0.0.1:7722 -u $USER -F -f d DBUG 2&> /var/log/rtpproxy/rtpproxy.log &
                else
                        echo "Iniciando sem LOG"
                        /usr/local/bin/rtpproxy -l $IPADDR -s udp:127.0.0.1:7722 -u $USER  -F -f d DBUG 2&> /dev/null
                fi

                if [ -n $(pidof rtpproxy) ]; then
                        echo "START OK"
                fi
        else
                echo "Processo ja em execucao"
        fi
}


stop(){

        if [ -z $(pidof rtpproxy) ]; then
                echo "Processo nao encontrado"
        else
                kill -9 $(pidof rtpproxy)
                if [ -n $(pidof rtpproxy) ]; then
                        echo "STOP OK"
                else
                        echo "Falha em realizar stop do servico"
                fi

        fi
}

case $1 in
        start)
                start
        ;;
        stop)
                stop
        ;;
        restart)
                stop
                start

        ;;
        *)
                echo "Utilize: stop | start | restart"
        ;;
esac

Vamos dar permissao e colocar na inicialização

chmod +x /etc/init.d/rtpproxy 
update-rc.d rtpproxy defaults
/etc/init.d/rtpproxy start


Criando o arquivo opensips.cfg

O arquivo opensips.cfg é a onde a coisa toda acontece para o opensips, claro que ele dependerá de informações que estarão no banco de dados, mas é onde criamos todas as nossas rotas e validações.


####### Global Parameters #########
debug=3
log_stderror=no
log_facility=LOG_LOCAL0

fork=yes
children=4

/* Descomente as linhas abaixo para ativar o debug */
#debug=7
#fork=no
#log_stderror=yes


/* Comente a linha abaixo para ativar a descoberta automatica de enderecos locais
 , isso significa que o sistema ira verificar todos os ips ativos e hosts e entao ativara
 o protocolo para todos eles */ 
auto_aliases=no

/* Defina aqui o ip a ser utilizado */
listen=udp:10.254.254.6:5060   # Altere este IP para o seu ambiente

/* Nao usaremos sip por tcp nem tls neste script */
disable_tcp=yes

disable_tls=yes


####### Secao de modulos ########

#set module path
mpath="/usr//lib64/opensips/modules/"

loadmodule "signaling.so"
loadmodule "sl.so"
loadmodule "tm.so"
modparam("tm", "fr_timer", 5)
modparam("tm", "fr_inv_timer", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)

loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)


loadmodule "maxfwd.so"
loadmodule "sipmsgops.so"
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)

loadmodule "db_mysql.so"


loadmodule "uri.so"
modparam("uri", "use_uri_table", 0)

loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "FLB_NATB")
modparam("usrloc", "db_mode",   2)
modparam("usrloc", "db_url",  "mysql://opensips:opensipsrw@localhost/opensips")


loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")

/* Descomente a linha abaixo para nao permitir mais de 10 contatos por conta */
#modparam("registrar", "max_contacts", 10)

loadmodule "acc.so"
/* Quais eventos deverao ser registrados ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* por padrao nos nao ajustamos a direcao em requisicoes sequencias, 
 se voce deseja usar este recurso tenha certeza de ativar o "appen_fromtag" 
 para o modulo "rr" */
modparam("acc", "detect_direction", 0)
modparam("acc", "failed_transaction_flag", "FLT_ACCFAILED")
/* Gatilhos para accounting  (flags) */
modparam("acc", "log_flag", "FLT_ACC")
modparam("acc", "log_missed_flag", "FLT_ACCMISSED")
modparam("acc", "log_extra", 
	"src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
modparam("acc", "db_flag", "FLT_ACC")
modparam("acc", "db_missed_flag", "FLT_ACCMISSED")
modparam("acc", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
modparam("acc", "db_extra", "src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd" )

loadmodule "auth.so"
loadmodule "auth_db.so"
modparam("auth_db", "db_url",  "mysql://opensips:opensipsrw@localhost/opensips")
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("auth_db", "load_credentials", "")


loadmodule "permissions.so"
modparam("permissions", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")

loadmodule "alias_db.so"
modparam("alias_db", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")

loadmodule "presence.so"
modparam("presence", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")

#loadmodule "presence_xml.so"


loadmodule "dialog.so"
modparam("dialog", "db_mode", 2)
modparam("dialog", "db_url","mysql://opensips:opensipsrw@localhost/opensips")
modparam("dialog", "dlg_match_mode", 1)
#modparam("dialog", "default_timeout", 60)

loadmodule "siptrace.so"
modparam("siptrace", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
modparam("siptrace", "trace_flag", 22)
modparam("siptrace", "traced_user_avp", "$avp(s:traceuser)")


loadmodule "nathelper.so"
modparam("nathelper", "natping_interval", 30)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", "FLB_NATSIPPING")
modparam("nathelper", "sipping_from", "sip:pinger@10.254.254.6") # Altere o ip para o ip do servidor
modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")

loadmodule "rtpproxy.so"
modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7722")



####### Logica de roteamento ########


route {

	if (!mf_process_maxfwd_header("3")) {
                send_reply("483","looping");
                exit;
        }

	xlog("REQUISICAO RECEBIDA, ENVIANDO PARA REQINIT");
	# Checagem inicial por requisicao
	route(REQINIT);

	xlog("ENVIANDO PARA NAT");
	# Deteccao de nat
	route(NAT);

	xlog("ENVIANDO PARA WITHINDLG");
	# Gerenciando requisicaoes com dialog
	route(WITHINDLG);

	# Manipulando requisicoes iniciais (nao consta To tag)
	
	# Processando CANCEL

	if(is_method("CANCEL")){
		xlog("METHOD CANCEL");
		if(t_check_trans()){
			t_relay();
		}
		exit;
	}

	t_check_trans();

	# Enviando para autenticacao
	xlog("ENVIANDO PARA AUTENTICACAO");
	route(AUTH);

	# gravando rota para formacao dos dialogs (caso sejam roteados)
	# removemos qualquer cabecalho de rota pre carregado
	remove_hf("Route");
	if(is_method("INVITE|SUBSCRIBE")){
		xlog("METHOD INVITE OU SIBSCRIBE");
		record_route();
	}

	# Contabilizando (acc) INVITES
	if(is_method("INVITE")){
		xlog("METHOD INVITE, FAZENDOA ACC");
		setflag(FLT_ACC);
	}

	# Enviando chamada para destinos externos
	xlog("ENVIANDO PARA SIPOUT");
	route(SIPOUT);

	# Requisicoes para dominio local
	
	# Roteando requisicoes de PRESENCE
	xlog("ENVIANDO PARA PRESENCE");

	route(PRESENCE);

	# Gerenciando pedidos de registro
	xlog("ENVIANDO PARA REGISTRAR");	
	route(REGISTRAR);

	if($ru==""){
		xlog("ru --> vazio");
		# Requisicao sem usuario na RURI
		sl_send_reply("484", "Address Incomplete");
	}

	# Enviando requisicao para PSTN
	xlog("ENVIANDO PARA PSTN");
	route(PSTN);


	# Salvando informacao de quem originou a chamad
	$avp(callee)=$rU;
	xlog("ENVIANDO PARA DISPATCH PSTN");
	route(FSDISPATCH);


	
	# Servico de localizacao de usuario
	route(LOCATION);

	# Efetuando o relay (encaminhamento)
	route(RELAY);



}


route[RELAY] {
	if(check_route_param("nat=yes")){
		setbflag(FLB_NATB);
	}

	if(isflagset(FLT_NATS) || isbflagset(FLB_NATB)){
		#route(RTPPROXY);
	}

#	if(is_method("INVITE")){
#		t_on_reply("REPLY_ONE");
#		t_on_failure("FAIL_ONE");
#	}

	xlog("AQUI TENTAMOS ENVIAR A CHAMADA $fU $tU");
	if(!t_relay()){
		xlog("FALHA EM ENVIAR A CHAMADA, NAO FOI POSSIVEL FAZER O RELAY");
		sl_reply_error();
	}
	xlog("CHAMADA FOI ENVIADA AQUI, QUAL O ERRO ENTAO");

	exit;
}


route[REQINIT] {
	if(!mf_process_maxfwd_header("10")){
		sl_send_reply("483", "Too Many Hops");
		exit;
	}
	
}


route[WITHINDLG] {
	if(has_totag()){
		if(loose_route()){
			if(is_method("BYE")){
				setflag(FLT_ACC);
				setflag(FLT_ACCFAILED);
			}
			route(RELAY);
		}else{
			if(is_method("SUBSCRIBE") && uri==myself) {
				# requisicao de subscribe pre-estabelecida
				route(PRESENCE);
				exit;
			}

			if(is_method("ACK")){
				if(t_check_trans()){
					t_relay();
					exit;
				}
			}else{
				# ACK para transacao nao encontrada, ignoramos...
				exit;

			}
			
			sl_send_reply("404", "Not Here");

		}	
		exit;
	}
}


route[REGISTRAR] {

	if(is_method("REGISTER")){
		if(isflagset(FLT_NATS)){
			setbflag(FLB_NATB);
		}

		if(!save("location")){
			sl_reply_error();
		}

		exit;
	}

}

route[LOCATION] {

	alias_db_lookup("dbaliases");
	if(!lookup("location")){
		switch($rc) {
			case -1:
			case -3:
				t_newtran();
				t_reply("404","Not Found");
				exit;
			case -2:
				sl_send_reply("405", "Method Not Allowed");
				exit;
		}
	}


	if(is_method("INVITE")){
		setflag(FLT_ACCMISSED);
	}

	

}

route[PRESENCE] {
	if(!is_method("PUBLISH|SUBSCRIBE")){
		return;
	}

	if(!t_newtran()){
		sl_reply_error();
		exit;
	}

	if(is_method("PUBLISH")){
		handle_publish();
	}else if(is_method("SUBSCRIBE")){
		handle_subscribe();
	}
	exit;

}


route[AUTH]{
	xlog("PEDIDO DE AUTENTICACAO");
	if(is_method("REGISTER")){
		# atentica pedidos de registro
		if(!www_authorize("", "subscriber")){
			www_challenge("", "0");
			exit;
		}

		if($au!=$tU){
			sl_send_reply("403", "Forbidden auth ID");
			exit;
		}

		
	}else{
		if(route(FSINBOUND)){
			return;
		}

		if(check_source_address("0")){
			return;
		}

		if(from_uri==myself){
			if(!proxy_authorize("", "subscriber")){
				proxy_challenge("","0");
				exit;
			}

			if(is_method("PUBLISH")){
				if($au!=$tU){
					sl_send_reply("403", "Forbidden auth ID");
					exit;
				}
				
			}else{
				if($au!=$fU){
					sl_send_reply("403", "Forbidden auth ID");
					exit;
				}
			}

			
			# Validamos (autenticamos) o usuario
			consume_credentials();
		}else{
		
			# usuario nao e local, vamos negar
			if(!uri==myself){
				sl_send_reply("403", "Not relaying");
				exit;
			}	
		}
	}

	return;
}


route[NAT] {
	force_rport();
	if(nat_uac_test("19")){
		if(method=="REGISTER"){
			fix_nated_register();
		}else{
			fix_nated_contact();
		}
		setflag(FLT_NATS);
	}

	return;
}

route[RTPPROXY] {
	if(is_method("BYE")){
		unforce_rtp_proxy();
	}else if(is_method("INVITE")){
		engage_rtp_proxy();
	}

	if(!has_totag()){

		if(!check_route_param("nat=yes")){
			add_rr_param(";nat=yes");
			xlog("NAT yes NAO ENCONTRADO");
		}
	}

	return;
}

route[SIPOUT]{
	if(!uri==myself){
		append_hf("P-hint: outbound\r\n");
		route(RELAY);
	}
}

route[PSTN]{
        # neste caso apenas para exemplificar um uso simples
        # vamos fazer o redirecionamento par ao asterisk
        # realizar a dicagem da chamada

        if(!($rU=~"^(\+|00)[1-9][0-9]{3,20}$"))
                return;

        ## a regra acima aceita para discagem externa qualquer numero
        # comecado com 00 ou +
        #

        if(from_uri!=myself){
                sl_send_reply("403", "Not Allowed");
                exit;
        }

        $ru = "sip:" + $rU + "@" + "10.254.254.6:5090";
        xlog("NOVO DESTINO: $ru");
        route(RELAY);
        exit;

}

route[XMLRPC]{
	# nao vamos implementar esta funcionalidade
	return;
}

route[FSINBOUND] {
	# verificar para validar o ip do asterisk:porta
	# se bater , responder com return 1;
	if($si=="10.254.254.6" && $sp=="5090"){
		return(1);
	}else{
		return(-1);
	}
}

route[FSDISPATCH] {

	if(!is_method("INVITE")){
		return;
	}

	if(route(FSINBOUND)){
		return;
	}


	xlog("CAIMOS NO SWITCH, VAMOS LOCALIZAR O PERFIL DA CHAMADA $rU");


	if($rU =~ "^41$"){
			xlog("SWITCH expressa comeca e termina em 41");
			#regra de menu de voicemail, apenas 
			# usuarios autenticados
			if($au==""){
				sl_send_reply("403", "Not Allowed");
				exit;
			}

			$rU = "vma-" + $au;
	}else if($rU =~ "^441[0-9][0-9]$"){
			xlog("SWTICH OPCA 441XX ");
			# numero discado comeca com 441 seguido de dois digitos
			# chamada direta para inbox do voicemail
			strip(2);
			route(FSVBOX);
	}else if($rU =~ "^433[01][0-9][0-9]$"){
			xlog("SWITCH OPCAO 433[01]XX");
			# numero comecado em 443, seguido de 0 ou 1, mais dois digitos
			# sistema de conferencia
			strip(2);
	}else if($rU =~ "^45[0-9]+$"){
			xlog("SWTICH OPCAO 45X.");
			#numero comecado com 45, seguindo de numeros;
			strip(2);
	}else{
			xlog("OPCAO DEFAULT DO SWITCH");
			# usuario offline, enviando para voicemail
			if(!registered("location")){
				route(FSVBOX);
				exit;
			}

			# usuario online, fazendo bridging
			xlog("USUARIO ESTA ONLINE VAMOS FAZER BRIDGE");
			prefix("kb-");
			if(is_method("INVITE")){
				t_on_failure("FAIL_FSVBOX");
			}
	}
	route(FSRELAY);
	exit;
}

route[FSVBOX]{
	xlog("ENVIANDO PARA FSVBOX");
	$du = "sip:" + "10.254.254.6" + ":" + "5090";
	if($rU =~ "^441[0-9][0-9]"){
		strip(2);
	}
	prefix("vm-");
	if($var(newbranch)==1){
		append_branch();
		$var(newbranch)=0;
	}
	route(RELAY);
	exit;
}


route[FSRELAY] {
	xlog("ENVIANDO PARA FSRELAY");
	$du = "sip:" + "10.254.254.6" + ":" + "5090";
	if($var(newbranch)==1){
		append_branch();
		$var(newbranch)=0;
	}
	route(RELAY);
	exit;

}

branch_route[BRANCH_ONE]{
	xlog("new branch at $ru");
}


onreply_route[REPLY_ONE]{
	xlog("Incoming reply");
	if((isflagset(FLT_NATS) || isbflagset(FLB_NATB) && status =~ "(183)|(2[0-9][0-9])")){
		#rtpproxy_offer();
		
	}
	if(isbflagset(FLB_NATB)){
		fix_nated_contact();
	}

	
}



	


failure_route[FAIL_ONE]{
	xlog("FAILURE ROUTE FAIL_ONE");
	if(is_method("INVITE") && (isbflagset(FLB_NATB) || isflagset(FLT_NATS))){
		unforce_rtp_proxy();
	}

	if(t_was_cancelled()){
		exit;
	}

	
}


failure_route[FAIL_FSVBOX]{
	xlog("FAILURE ROUTE FAIL_FSVBOX");
	if(is_method("INVITE") && (isbflagset(FLB_NATB) || isflagset(FLT_NATS))){
		unforce_rtp_proxy();
	}

	if(t_was_cancelled()){
		exit;
	}

	if(t_check_status("486|408|480")){
		$rU = $avp(callee);
		$var(newbranch) = 1;
		route(FSVBOX);
	}
}


Testes com Opensips (registro)

Antes de podermos testar precisamos iniciar o serviço, no momento estamos com ele operando em modo debug, então a inicialização deve ser realizada com o comando abaixo

/etc/init.d/opensips debug

Abra uma nova sessão no servidor e então vamos criar os usuários

opensipsctl add 101 101
opensipsctl add 102 102
opensipsctl add 103 103

usuario 101 com senha 101 e assim por diante

Faça a onexão com seu softphone, aqui para testes utilizei o jitsi e o zoiper, neste momento vamos apenas fazer o registro do usuário para testar a autenticação, se você tentar realizar uma discagem não funcionará pois neste caso o processo depende do Asterisk que ainda não está configurado, vamos dar inicio nesta configuração agora.

Asterisk

Não vamos dar muitos detalhes da instalação do asterisk aqui, a ideia é simplesmente ter o mesmo funcionando da forma que necessitamos.

apt-get install asterisk

Após a instalação , abra o arquivo /etc/asterisk/sip.conf, localize a linha udpbindaddr=0.0.0.0 e altere para udpbindaddr=0.0.0.0:5090 , depois ao fim do arquivo adicione.

[opensips]
type=peer
host=10.254.254.6
port=5060
qualify=yes
context=opensips
insecure=port,invite
canreinvite=no

Agora abra o arquivo /etc/asterisk/extensions.conf , crie no fim do arquivo a seguinte entrada.

[opensips]

exten => _kb-1XX,1,NoOp(CHAMADA INTERNA - FAZER BRIDGE - ${CALLERID(num)} ${EXTEN:3})
same => n,Dial(SIP/opensips/${EXTEN:3})
same => n,Goto(opensips,vm-${EXTEN:3},1)
same => n,Hangup()

exten => _vm-1XX,1,NoOp(CHAMADA PARA VOICEMAIL)
same => n,Voicemail(${EXTEN:3}@default)
same => n,Hangup()

exten => _vma-1XX,1,NoOp(CHAMADA PARA VOICEMAIL - ADMINISTRATIVO)
same => n,VoicemailMain(${EXTEN:4}@default)
same => n,Hangup()

exten => _3[01]XX,1,NoOp(CHAMADA PARA CONFERENCIA)
same => n,Answer()
same => n,ConfBridge(${EXTEN},cM1)
same => n,Hangup()

exten => _00.,1,NoOp(CHAMADA PARA PSTN)
same => n,Wait(2)
same => n,Answer()
same => n,Wait(1)
same => n,PlayBack(tt-monkeys)
same => n,Hangup()

exten => h,1,Hangup()

Finalmente precisamos criar as entradas do voicemail, para isso altere o arquivo /etc/asterisk/voicemail.conf localize o contexto [default] e então adicione as entradas para seu voicemail, segue dois exemplos abaixo.

101 => 123123,Mike Tesliuk
102 => 123123,Mike Tesliuk 2

Feito isso, faça um restart no asterisk

/etc/init.d/asterisk restart

Agora você ja poderá fazer os testes, basicamente criamos as seguintes situações para serem testadas.

  • 1 Autenticação de usuários
  • 2 Chamada entre usuários
  • 3 Encaminhamento para caixa postal
  • 4 Acesso a caixa postal
  • 5 Acesso a conferência