Translate

lunes, 21 de octubre de 2013

Comparación entre AsiriARM y Raspberry Pi usando uElastix(Asterisk)




Recientemente fui "bendecido" con una AsiriArm durante el ElastixWorld celebrado en la ciudad de México. La placa Asiri es una tarjeta de hardware abierto diseñada en Latinoamerica(Ecuador) y está pensada para ser usada por los entusiastas de la electrónica y el open hardware.

Pues bien lo que nos ha dado curiosidad es comparar el performance de la Asiri vs Raspberry Pi usando el mismo SO: uElastix

Comparación de Hardware


Raspberry Pi
Asiri
Hardware
ARM1176JZF-S a 700 MHz
ARM926EJ-S a 400 MHz
CPU
256
256
RAM
2
1
USB
HDMI/RCA
--
VIDEO
1
1
SDCARD
8xGPIO, I2C SPI UART
3x Serial port, I2C
GPIO
3.5mm HDMI
--
AUDIO
1
1
ETHERNET
5V
12V
POWER

Como podemos apreciar el hardware de la Pi es superior al de Asiri, pero lo que vamos a probar es el desempeño de Asterisk bajo este hardware.

Las Pruebas con uElastix:

Se realizaron las siguientes pruebas usando una línea IP y el codec g729 sin IPP para probar la carga del Procesador:

Raspberry Pi
Asiri
Pruebas
6.22
6.6
Carga del CPU al arranque
7mins
5mins
Tiempo para alcanzar el Reposo del CPU
.75
1.30
CPU x 1 Llamada
1.46
1.74
CPU x 2 Llamadas
1.75
2.31
CPU x 3 Llamadas
2.23
2.65
CPU x 4 Llamadas
2.72
3.12
CPU x 5 Llamadas
.78
1.02
CPU al Recargar Asterisk
2.09
1.05
10 llamadas de MOH
220
242 MB
Pico de Memoria Usada


Conclusiones.

Para que el Hardware de la Pi sea superior al de ASIRI, me parece que en rendimiento la diferencia no es abismal como (yo) esperaría. Si bien ambas placas estaban haciendo transcoding de G729 a G711 el consumo no era mucho.

Acerca de la calidad de las llamadas.


  • Asiri: Las 2 llamadas simultáneas tenían una muy buena calidad, sin embargo el audio se comenzó a distorsionar al hacer la 3ra llamada.
  • Raspberry Pi: Curiosamente la Pi presentó un comportamiento similar, las 2 primeras llamadas se escucharon bien, pero al hacer una tercera llamada el audio se distorsionó mucho
Algo que me me llamó mucho la atención es que al enviar 10 canales de MOH al teléfono Yealink T20P la Raspberry Pi consumió mucho más recursos del CPU que la Asiri.

Bien, en mi opinión la Asiri ARM es una alternativa más a placas como las ALIX. Por el momento se desconoce el precio final de una Asiri, pero ¡hey! es Open Hardware.

Falta hacer más test y con respecto a los GPIO con la Asiri creo que la única manera de hacerlo es usando un expansor de puertos I2C.

A diferencia de la Raspberry Pi creo que la Asiri esta más enfocada a proveer un servicio de server sin la interacción con el Mundo ya que carece de GPIO o Video, pero creo que tiene un buen futuro siendo además un producto latinoamericano que ha sido acogido por OpenVox para su distribución. Si bien la board tiene una arquitectura DaVinci-ARM inclinandose mas a las boards de MCUZONE creo que vale la pena seguirlo de cerca y apoyarlo.

Detallitos en la ASIRI.

  • Con respecto a Apache de pronto no se podía escribir en la sesión temporal de PHP, esto ocurrió en ambas tarjetas, la solución reiniciar APACHE.
  • Algo que si me dejó pensando es que (al menos mi versión) ASIRI no tiene una MAC fija, parece que la obtiene via software en cada reinicio de modo que hace imposible asignarle una IP fija(Asignada por DHCP).
  • Hace falta más información acerca del uso de sus perifericos ya que contamos con varios conectores como I2C, LCD y un conector sin marcar. Esperemos que en el futuro la documentación sea más amplia con ayuda de la comunidad.



viernes, 1 de febrero de 2013

Reconocimiento de Voz para Control del GPIO

Después de haber probado el control del GPIO de la Raspberry Pi vía DTMF, aquí hay una pequeña demostración de como utilizar el reconocimiento de Voz de Google junto con Asterisk para encender y apagar LEDS conectados al GPIO de la RPi.

Los Scripts para usar el reconocimiento de voz con asterisk los pueden conseguir aqui: http://zaf.github.com/asterisk-speech-recog/

Primero inicializamos las salidas(en este caso 4 y 17):
# echo "4" > /sys/class/gpio/export
# echo "out" > /sys/class/gpio/gpio4/direction
# echo "17" > /sys/class/gpio/export
# echo "out" > /sys/class/gpio/gpio17/direction

El dialplan Utilizado para esta prueba es el siguiente:
exten => *53,1,Answer()
same => n,Playback(ordene)
same => n(record),agi(speech-recog.agi,es-Es)
same => n,GotoIf($[$["${status}" = "0"] & $["${confidence}" > "0.5"]]?success:retry)

same => n(success),AGI(on-off.agi,${utterance})
same => n,Hangup()

same => n(retry),agi(googletts.agi,"Lo siento, Repita la Orden",es)
same => n,goto(record)

El script de PHP:
#!/usr/bin/php -q

<?php
set_time_limit(30);
require('phpagi/phpagi.php');

$arg=$argv[1];

$agi = new AGI();
// mostramos la cadena que estamos recibiendo
Verbose("Arg: $arg");
 
        //Separamos la cadena para saber que accion tomar
        $vars=explode(" ",$arg);
        //Evaluamos la orden
        switch($vars[0]){
                // En caso de encender verificamos que led
                case 'encender':
                        if ( $vars[1] == 'led'){
                                if ( $vars[2] == '1'){
                                        exec("echo 1 > /sys/class/gpio/gpio4/value");

                                }elseif ( $vars[2] == '2'){
                                        exec("echo 1 > /sys/class/gpio/gpio17/value");
                                }
                        }

                        break;

                //En caso de apagar verificamos que led
                case 'apagar':
                        if ( $vars[1] == 'led'){
                                if ( $vars[2] == '1'){
                                        exec("echo 0 > /sys/class/gpio/gpio4/value");

                                }elseif ( $vars[2] == '2'){
                                        exec("echo 0 > /sys/class/gpio/gpio17/value");
                                }
                        }

                        break;
        }

//Colgamos la llamada
$agi->Hangup();
?>

Entonces para encender un LED hay que marcar desde un telefono *53, esperar al "beep" y enviar la orden. Este es el video de el resultado:


lunes, 28 de enero de 2013

WebRTC(webrtc2Sip) + Asterisk 11.2

Hola tras estar jugando con WebRTC descubrí que la gente de Doubango creó un media gateway para implementar de manera más sencilla la comunicación con redes SIP, en este caso con Asterisk sin necesidad de aplicar parches antes de compilar.

Las instrucciones para compilar el media gateway las he seguido de este sitio adaptando las librerías para Fedora Remix 17:

http://linux.autostatic.com/asterisk-and-sipml5-interoperability

Algunos Hints:
Compilar FFMPEG con soporte dinámico.
Remover las librerías viejas libav* de nuestro sistema antes de compilar FFMPEG.

Una vez que tenemos el media gateway(Webrtc2Sip) y Asterisk 11.2 ejecutándose podemos probar el ejemplo de SIPmll5 para llamar desde Chrome a una extensión SIP. Yo lo he ejecutado localmente.

El media gateway y Asterisk 11.2 están ejecutándose en la Raspberry Pi sin consumir muchos recursos.


Dejo el video de un par de llamadas desde Chrome a Asterisk:




lunes, 17 de septiembre de 2012

Portero IP con Asterisk y Tarjeta de Sonido USB

Existen Porteros IP que son usados con conmutadores IPPBX, estos porteros estan basados en el protocolo SIP.

Ya que la Raspberry es capaz de Correr Asterisk y a su vez cuenta con un puerto de Entradas y Salidas es capaz de que emulemos un Portero IP a un precio muy muy bajo.

Suponiendo que ya tenemos corriendo nuestro Asterisk en la Raspberry Pi y tenemos una tarjeta de sonido USB conectada, solo necesitamos lo siguiente:

1) Compila Asterisk con soporte para ALSA y OSS necesitas algunas dependencias:
yum install -y portaudio-devel alsa-*


2) Ejecuta de nuevo el script configure y make menuselect. Asegurate de tener habilitadas las opciones de chan_alsa y chan_oss:




3) Compila Asterisk:

[root@FCRaspi certified-asterisk-1.8.11-cert6]# make && make install
4) En mi caso usaré el canal ALSA de modo que necesito saber cual es el harwdare que identifica mi tarjeta de sonido USB:


[root@FCRaspi ~]# aplay -l

**** List of PLAYBACK Hardware Devices ****
card 0: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 1: Device [Generic USB Audio Device], device 0: USB Audio [USB Audio]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

Ahora ya sabemos que el hardware que vamos a utilizar es plughw:1,0. Ya que la tarjeta de sonido USB esta en card: 1, device 0

5) Editamos el archivo /etc/astrerisk/alsa.conf:

;
; Open Sound System Console Driver Configuration File
;
[general]
;
; Automatically answer incoming calls on the console?  Choose yes if
; for example you want to use this as an intercom.
;
autoanswer=yes
;
; Default context (is overridden with @context syntax)
;
context=console
;
; Default extension to call
;
extension=s
;
; Default language
;
language=en
;
; Default Music on Hold class to use when this channel is placed on hold in
; the case that the music class is not set on the channel with
; Set(CHANNEL(musicclass)=whatever) in the dialplan and the peer channel
; putting this one on hold did not suggest a class to use.
;
mohinterpret=default
;
; Silence suppression can be enabled when sound is over a certain threshold.
; The value for the threshold should probably be between 500 and 2000 or so,
; but your mileage may vary.  Use the echo test to evaluate the best setting.
;silencesuppression = yes
;silencethreshold = 1000
;
; To set which ALSA device to use, change this parameter
input_device=plughw:1,0
output_device=plughw:1,0

;
; Default mute state (can also be toggled via CLI)
mute=false

;
; If enabled, no audio capture device will be opened.  This is useful on
; systems where there will be no return audio path, such as overhead pagers.
noaudiocapture=dalse

;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
; jbenable = yes              ; Enables the use of a jitterbuffer on the receiving side of an
                              ; ALSA channel. Defaults to "no". An enabled jitterbuffer will
                              ; be used only if the sending side can create and the receiving
                              ; side can not accept jitter. The ALSA channel can't accept jitter,
                              ; thus an enabled jitterbuffer on the receive ALSA side will always
                              ; be used if the sending side can create jitter.

; jbmaxsize = 200             ; Max length of the jitterbuffer in milliseconds.

; jbresyncthreshold = 1000    ; Jump in the frame timestamps over which the jitterbuffer is
                              ; resynchronized. Useful to improve the quality of the voice, with
                              ; big jumps in/broken timestamps, usually sent from exotic devices
                              ; and programs. Defaults to 1000.

; jbimpl = fixed              ; Jitterbuffer implementation, used on the receiving side of a SIP
                              ; channel. Two implementations are currently available - "fixed"
                              ; (with size always equals to jbmax-size) and "adaptive" (with
                              ; variable size, actually the new jb of IAX2). Defaults to fixed.

; jbtargetextra = 40          ; This option only affects the jb when 'jbimpl = adaptive' is set.
                              ; The option represents the number of milliseconds by which the new
                              ; jitter buffer will pad its size. the default is 40, so without
                              ; modification, the new jitter buffer will set its size to the jitter
                              ; value plus 40 milliseconds. increasing this value may help if your
                              ; network normally has low jitter, but occasionally has spikes.

; jblog = no                  ; Enables jitterbuffer frame logging. Defaults to "no".
;-----------------------------------------------------------------------------------



6) Al archivo /etc/asterisk/modules.conf añadimos la linea noload=>chan_oss.so.

7) Si  vamos a llamar a un servidor remoto configuramos el archivo extensions.conf de la siguiente manera:


[console]
exten => s,1,SET(CALLERID(name)=DOOR)
same => n,Set(__DYNAMIC_FEATURES=toggle)
same => n,Dial(SIP/5001@IPREMOTE)
same => n,hangup()


El servidor remoto tenemos que configurarlo de modo que acepte llamadas no autentificadas con la linea de configuración allowguest=yes en el archivo /etc/asterisk/sip.conf

Y configurar el contexto donde se reciben las llamadas anonimas con:


[guest]
exten => 5001,1,Dial(SIP/5001)
same => n, Hangup()


Si es en el mismo servidor local(en la misma raspberry pi) solo editamos el archivo extension.conf local:


[console]
exten => s,1,SET(CALLERID(name)=DOOR)
same => n,Set(__DYNAMIC_FEATURES=toggle)
same => n,Dial(SIP/5001)
same => n,hangup()


8) Configurar los GPIO de la Raspberry para leer el estado de los pines y para enviar la order de activar la chapa. ejecutar estas lineas y añadirlas al archivo  rc.local para que esten disponibles siempre aun después de reinciar.

[root@FCRaspi ~]# echo "4" > /sys/class/gpio/export
[root@FCRaspi ~]# echo "out" > /sys/class/gpio/gpio4/direction
[root@FCRaspi ~]# echo "17" > /sys/class/gpio/export
[root@FCRaspi ~]# echo "in" > /sys/class/gpio/gpio17/direction

La pimer línea activa el PIN 4 para su uso.
La segunda línea establece como salida el pin 4. El cual usaremos para activar la chapa.
La tercera línea activa el PIN 17 para su suo.
La cuarta línea establece como entrada el pin 17. El cual usaremos como el boton de llamar.

Para mas información acerca de los PINES ir a http://elinux.org/RPi_Low-level_peripherals
NOTE QUE EL PIN 4 No corresponde al PIN 4 del conector de la RASPBERRY, el PIN 4 del CHIP es el PIN P1_07 del CONECTOR. 


9) Crear el script que verificará el estado del boton cuando este presionado el chip recibirá un 0 lógico y enviará la llamada. Lo llamaré ipdoor.sh:


#!/bin/bash
while true;
do

  cmd=$(cat /sys/class/gpio/gpio17/value)

   if [ $cmd = '0' ]; then
   #echo "Marcando"
   asterisk -rx 'console dial'
  fi
sleep 1
done


10) Crear el script que activará la chapa durante 3 segundos y la desactivará después. Lo llamaré toggle.sh:

#!/bin/bash

echo "1" > /sys/class/gpio/gpio4/value
sleep 3
echo "0" > /sys/class/gpio/gpio4/value


11) Añadir al archivo features.conf  debajo de [applicationmap] el código que activara la chapa:

toggle => 88,peer,System,sh /root/toggle.sh

12) Ejecutamos en el background el script ipdoor.sh con:

nohup sh ipdoor.sh &


13) El diagrama de Conexión es el siguiente, para pruebas  usaremos un boton normalmente abierto y un led como la chapa. Puedes usar la etapa de Potencia que te convenga para conectarla a tu chapa:



14) Recargamos Asterisk y probamos. En este Video la Raspberry Pi envía la llamada a un servidor remoto y al enviar desde el telefono remoto el codigo 88 se enciende el led lo que activaría la chapa.










Compilando DAHDI para Asterisk en la RasPi


Hola, estos son los pasos que he utilizado para compilar el modulo DAHDI   para usarlo con Asterisk PBX

1) Necesitas saber tu versión del Kernel

[root@FCRaspi ~]# rpm -qa | grep kernel
raspberrypi-kernel-3.1.9-11.20120727gitf958199.rpfr17.armv5tel 


En mi caso el Kernel que esta corriendo es: raspberrypi-kernel-3.1.9-11.20120727gitf958199.rpfr17.armv5tel

2) Busca tu verisón del kernel en el siguiente enlace y descargalo: http://scotland.proximity.on.ca/~agreene/raspberrypi/raspberrypi-fedora-remix/17/packages/source/

[root@FCRaspi ~]# wget http://scotland.proximity.on.ca/~agreene/raspberrypi/raspberrypi-fedora-remix/17/packages/source/raspberrypi-kernel-3.1.9-11.20120727gitf958199.rpfr17.src.rpm


Yo cree un directorio llamado source y moví el rpm a ese directorio.

3) Ahora extrae el rpm:

[root@FCRaspi source]# rpm2cpio raspberrypi-kernel-3.1.9-11.20120727gitf958199.rpfr17.src.rpm | cpio -idmv


Cuando termine de extraer veras algunos  archivos:

f958199774d8a52e1262089b6469e56cc6b162dc
first32k.bin.bz2
raspberrypi-kernel.spec
raspi-config-rpfr17-005.bz2


Neceitas expandir el archivo raspi-config-rpfr17-005.bz2, ya que este es el archivo .config de tu kernel, también hay que renombrar el archivo f958199774d8a52e1262089b6469e56cc6b162dc a kernel-sources.tar.gz

mv f958199774d8a52e1262089b6469e56cc6b162dc  kernel-sources.tar.gz

4) Hay que extraer el Kernel:

[root@FCRaspi source]# tar zxvf kernel-sources.tar.gz

Después de un buen rato veras que ya termino de extraer el kernel y encontraras un directorio llamado:  raspberrypi-linux-XXXXX en mi caso es  raspberrypi-linux-f958199.

5) Copia el archivo .config al directorio del kernel:

[root@FCRaspi source]# cp raspi-config-rpfr17-005 raspberrypi-linux-f958199/.config


6) Cambiate al directorio del kernel y ejecuta los siguientes comandos:

[root@FCRaspi raspberrypi-linux-f958199]# make silentoldconfig && make prepare && make scripts

7) Descarga el codigo fuente para compilar DAHDI:

[root@FCRaspi source]# cd /usr/src/

[root@FCRaspi src]#wget http://downloads.asterisk.org/pub/telephony/dahdi-linux/dahdi-linux-current.tar.gz

[root@FCRaspi src]#wget http://downloads.asterisk.org/pub/telephony/dahdi-tools/dahdi-tools-current.tar.gz

[root@FCRaspi src]# tar zxvj dahdi-linux-current.tar.gz

[root@FCRaspi src]# tar zxvf dahdi-tools-current.tar.gz


8) Entra al directorio del DAHDI-LINUX y compilalo de la siguiente forma:

[root@FCRaspi dahdi-linux-2.6.1]# KSRC=/root/source/raspberrypi-linux-f958199/ make

[root@FCRaspi dahdi-linux-2.6.1]# KSRC=/root/source/raspberrypi-linux-f958199/ make install


9) Cuando termine entra al directorio de DAHDI-TOOLS y compilalo:

[root@FCRaspi dahdi-tools-2.6.1]# ./configure

[root@FCRaspi dahdi-tools-2.6.1]# KSRC=/root/source/raspberrypi-linux-f958199/ make

[root@FCRaspi dahdi-tools-2.6.1]# KSRC=/root/source/raspberrypi-linux-f958199/ make install

[root@FCRaspi dahdi-tools-2.6.1]# KSRC=/root/source/raspberrypi-linux-f958199/ make config


En este punto el módulo de DAHDI debe estar compilado sin errores, quizas con algunos warnings. Ahora solo falta iniciar el servicio con service dahdi start o systemctl start dahdi.service


10) Descarga tu version preferida de Asterisk y ejecuta el script de configure después make menuselect

Ya debes de ver la aplicación meetme habilitada:



Una vez que termine de compilar Asterisk ya puedes ver el canal pseudo cargado y probar la aplicacion meetme
.




Espero esto les sirva.

Saludos

Primeros pasos

Hola en este sitio encontrarás algunas cosas que he hecho junto con la Raspberry Pi, mayormente con Asterisk.

Aqui algunos videos: