Está en la página 1de 154

PROJECTE FINAL DE CARRERA

Diseño de aplicaciones sobre VoIP con


mecanismos de geoposicionamiento

Estudis: Enginyeria de Telecomunicació

Autor: Laura Duarte Domingo

Director/a: Marcel Fernández Muñoz

Any: 2014
A Isaac y a mi familia,
por la infinita paciencia que han
demostrado a lo largo de este viaje
II
Resumen

N LOS ÚLTIMOS AÑOS , la VoIP se ha ido introduciendo cada vez en más aspectos
E de nuestra vida cotidiana. Este proyecto nace de la intención de explorar las
posibilidades que ésta nos ofrece. Con la decisión de trabajar siempre con tecnología
open source se opta por utilizar dos tecnologías en auge en este momento. Asterisk,
utilizada cada vez en más empresas por su facilidad de implantación y flexibilidad.
No sólo ofrece la posibilidad de implementar una centralita de telefonía con VoIP de
forma económica, sino que además integra algunos servicios de valor añadido como los
ofrecidos por las más potentes centralitas comerciales. Android, que ha experimentado
un gran crecimiento desde su aparición, siendo uno de los dos sistemas operativos más
utilizado para smartphones y que nos permite crear aplicaciones de forma gratuita y
con un gran abanico de posibilidades a nuestra disposición.

El objetivo final es conseguir un proyecto que englobe estas tecnologías, con lo


que se realiza una plataforma de VoIP pensada para su utilización en una residencia
de ancianos (aunque la idea puede extrapolarse a otros escenarios). Utilizando
Asterisk como un servidor de VoIP, se crea además una centralita de telefonía con
reconocimiento de voz para la recepción del centro, que comunicará las llamadas
del exterior con los diferentes departamentos. Utilizando Android se diseñan dos
softphones para los smartphones de los miembros de la residencia. Además de las ca-
racterísticas básicas, los softphones de los residentes están diseñados para controlar la
ubicación de los mismos si se alejan demasiado de la residencia. De la misma manera,
los softphones de los trabajadores incluyen un sistema de comprobación de la ubicación
de los residentes en estos casos, así como la posibilidad de comprobar el sistema de
batería de los terminales de los residentes para que estas alertas no queden inutilizadas.

El desarrollo de este proyecto nos ha servido para darnos cuenta de la potencia que
tienen las herramientas que hemos utilizado y las amplias posibilidades que ofrecen
para proyectos futuros.

iii
IV
CONTENIDO

1 Introducción 9
1.1 P LATAFORMA DE V O IP . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.2 C ASOS DE USO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2 Conceptos Generales 13
2.1 V O IP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.1.1 ¿Q UÉ ES LA V O IP? . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.1.2 A RQUITECTURA . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.1.2.1 C OMPONENTES FUNDAMENTALES DE UNA RED V O IP . . . 14
2.1.2.2 T RANSMISIÓN DE LA V O IP POR LA RED . . . . . . . . . . 15
2.1.3 C ÓDECS DE AUDIO . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.1.4 P ROTOCOLOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.1.4.1 SIP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.1.4.1.1 E JEMPLO DE UNA COMUNICACIÓN SIP/RTP . . 18
2.1.4.2 H.323 . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.1.4.3 IAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.2 A STERISK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2.1 ¿Q UÉ ES A STERISK ? . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2.2 C ONCEPTOS BÁSICOS . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.2.3 A RQUITECTURA . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.2.3.1 S ERVICIOS Y FUNCIONALIDADES QUE OFRECE . . . . . . . 25
2.2.4 I NTEGRACIÓN CON LA RED CONMUTADA DE TELEFONÍA . . . . . . . 26
2.2.4.1 TARJETAS ANALÓGICAS . . . . . . . . . . . . . . . . . . . 26
2.2.4.2 TARJETAS DIGITALES . . . . . . . . . . . . . . . . . . . . 26
2.3 A NDROID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.3.1 ¿Q UÉ ES A NDROID ? . . . . . . . . . . . . . . . . . . . . . . . . . . 27

1
2.3.1.1 A RQUITECTURA . . . . . . . . . . . . . . . . . . . . . . . 27
2.3.1.2 A PLICACIONES . . . . . . . . . . . . . . . . . . . . . . . 28
2.3.1.2.1 A NATOMÍA DE UNA APLICACIÓN . . . . . . . . . 29
2.3.1.2.2 A NDROID M ANIFEST . . . . . . . . . . . . . . . 30
2.3.2 A CTIVIDADES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.3.2.1 C ICLO DE VIDA DE UNA A CTIVIDAD . . . . . . . . . . . . 31
2.3.3 I NTENTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.3.4 I NTERFAZ DE U SUARIO . . . . . . . . . . . . . . . . . . . . . . . . 33
2.3.4.1 C OMPONENTES DE LA PANTALLA . . . . . . . . . . . . . . 33
2.3.4.1.1 V ISTAS . . . . . . . . . . . . . . . . . . . . . . 33
2.3.4.1.2 L AYOUTS . . . . . . . . . . . . . . . . . . . . . 34
2.3.4.2 M ENÚS . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.3.4.3 D IÁLOGOS . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.3.4.4 N OTIFICACIONES . . . . . . . . . . . . . . . . . . . . . . 36
2.3.5 S ERVICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.3.6 B ROADCAST R ECEIVERS . . . . . . . . . . . . . . . . . . . . . . . 37
2.3.7 P ERSISTENCIA DE D ATOS . . . . . . . . . . . . . . . . . . . . . . . 37
2.3.7.1 S HARED P REFERENCES . . . . . . . . . . . . . . . . . . . 37
2.3.7.2 B ASE DE DATOS LOCAL . . . . . . . . . . . . . . . . . . . 37
2.3.8 LBS (L OCATION B ASED S ERVICES ) . . . . . . . . . . . . . . . . . 38

3 Implementación de la Centralita 39
3.1 O BJETIVO . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . 39
3.2 E NTORNO DE SIMULACIÓN . . . . . . . . . . . .
. . . . . . . . . . . . . . 39
3.3 I NSTALACIÓN DEL ENTORNO . . . . . . . . . . .
. . . . . . . . . . . . . . 40
3.3.1 TARJETA D IGIUM TDM808 . . . . . . . .
. . . . . . . . . . . . . . 41
3.3.2 C ANCELADOR DE ECO O SLEC . . . . . . .
. . . . . . . . . . . . . . 41
3.3.3 G ESTOR DE CORREO . . . . . . . . . . .
. . . . . . . . . . . . . . 42
3.3.4 R ECONOCIMIENTO DE VOZ . . . . . . . .
. . . . . . . . . . . . . . 42
3.3.5 S OFTPHONE . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . 42
3.4 C ONFIGURACIONES . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . 43
3.4.1 TARJETA D IGIUM Y C ANCELADOR DE ECO O SLEC . . . . . . . . . . 43
3.4.2 C ANALES DAHDI . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.4.3 A STERISK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.4.3.1 U SUARIOS . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.4.3.2 D IALPLAN . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.4.3.3 M ÚSICA EN ESPERA . . . . . . . . . . . . . . . . . . . . . 50
3.4.3.4 B UZÓN DE VOZ . . . . . . . . . . . . . . . . . . . . . . . 50
3.4.3.5 F OLLOW M E . . . . . . . . . . . . . . . . . . . . . . . . 50
3.4.3.6 S ALA DE C ONFERENCIAS . . . . . . . . . . . . . . . . . . 51
3.4.3.7 C OLAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

2
3.4.3.8 T RANSFERENCIA Y PARKING DE LLAMADAS . . . . . . . . 52
3.4.4 C ENTRALITA PBX . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
3.4.4.1 I NTEGRACIÓN DEL RECONOCIMIENTO DE VOZ . . . . . . . 55
3.4.5 E JECUCIÓN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

4 Implementación de los Softphones 65


4.1 O BJETIVO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
4.2 I NSTALACIÓN Y CONFIGURACIÓN DEL ENTORNO DE TRABAJO . . . . . . . . 65
4.2.1 D ESARROLLO DE APLICACIONES A NDROID . . . . . . . . . . . . . . 66
4.2.2 B ASE DE DATOS REMOTA . . . . . . . . . . . . . . . . . . . . . . . 67
4.2.2.1 E STRUCTURA DE LA BASE DE DATOS . . . . . . . . . . . . 67
4.2.2.2 S CRIPTS PHP . . . . . . . . . . . . . . . . . . . . . . . . 68
4.2.3 E XTENSIONES DE EMERGENCIA EN A STERISK . . . . . . . . . . . . 70
4.3 D ESARROLLO DE LAS APLICACIONES . . . . . . . . . . . . . . . . . . . . . 70
4.3.1 S OFTPHONE BÁSICO . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.3.1.1 I NTEGRACIÓN DE LA V O IP EN LA APLICACIÓN . . . . . . . 75
4.3.1.1.1 S ERVICE SIP . . . . . . . . . . . . . . . . . . . . 76
4.3.1.1.2 C ALL R ECEIVER SIP . . . . . . . . . . . . . . . . 83
4.3.1.1.3 S ERVICE B INDER . . . . . . . . . . . . . . . . . 84
4.3.2 S OFTPHONE PARA RESIDENTES . . . . . . . . . . . . . . . . . . . . 84
4.3.2.1 A LERTAS DE BATERÍA . . . . . . . . . . . . . . . . . . . . 86
4.3.2.2 A LERTAS DE POSICIONAMIENTO . . . . . . . . . . . . . . 86
4.3.2.2.1 A LERTS S ERVICE . . . . . . . . . . . . . . . . . 88
4.3.3 S OFTPHONE PARA LA RECEPCIÓN DEL CENTRO . . . . . . . . . . . . 92
4.3.3.1 C OMPROBACIÓN DE ALERTAS DE BATERÍA . . . . . . . . . 93
4.3.3.2 C OMPROBACIÓN DE ALERTAS DE POSICIONAMIENTO . . . 95
4.3.3.2.1 S HOW L OCATION M AP . . . . . . . . . . . . . . . 97

5 Conclusiones y líneas de futuro 107


5.1 VALORACIÓN PERSONAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

6 Bibliografía 111

A Instalaciones y configuraciones relacionadas con Asterisk 113


A.1 Instalaciones relacionadas con Asterisk . . . . . . . . . . . . . . . . . . . 113
A.1.1 P RERREQUISITOS . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
A.1.2 DAHDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
A.1.3 LIB PRI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
A.1.4 A STERISK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
A.1.5 C ANCELADOR DE ECO O SLEC . . . . . . . . . . . . . . . . . . . . . 116
A.1.6 R ECONOCIMIENTO DE VOZ . . . . . . . . . . . . . . . . . . . . . . 116
A.2 Archivos de configuración Asterisk . . . . . . . . . . . . . . . . . . . . . 117

3
A.2.1 C ANALES DAHDI . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
A.2.2 U SUARIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
A.2.3 D IALPLAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
A.2.4 M ÚSICA EN ESPERA . . . . . . . . . . . . . . . . . . . . . . . . . . 125
A.2.5 B UZÓN DE VOZ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
A.2.5.1 G ESTOR DE CORREO . . . . . . . . . . . . . . . . . . . . 126
A.2.6 F OLLOW M E . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
A.2.7 S ALA DE C ONFERENCIAS . . . . . . . . . . . . . . . . . . . . . . . 127
A.2.8 C OLAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
A.2.9 T RANSFERENCIA Y PARKING DE LLAMADAS . . . . . . . . . . . . . . 127

B Instalaciones y configuraciones relacionadas con las aplicaciones Android 129


B.1 I NSTALACIÓN ENTORNO DE DESARROLLO PARA A NDROID . . . . . . . . . . 129
B.2 B ASE DE DATOS REMOTA . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
B.2.1 I NSTALACIÓN Y CONFIGURACIÓN . . . . . . . . . . . . . . . . . . . 135
B.2.2 S CRIPTS PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
B.2.2.1 S OFTPHONE RESIDENTES . . . . . . . . . . . . . . . . . . 141
B.2.2.2 S OFTPHONE RECEPCIÓN . . . . . . . . . . . . . . . . . . 144
B.3 E XTENSIONES DE EMERGENCIA A STERISK . . . . . . . . . . . . . . . . . . 147

4
LISTA DE FIGURAS

1.1 Plataforma de VoIP implementada para la residencia. . . . . . . . . . . . 11

2.1 Principales componentes de una red VoIP. . . . . . . . . . . . . . . . . . 15


2.2 Trapezoide SIP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.3 Tramas SIP y RTP de una llamada telefónica de VoIP. . . . . . . . . . . . 19
2.4 Arquitectura modular de Asterisk. . . . . . . . . . . . . . . . . . . . . . . 23
2.5 Esquema de la arquitectura del sistema Android. . . . . . . . . . . . . . 29
2.6 Ciclo de vida de una actividad. . . . . . . . . . . . . . . . . . . . . . . . 32
2.7 Ejemplo de un Linear Layout con las vistas más comunes y los dos tipos
de menús existentes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

3.1 Esquema del entorno de simulación. . . . . . . . . . . . . . . . . . . . . 40


3.2 Diagrama de flujo de la centralita (Inicio). . . . . . . . . . . . . . . . . . 58
3.3 Diagrama de flujo de la extensión 0 de la centralita (Recepción). . . . . 59
3.4 Diagrama de flujo de la extensión 1 de la centralita (Trabajadora Social). 60
3.5 Diagrama de flujo de la extensión 2 de la centralita (Enfermería). . . . . 61
3.6 Diagrama de flujo de la extensión 3 de la centralita (Dirección). . . . . . 62
3.7 Diagrama de flujo de la extensión 4 de la centralita (Psicóloga). . . . . . 63
3.8 Diagrama de flujo de la extensión 6 de la centralita (Menú privado). . . 64

4.1 Tablas de la base de datos ubicada en el servidor. . . . . . . . . . . . . . 68


4.2 Menú tab de la aplicación con: a) Pantalla principal de la aplicación. b)
Lista de contactos. c) Registro de llamadas. . . . . . . . . . . . . . . . . 72
4.3 a) Menú principal de la aplicación para los residentes. b) Diálogo que
aparece al cerrar las aplicaciones. . . . . . . . . . . . . . . . . . . . . . . 73
4.4 a) Listado de cuentas con menú abierto. b) Menú context de una cuenta
(opciones de la cuenta). . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

5
LISTA DE FIGURAS

4.5 Pantalla mostrada durante las llamadas en las aplicaciones. . . . . . . . 75


4.6 a) Notificación que aparece cuando no hay ninguna cuenta activa. b)
Notificación permanente que aparece cuando hay una cuenta logada en
el servidor SIP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
4.7 a) Notificación que aparece al no poder registrar la cuenta especificada
en el servidor SIP. b) Notificación que indica la existencia de llamadas
perdidas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
4.8 Listado de cuentas con acceso protegido por contraseña. . . . . . . . . . 85
4.9 Menú principal del softphone para la recepción del centro. . . . . . . . . 93
4.10 a) Notificación de alertas de batería. b) Listado de alertas de batería. . . 95
4.11 a) Mapa de alertas con 2 usuarios (mostrando la información de uno de
ellos). b) Mapa con 2 usuarios fuera de la zona permitida (rojos) y un
usuario en seguimiento (verde). . . . . . . . . . . . . . . . . . . . . . . . 98
4.12 Diálogo mostrado cuando no hay alertas de posicionamiento en el mapa. 100
4.13 a) Menú del mapa de alertas. b) Diálogo para iniciar un seguimiento. . . 104

B.1 Pantalla inicial del Android Manager. . . . . . . . . . . . . . . . . . . . . 131


B.2 Pantalla del Android Manager con todos los paquetes disponibles para
instalar. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
B.3 Pantalla del Android Manager para instalar licencias. . . . . . . . . . . . 132
B.4 Ventana para instalar el plugin ADT en Eclipse. . . . . . . . . . . . . . . 132
B.5 Pantalla con los paquetes necesarios para instalar el plugin ADT. . . . . . 133
B.6 Pantalla para aceptar las licencias de los paquetes del plugin ADT. . . . . 134
B.7 Pantalla de Eclipse con las opciones del Android SDK instaladas. . . . . . 135
B.8 Definición de la ubicación de la base de datos con usuario y contraseña. 136
B.9 Pantalla inicial del cliente gráfico MySQL Navigator. . . . . . . . . . . . . 137
B.10 Pantalla de creación de la tabla de alertas MyAlerts. . . . . . . . . . . . . 138
B.11 Pantalla de creación de la tabla de coordenadas MyCoordinates. . . . . . 139
B.12 Base de datos Alcatraz con sus dos tablas: MyAlerts y MyCoordinates. . . 140

6
LISTA DE TABLAS

2.1 Códecs de audio y protocolos soportados en Asterisk. . . . . . . . . . . . 25


2.2 Versiones de Android. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

3.1 Listado de usuarios SIP. . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

4.1 Clases e interfaz incluidos en la API SIP de Android. . . . . . . . . . . . 76

7
LISTA DE TABLAS

8
1
Introducción

N LOS ÚLTIMOS AÑOS , la utilización de la VoIP ha tenido un gran crecimiento en el


E ámbito de las telecomunicaciones, pasando de ser algo lejano a ser una tecnología
utilizada a diario. Sus múltiples características y ventajas son las que nos inspiraron
para realizar este proyecto, aunque los objetivos del mismo fueron cambiando y
ampliándose a medida que avanzaba el proyecto.

La idea principal era realizar un proyecto basado en VoIP, cosa que se ha mantenido
a lo largo de todo el desarrollo. En principio, se empezó con el estudio de Asterisk
con la idea de desarrollar una centralita telefónica, por ejemplo, para una empresa y
utilizarla como punto de partida. Al estudiar las posibilidades de Asterisk se decidió
realizar un cambio de dirección y crear algo que pudiera aprovechar el trabajo ya
realizado. Fue entonces cuando se decidió implementar una aplicación Android que
utilizara la VoIP, como un softphone. Una vez terminada la aplicación, se pensó en
conseguir un valor añadido para el mismo, que acabara de redondear el proyecto y
que unificara la idea de la centralita con el softphone realizado.

Como últimamente casi todas las aplicaciones Android utilizan de una forma u otra
la ubicación del usuario, se decidió que el valor añadido de las aplicaciones estaría
relacionado con el sensor GPS del smartphone. Para ello se enfocó el proyecto a un
hipotético caso real: una residencia de ancianos. Algunas residencias y centros de
día permiten a sus residentes salir a pasear o a comprar por sus alrededores. Como
algunos de ellos pueden perderse o desorientarse una vez en el exterior, se desea
mantener su ubicación controlada cuando se alejan demasiado de la residencia.

Así es como se consiguió el proyecto final: una plataforma de VoIP diseñada espe-
cialmente para su utilización en una residencia de ancianos. La centralita realizada
en Asterisk se convirtió en la centralita de la residencia de ancianos. Por último, a
partir del softphone inicial, se crearon dos softphones con distintas características: uno

9
CAPÍTULO 1. I NTRODUCCIÓN

diseñado para los residentes del centro y el otro diseñado específicamente para los
trabajadores, concretamente para el personal de la recepción.

Los objetivos finales son:

* Implantación de Asterisk.

* Centralita Asterisk con reconocimiento de voz para utilizar en la residencia de


ancianos. Se le añaden servicios de valor añadido como son: buzón de voz,
música en espera, etc.

* Softphone para los residentes: softphone con un sistema de alertas de posi-


cionamiento y de batería baja.

* Softphone para la recepción del centro: softphone con un sistema que permita
gestionar las alertas generadas por los residentes.

* Implantación de una base de datos LAMP para los sistemas de alertas.

Hoy en día, el sector de las telecomunicaciones es un mundo de evolución rápida


y constante. Nuevas ideas y tecnologías salen al mercado en intervalos de tiempo
muy cortos. El desarrollo open source es mucho más capaz de adaptarse a los rápidos
cambios tecnológicos, lo que le proporciona una enorme ventaja competitiva. Por ese
motivo, todo el proyecto está basado en tecnología open source.

1.1 P LATAFORMA DE V O IP

La plataforma de VoIP implementada para la residencia se puede ver en la figura 1.1


y consta de:

* Asterisk: se utiliza como servidor de VoIP (protocolo SIP) y servidor de media. En


Asterisk se implementa la centralita de telefonía que se utilizará para las llamadas
entrantes a la residencia.

* LAMP: servidor y base de datos. Esta base de datos se utiliza para guardar y
consultar información sobre los residentes del centro (localización y estado de la
batería del teléfono).

* Smartphones con sensor GPS: donde se instalan las aplicaciones desarrolladas


en Android.

10
1.2. C ASOS DE USO

FIGURA 1.1: Plataforma de VoIP implementada para la residencia.

La comunicación entre Asterisk y las aplicaciones instaladas en los smartphones se


realiza mediante el protocolo SIP. Las aplicaciones y la base de datos se comunican
mediante HTML. Las aplicaciones realizan peticiones HTML contra Apache, que ejecuta
los scripts PHP correspondientes, accediendo a la base de datos MySQL y devolviendo
los resultados obtenidos en formato JSON. No existe comunicación entre Asterisk y la
base de datos.

1.2 C ASOS DE USO

Residente sale de la zona permitida


Cuando un residente se aleja demasiado de la residencia, la aplicación del residente
realiza de forma automática una llamada SIP (perdida) a una extensión especial de
Asterisk. Entonces, Asterisk pone en contacto, mediante otra llamada SIP, al residente
con el softphone de recepción para informar del evento. A la vez, la aplicación del
residente empieza a enviar las coordenadas GPS del dispositivo a la base de datos.
Cuando se cuelga la llamada, el softphone de recepción muestra un mapa de los
alrededores de la residencia con la ubicación de los residentes que se encuentran fuera
de la zona permitida. La información mostrada en el mapa se obtiene de la base
de datos y se va actualizando de forma periódica. En caso de que el softphone de

11
CAPÍTULO 1. I NTRODUCCIÓN

recepción esté ocupado y no se pueda atender la llamada, se muestra igualmente el


mapa con las coordenadas.

Residente entra en la zona permitida


Cuando el residente vuelve a acercarse a la residencia, la aplicación del residente
realiza de forma automática una llamada SIP (perdida) a una extensión especial de
Asterisk. Entonces, Asterisk pone en contacto, mediante otra llamada, al residente
con el softphone de recepción para informar del evento. A la vez, la aplicación del
residente deja de enviar sus coordenadas GPS.
Cuando se cuelga la llamada, la aplicación de recepción muestra un mapa de los
alrededores de la residencia. Si quedan residentes fuera de la zona permitida, se
siguen mostrando sus coordenadas en el mapa. Si era el único residente fuera de la
zona, aparece un diálogo en la pantalla informando de que no hay ningún residente
que localizar.

Recepción pide un seguimiento


Desde la aplicación de recepción se puede solicitar la ubicación de un residente que
no esté fuera de la zona permitida. Al hacer la petición, la aplicación de recepción
lanza una llamada a una extensión especial de Asterisk, especificando la identificación
del residente que se quiere seguir. Entonces, Asterisk realiza una llamada perdida al
softphone del residente, que sirve para que éste empiece a enviar sus coordenadas
GPS a la base de datos. En el mapa de la aplicación de recepción se muestran tanto la
ubicación de este residente como las de los que están fuera de la zona permitida.
Cuando se desea finalizar el seguimiento, la aplicación de recepción lanza una
llamada a otra extensión especial de Asterisk indicando, igual que antes, el identi-
ficador del residente. Entonces, Asterisk realiza una llamada perdida al softphone
del residente, que sirve para que éste deje de enviar sus coordenadas a la base de datos.

Alerta de batería baja


Cuando el smartphone del residente detecta que el nivel de batería está por debajo del
15%, la aplicación registra este hecho en la base de datos. La aplicación de recepción
comprueba, de forma periódica, la información sobre las alertas de batería en la base
de datos. Si hay alguna, muestra un listado de los residentes que se encuentran en esta
situación.

12
Conceptos Generales
2
2.1 V O IP

2.1.1 ¿Q UÉ ES LA V O IP?

VoIP (Voice Over Internet Protocol) se refiere a los protocolos de comunicación,


tecnologías, metodologías y técnicas de transmisión involucradas en la transmisión de
comunicaciones de voz y sesiones multimedia sobre redes IP.

La red de telefonía tradicional PSTN1 se basa en la conmutación de circuitos para


establecer las comunicaciones y transportar la señal de voz y la señalización de un
extremo al otro. Las redes IP, en cambio, están basadas en la conmutación de paquetes.
Por tanto, para poder transportar la señal de voz sobre este tipo de redes, ésta debe ser
digitaliza, codificada y empaquetada.

La utilización de la VoIP aporta múltiples ventajas, entre las cuales se destacan:


* Reducción significativa de costes de gestión, administración y mantenimiento al
aprovechar la red IP. Llamadas gratuitas entre miembros de redes VoIP puras (sin
enrutar llamadas a través de la PSTN).
* Los datos y la voz se integran en una misma infraestructura. No hay necesidad de
utilizar redes diferentes para su transmisión.
* Posibilidad de transmitir más de una llamada sobre la misma línea telefónica.
* Ofrece servicios de valor añadido que suelen conllevar un cargo extra sobre la
PSTN o que incluso no se encuentran disponibles en algunos países, como son la
identificación de llamada, el voicemail, las conferencias, etc.
1
Public Switched Telephone Network

13
CAPÍTULO 2. C ONCEPTOS G ENERALES

* Proporciona total portabilidad. Mientras el usuario disponga de un teléfono que


soporte VoIP conectado a la red, puede estar siempre localizable, sin importar su
ubicación.
* Permite la integración con otros servicios disponibles en Internet, incluyendo
videoconferencias, mensajería instantánea, etc.

Por otra parte, uno de los principales inconvenientes al utilizar conmutación de


paquetes para VoIP es la dificultad de ofrecer QoS. La transmisión de voz tiene que ser
en tiempo real, por lo que es necesario que los paquetes lleguen de forma ordenada,
sin pérdidas y garantizando una mínima tasa de transmisión (los retrasos superiores a
150 milisegundos afectan a la conversación). Existen varios mecanismos que ayudan
a lograr estos objetivos, entre los que se encuentran: la supresión de silencios para
aprovechar mejor el ancho de banda, la compresión de cabeceras aplicando los
estándares RTP/RTCP y la priorización de los paquetes que requieran menor latencia.

2.1.2 A RQUITECTURA

2.1.2.1 C OMPONENTES FUNDAMENTALES DE UNA RED V O IP

La figura 2.1 muestra los elementos fundamentales de una red VoIP.


* Terminales: teléfonos IP que pueden ser software o hardware.
– Hardware: terminales físicos con soporte VoIP nativo que pueden conectarse
directamente a una red IP.
– Software: aplicaciones que simulan un teléfono con soporte VoIP. Pueden
correr sobre cualquier dispositivo que disponga de conexión a la red (orde-
nadores, móviles, etc.).
* Servidor: provee el manejo y funciones administrativas para soportar el en-
rutamiento de llamadas a través de la red. Este elemento recibe distintos nombres
en función del protocolo de señalización que se utilice. En un sistema basado en
H.323, el servidor recibe el nombre de Gatekeeper. En cambio, en un sistema SIP,
el servidor se conoce simplemente por Servidor SIP.
* Gateway: dispositivo que hace de enlace con la telefonía fija tradicional. Actúa de
forma transparente al usuario.
* Red IP: provee conectividad entre todos los terminales. La red IP puede ser una
red IP privada, una Intranet o Internet.

14
2.1. V O IP

FIGURA 2.1: Principales componentes de una red VoIP.

2.1.2.2 T RANSMISIÓN DE LA V O IP POR LA RED

Los paquetes de VoIP se transmiten sobre la red IP utilizando el modelo TCP/IP con
algunas diferencias. Estas diferencias residen en los protocolos utilizados en cada capa
por los paquetes de datos y los paquetes de VoIP. En algunas capas se utilizan los
mismos para ambos; en otras, se utilizan protocolos propios para cada tipo.

A continuación se detallan las funciones de las cinco capas del modelo TCP/IP con
los protocolos utilizados en los paquetes de VoIP:
* Aplicación: Asegura la calidad y entregabilidad de los paquetes VoIP. Se utilizan
los siguientes protocolos:
– NTP: Network Time Protocol. Permite sincronización, lo que nos asegura que
las señales son transmitidas y recibidas en el margen de tiempo adecuado
para asegurar calidad.
– RTP: Real-time Transport Protocol. Proporciona funciones de transporte de
red extremo-a-extremo para las señales de voz digitales encapsuladas en los
paquetes VoIP.
– RTCP: Real-time Transport Control Protocol. Monitoriza la entrega de las
señales de voz y proporciona funciones mínimas de control para asegurar la
entrega de los paquetes.
* Transporte: El protocolo UDP2 transporta los paquetes desde el origen al destino.
2
User Data Protocol

15
CAPÍTULO 2. C ONCEPTOS G ENERALES

Aunque este protocolo no garantiza la entrega de los paquetes en destino, se


utiliza porque es más rápido que TCP y en aplicaciones en tiempo real, como es
la voz, se prioriza la velocidad por encima de la fiabilidad.

* Red: Se añade la dirección IP al paquete. Esta dirección es la que utilizan los


dispositivos de enrutamiento para direccionar los paquetes durante la llamada y
es única y propia de cada dispositivo (PC o teléfono IP).

* Interfaz: Se añade la dirección física MAC3 al paquete. Esta dirección se obtiene


de la tarjeta NIC4 del propio dispositivo.

* Física: Se convierten los paquetes en señales eléctricas o electro-ópticas para


que se puedan transportar por la red.

2.1.3 C ÓDECS DE AUDIO

Los códecs5 son los medios por los cuales se puede convertir la señal de voz analógica a
digital para poder transportarla por la red. Se pueden definir como modelos matemáti-
cos usados para codificar y comprimir digitalmente información de audio analógica.
La mayoría tienen en cuenta la capacidad del cerebro humano de interpretar la
información recibida a pesar de que esté incompleta. Los algoritmos de compresión de
voz se aprovechan de nuestra tendencia a interpretar lo que creemos que debemos oír
en vez de lo que realmente oímos. El propósito de los algoritmos de codificación es
encontrar un equilibrio entre eficiencia y calidad.

En VoIP se pueden utilizar una gran variedad de códecs de audio. La elección para
cada caso varía en función de los requerimientos de calidad de sonido, ancho de banda
necesario y carga computacional. A continuación se enumeran y describen algunos de
los más utilizados.

G.711 Códec fundamental de la PSTN estandarizado por la ITU en 1972. Tiene una
frecuencia de muestreo de 8 kHz y utiliza la modulación PCM6 . Existen dos
métodos de compansión7 : µ − law en América del Norte y Japón y a − law en
el resto del mundo. La principal diferencia radica en el número de muestras
3
Medium Access Control
4
Network Interface Card
5
Abreviatura de codificador – decodificador, aunque actualmente también se utiliza como abre-
viatura de compresor-decompresor.
6
Pulse Code Modulation.
7
Método aplicable a señales para mejorar la transmisión de las mismas en canales limitados. Está
formado por dos procesos: compresión y expansión.

16
2.1. V O IP

por palabra (de 8 bits) que se utilizan: 14 muestras (µ − law) y 13 mues-


tras a − law. Ambos tienen un bit rate de 64 kbps. G.711 es el códec base del
que derivan todos los demás y es el que conlleva una menor carga computacional.

G.729A Este códec presenta una calidad de sonido muy buena teniendo en cuenta
el poco ancho de banda que utiliza, sólo 8 kbps. Para ello utiliza el método de
compresión de habla CS-ACELP8 . Debido a patentes, este códec no se puede usar
sin pagar una licencia. Además, la carga computacional de este algoritmo es
bastante elevada.

GSM9 Este códec, que opera a 13 kbps, es el preferido de Asterisk. No requiere licencia
y ofrece un gran rendimiento en relación a los requerimientos de CPU. La calidad
de sonido se considera ligeramente peor que la obtenida con G.729A.

2.1.4 P ROTOCOLOS

Los protocolos propios de las redes IP no fueron diseñados para soportar streaming
en tiempo real. Los terminales de estas redes suelen esperar la recepción de paquetes
perdidos, piden retransmisiones o simplemente los ignoran. Obviamente, la forma en
la que hablamos es totalmente incompatible con la manera en que los protocolos de
Internet transportan los datos: no se puede aceptar la pérdida de letras o palabras o
los retrasos apreciables entre emisor y receptor.

El mecanismo para llevar a cabo una conexión de VoIP consta de una serie de
intercambios de señalización entre los terminales (y gateways intermedios) que
culminan en dos flujos de media continuos que transportan la conversación (uno para
cada dirección). Manejar esto es el objetivo de los protocolos de VoIP. A continuación
se definen los más relevantes y utilizados.

2.1.4.1 SIP10

Protocolo desarrollado por el IETF11 para establecer, modificar y terminar sesiones mul-
timedia. Estas sesiones incluyen llamadas de voz y vídeo, conferencias multimedia, etc.

8
Conjugate-Structure Algebraic-Code-Excited Linear Prediction. Método de compresión del habla
que consiste en enviar códigos correspondientes a los sonidos en vez del sonido muestreado real.
9
Global System for Mobile Communications
10
Session Initiation Protocol
11
Internet Engineering Task Force

17
CAPÍTULO 2. C ONCEPTOS G ENERALES

FIGURA 2.2: Trapezoide SIP.

SIP es un protocolo de señalización de la capa de aplicaciones diseñado espe-


cialmente para ser independiente de la capa de transporte; puede funcionar con los
protocolos UDP y TCP indistintamente. Está basado en texto, con una sintaxis similar
a la de otras familias de protocolos como HTTP y SMTP. La premisa de SIP es que cada
terminal de una conexión es un par; se utiliza una estructura cliente/servidor basada
en un modelo de petición/respuesta para autenticar a sus usuarios.

Este protocolo utiliza el puerto 5060 para la señalización. No transporta medios


(voz y/o vídeo) entre extremos, para ello se utiliza el protocolo RTP. Se necesitan dos
puertos RTP para cada conexión (normalmente entre el 10.000 y el 20.000). Una
tipología corriente para ilustrar la utilización de estos dos protocolos, conocida como
Trapezoide SIP, se puede observar en la figura 2.2. Cuando se desea realizar una
llamada de A a B, el establecimiento de la llamada y toda su señalización se realiza a
través de servidores proxy mediante el protocolo SIP. En cuanto se inicia la llamada,
los terminales se comunican directamente entre ellos (si es posible), utilizando el
protocolo RTP, para que los datos no consuman recursos de los proxys. Debido a esta
separación, SIP da problemas en infraestructuras de red con NAT12 y se suele necesitar
un servidor STUN para solucionarlos.

Las ventajas de este protocolo residen en su gran nivel de aceptación y su arquitec-


tura flexible. Actualmente, SIP ha reemplazado a H.323 como protocolo de elección
para la negociación del transporte VoIP.

2.1.4.1.1 E JEMPLO DE UNA COMUNICACIÓN SIP/RTP


Para facilitar la comprensión del uso de los protocolos SIP y RTP en una comuni-
cación, se analiza a continuación una llamada telefónica entre dos clientes SIP. En este
12
Network Address Translation. Proceso consistente en modificar la dirección IP de la información en
las cabeceras IP de los paquetes mientras están en transito a través de un dispositivo de enrutamiento
de tráfico.

18
2.1. V O IP

FIGURA 2.3: Tramas SIP y RTP de una llamada telefónica de VoIP.

ejemplo hay tres agentes a tener en cuenta: los clientes 501 (IP 192.168.1.33) y 202
(IP 192.168.1.34), siendo el primero el que inicia y finaliza la llamada; y el servidor de
VoIP (IP 192.168.1.38). En la figura 2.3 se muestran las tramas más relevantes de esta
llamada.

* Tramas 1-4: se realiza la negociación inicial entre el llamante y el servidor. El


cliente 501 realiza una petición al servidor (INVITE) para iniciar una comuni-
cación con el cliente 202. En esta petición se especifica también la información
de la sesión: tipo de medio que se transportará (audio), puerto (4002) y proto-
colo (RTP), entre otros. El servidor confirma al cliente 501 la posibilidad de la
conexión (OK) especificando a su vez la información de la sesión: audio, puerto
11706 y protocolo RTP.

* Tramas 5-7: se realiza la negociación entre el servidor y el llamado. El servidor


indica al cliente 202 que el cliente 501 quiere establecer una comunicación con
él mediante otro INVITE con información de sesión: audio, puerto 14046 y pro-
tocolo RTP. El cliente 202 recoge esta petición y cuando está preparado lo indica
al servidor comunicando su estado (Ringing). En este momento, el teléfono del
cliente 202 empieza a sonar.

* Tramas 8-9: El cliente 202 descuelga el teléfono. Esto se indica al servidor me-
diante un paquete (OK) con la información de la sesión: audio, puerto 4006 y
protocolo RTP. A partir de este momento, se inicia la conversación.

* Tramas 10-17: Estas tramas representan el intercambio de datos (audio) entre los
dos terminales. Como se ha indicado antes, el protocolo utilizado para ello es el
RTP.

19
CAPÍTULO 2. C ONCEPTOS G ENERALES

* Tramas 18-21: El cliente 501 cuelga el teléfono, enviando al servidor una petición
(BYE) para que comunique al cliente 202 que se va a finalizar la comunicación.
El servidor confirma la petición al cliente 501 e informa al otro cliente de la
finalización de la comunicación, enviando otra petición (BYE) especificando el
motivo de la finalización (normal clearing).

2.1.4.2 H.323

Protocolo desarrollado por la ITU13 en 1996 como medio para transmitir comunica-
ciones de voz, vídeo, datos y fax sobre redes IP manteniendo conectividad con la PSTN.
Originalmente, fue diseñado para proporcionar un mecanismo de transporte IP para
videoconferencias y desde entonces ha evolucionado para cubrir todas las necesidades
de la VoIP. La señalización de llamadas está basada en el protocolo Q.391 de la ITU-T
y es adecuada para transmitir llamadas a través de redes utilizando una mezcla de IP,
PSTN y ISDN.

H.323 es un protocolo relativamente seguro que no necesita elementos de seguri-


dad adicionales a los requeridos por cualquier conexión vía Internet. Igual que SIP,
utiliza el protocolo RTP para transportar las comunicaciones de medios y por tanto,
presenta los mismos problemas en topologías de red con NAT. Uno de los factores de
su poca popularidad reside en su complejidad.

2.1.4.3 IAX14

Protocolo abierto desarrollado por Digium con el propósito de establecer comunica-


ciones entre servidores Asterisk. Pese a ello, IAX no está limitado sólo a Asterisk:
cualquiera puede usarlo y es soportado por varios proyectos de telecomunicaciones
open source.

Su objetivo principal es minimizar el ancho de banda usado en las transmisiones de


datos, voz y vídeo sobre IP y proporcionar soporte nativo para ser transparente a NAT.
Con ese fin, IAX multiplexa la señalización de canal y el flujo de datos sobre un único
stream UDP entre los extremos, utilizando el puerto 4569.

El protocolo IAX original ha quedado obsoleto en favor de su nueva versión, IAX2.


Este permite la utilización de un gran número de códecs de audio y puede transportar
cualquier tipo de datos. Además, está considerado uno de los protocolos más sencillos
13
International Telecommunication Union
14
Inter-Asterisk eXchange

20
2.2. A STERISK

para implementar en redes seguras.

2.2 A STERISK

2.2.1 ¿Q UÉ ES A STERISK ?

Asterisk es un software open source que implementa las funciones de una central
telefónica PBX15 . Este proyecto de comunicaciones fue creado en 1999 por Mark
Spencer, miembro fundador de la compañía Digium, principal desarrolladora de
Asterisk. Está publicado como open source bajo la licencia GNU GPL16 . Aunque
originalmente fue diseñado para funcionar en Linux, también existen versiones para
otros sistemas operativos como BSD, Mac OS X, Solaris y Windows.

El proyecto Asterisk, en combinación con el proyecto de telefonía Zapata17 , ha


evolucionado con los años, pasando de simplemente conectar llamadas de teléfono
a convertirse en una plataforma que puede manejar voz, vídeo y texto a través de
docenas de interfaces tanto físicos como virtuales.

El poder de Asterisk reside en su naturaleza customizable. Es muy flexible, dando al


usuario la libertad de decidir lo que quiere implementar en función de sus necesidades.
Separa las funcionalidades y características de varias PBXs en componentes que pueden
interconectarse de manera que cada usuario puede customizar su solución como mejor
le convenga. Esto diferencia a Asterisk de otras soluciones corporativas cerradas que
aportan una solución única, dejando muchas veces funcionalidades deseadas fuera.

Asterisk cuenta con toda una comunidad, liderada por Digium, que lo desarrolla y
soporta. Esta comunidad ha sido valorada como factor clave para en el crecimiento de
la VoIP. Entre sus miembros se encuentran profesionales del ámbito de las telecomuni-
caciones, de redes y de tecnologías de la información.

15
Private Branch eXchange.
16
GNU General Public License.
17
Zapata Telephony Project: proyecto concebido por Jim Dixon, basado en la creación de sistemas
telefónicos más económicos utilizando tarjetas PCI con la electrónica básica para comunicarse con un
circuito de telefonía. En vez de tener componentes caros en la tarjeta, el procesado de la señal digital
(DSP) se maneja en la CPU, por software. Fue la base para la creación del interfaz DAHDI, que se
explicará más adelante.

21
CAPÍTULO 2. C ONCEPTOS G ENERALES

2.2.2 C ONCEPTOS BÁSICOS

Canales
Los canales son las conexiones que realizan una llamada entrante o saliente a la PBX
Asterisk. Cada llamada se realiza o recibe mediante un canal distinto. Asterisk no
hace ninguna distinción entre ellos. Entre los canales soportados más importantes se
encuentran: SIP, IAX2, H323, MGCP, Console y DAHDI.

Dialplan
El dialplan es el corazón de Asterisk. Todos los canales que llegan al sistema pasan
por el dialplan, que contiene los scripts de flujo de llamadas que determinan el
manejo de las llamadas entrantes y salientes. Está dividido en secciones llamadas
contextos. Dentro de estos contextos encontramos las extensiones y la definición de
las actuaciones o pasos que debe realizar el sistema al recibir una llamada para cada
extensión.

El dialplan puede escribirse de tres formas distintas: utilizando la sintaxis


tradicional de Asterisk (editanto extensions.conf); usando AEL18 (modificando
extensions.ael); o utilizando LUA (editando extensions.lua).

Contextos
Un contexto es, básicamente, una colección de extensiones. Cuando se crean canales,
estos siempre deben ubicarse en un contexto. Esto implica que las llamadas originadas
desde ese canal se ubicarán en dicho contexto.
El objetivo más importante de los contextos es ofrecer seguridad, evitando que las
diferentes secciones del dialplan interactúen entre ellas. Los canales sólo podrán
realizar llamadas hacia las extensiones incluidas en su contexto o acceder a funcionali-
dades propias del mismo.

Existen dos contextos especiales: general (define configuraciones generales para


todos los contextos) y globals (contiene variables disponibles para todo el dialplan).

Extensiones
Al contrario que en los sistemas telefónicos convencionales, donde las extensiones
se asocian a terminales, interfaces, menús, etc., en Asterisk las extensiones se
asocian a un listado de instrucciones a ejecutar. Estas instrucciones pueden tanto
llamar a un número de teléfono como acceder al buzón de voz o cualquier otra función.

18
Asterisk Extension Logic

22
2.2. A STERISK

FIGURA 2.4: Arquitectura modular de Asterisk.

Cada paso o instrucción dentro de una extensión se compone de tres componentes:


nombre (o número) de la extensión; prioridad (cada extensión puede incluir varios
pasos, el numero de paso se llama prioridad); la aplicación (o instrucción) que se debe
ejecutar en cada paso. Por tanto, la forma de definir una instrucción en el dialplan es
la siguiente:
exten ⇒ name, priority, application().

2.2.3 A RQUITECTURA

Asterisk está formado por un conjunto de bloques o módulos que el usuario tiene
a su disposición para crear aplicaciones de comunicación. Por este motivo se hace
referencia a Asterisk con los términos tool-kit o plataforma de desarrollo.

Estos módulos son componentes que proporcionan una funcionalidad específica,


por ejemplo, un driver para un canal o un recurso que permite la conexión con una
tecnología externa. Estos pueden añadirse al sistema en función de las necesidades
del usuario/desarrollador. Los módulos que se quieran utilizar suelen definirse en el
momento de la instalación, aunque también pueden añadirse a posteriori, especificán-
dolos en el archivo de configuración adecuado.

En la figura 2.4 se representan los tipos de módulos que se pueden encontrar en


Asterisk. A continuación se incluye un listado con una breve descripción de cada uno
de ellos y algunos ejemplos.

* Applications: Aplicaciones del dialplan. Se utilizan en el fichero extensions.conf

23
CAPÍTULO 2. C ONCEPTOS G ENERALES

para definir las diversas acciones que se pueden aplicar a una llamada. Por ejem-
plo: marcar un número, transferir una llamada, acceder al buzón de voz, etc.

* Bridging modules: Realizan bridging de canales en la nueva Bridging API. Cada


uno proporciona funcionalidades diferentes, dependiendo de las necesidades del
canal.

* CDR modules (Call Detail Recording): Diseñados para facilitar tantos métodos
de guardar detalles de las llamadas como sea posible. Estos detalles pueden
guardarse en un archivo (por defecto), una base de datos, RADIUS o syslog.

* CEL modules (Channel Event Logging): Proporcionan control sobre los informes de
actividad de una llamada. El uso de estos módulos requiere una planificación del
dialplan más cuidadosa.

* Channel drivers: Necesarios para realizar llamadas. Cada driver es específico para
el protocolo o tipo de canal que soporta (SIP, IAX2, ISDN, DAHDI, etc.). Este
módulo actúa como un gateway con el núcleo de Asterisk. La lista de protocolos
soportados por Asterisk se puede ver en la tabla 2.1.

* Codec translators: Permiten la conversión de formatos de streams de audio entre


llamadas. Por ejemplo: convertir una llamada que proviene de una canal que
utiliza G.711 a otro que utiliza el códec G.729. El listado de códecs que Asterisk
soporta se puede ver en la tabla 2.1.

* Format interpreters: Realizan la misma función que los codec translators pero en
archivos, en vez de canales. Por ejemplo: cambiar el formato a una grabación de
un menú en GSM para que se pueda reproducir en un canal que no soporte este
formato.

* Dialplan functions: Complementan a las aplicaciones del dialplan. Proporcionan


mejoras para diversas funcionalidades de Asterisk, como el manejo de cadenas,
conectividad a bases de datos, acceso a la blacklist, etc.

* PBX modules: Módulos periféricos que proporcionan mecanismos de control y


configuración mejorados.

* Resource modules: Integran a Asterisk con recursos externos. Por ejemplo: permi-
tir la operatividad con bases de datos ODBC, la utilización de la música en espera,
grabar una llamada, etc.

* Addons modules: Módulos desarrollados por la comunidad con usos o derechos


de distribución diferentes de los del código principal. Figuran en un directorio
diferente y no se compilan e instalan por defecto.

24
2.2. A STERISK

TABLA 2.1: Códecs de audio y protocolos soportados en Asterisk.

G.711 (a-law y u-law), G.726, G.723.1, G.729A, GSM, iLBC, Speex,


Códecs de audio
ADPCM, Linear, MP3
Protocolos SIP, H.323, IAX e IAX2, MGCP, SCCP, UNISTIM

* Test modules: Se utilizan por el equipo de desarrollo de Asterisk para validar


código nuevo. Están cambiando y añadiéndose nuevos de forma constante.

2.2.3.1 S ERVICIOS Y FUNCIONALIDADES QUE OFRECE

Como se ha comentado anteriormente, Asterisk permite la implementación de los


mismos servicios que una PBX clásica, añadiendo nuevas funcionalidades. Se puede
colocar delante de una PBX convencional para que actúe como gateway, o detrás de
ella, para utilizarlo como servidor de aplicaciones periférico.

Algunos de los servicios que ofrece se listan a continuación:


* Manejo de llamadas entrantes y generación de llamadas salientes.

* Buzón de voz.

* Música en espera (desde archivos o desde emisoras de radio por Internet).

* Gestión de colas de llamadas entrantes.

* Transferencia y desvío de llamadas.

* Salas de conferencia con dos o más usuarios.

* Gestión de listas negras.

* Grabación y monitorización de llamadas en curso.

* Implementación de AA (Automatic Attendants) y IVR (Interactive Voice


Response).

* Manejo de llamadas externo en cualquier lenguaje de programación o scripting a


través de AGI (Asterisk Gateway Interface).

* Notificación de eventos e integración CTI vía AMI (Asterisk Manager Interface).

* Integración con bases de datos y servicios web.

25
CAPÍTULO 2. C ONCEPTOS G ENERALES

* Sintetización del habla (text-to-speech) en varios idiomas y dialectos utilizando


programas de terceros.

* Reconocimiento de voz en varios idiomas usando motores de reconocimiento de


voz de terceros.

2.2.4 I NTEGRACIÓN CON LA RED CONMUTADA DE TELEFONÍA

Asterisk es capaz de comunicarse con diferentes tecnologías. Normalmente, esta


comunicación se efectúa mediante conexiones de red. Sin embargo, conexiones con
tecnologías mas tradicionales, como la red conmutada de telefonía, requieren un
hardware específico.

2.2.4.1 TARJETAS ANALÓGICAS

Las tarjetas analógicas permiten conectar el servidor Asterisk con la red conmutada de
telefonía y/o con teléfonos analógicos. Existen dos tipos:

* FXO (Foreign eXchange Office): permiten interactuar con los portadores de la red
de telefonía.

* FXS (Foreign eXchange Station): permiten interactuar con teléfonos analógicos.

Las tarjetas analógicas diseñadas por Digium reciben el nombre de TDM y pueden
interactuar tanto con líneas externas como con teléfonos analógicos en función de
los módulos presentes en la tarjeta. Al inspeccionar visualmente estas tarjetas, se
diferencian los tipos de módulos por el color: FXO (rojos); FXS (verdes).

2.2.4.2 TARJETAS DIGITALES

Las tarjetas digitales permiten conectar Asterisk con una red digital RDSI. De esta clase
de tarjetas se encuentran dos tipos:

* Básicas (BRI): cada puerto BRI tiene dos canales de voz más uno de señalización,
permitiendo mantener dos conversaciones de forma simultánea.

* Primarios (PRI): cada primario tiene 30 canales de voz más uno de señalización,
permitiendo establecer unas 30 conversaciones simultáneas.

En un sistema Asterisk que requiera el uso de estas tarjetas para conectarse a la red
telefónica será necesaria la instalación de:

26
2.3. A NDROID

* DAHDI19 : Interfaz utilizado para controlar una gran cantidad de tarjetas analógi-
cas y/o digitales.

* LibPRI: librería que implementa señalización para ISDN-PRI e ISDN-BRI, nece-


saria para las tarjetas digitales.

2.3 A NDROID

2.3.1 ¿Q UÉ ES A NDROID ?

Android es un sistema operativo basado en Linux para dispositivos móviles como


smartphones y tablets. Está desarrollado por la Open Handset Alliance20 , encabezada
por Google. Inicialmente desarrollado por Android, Inc., fue comprado por Google en
2005 como parte de su estrategia para entrar en el mercado de los móviles.

Su código está publicado bajo la licencia de código abierto Apache, por lo que
cualquiera que quiera trabajar con Android puede descargarlo y editarlo. Esta cualidad
hace de Android un producto muy atractivo, ya que permite competir con el gran
despliegue y éxito que el iPhone de Apple está teniendo en el mercado.

Este SO está basado en un sistema intuitivo que permite a los usuarios navegar
por los distintos menús y aplicaciones del terminal de forma sencilla, sin necesidad de
recurrir a un manual de instrucciones que, a veces, es incluso inexistente.

A lo largo de su historia, Android ha pasado por diversas versiones. En la tabla 2.2


se recogen las principales.

Para la realización de este proyecto se ha escogido la versión 2.3.3 (Gingerbread) ya


que, al inicio del proyecto, es la que tenía una mayor distribución entre los terminales
Android.

2.3.1.1 A RQUITECTURA

El sistema operativo Android está dividido en cinco secciones distribuidas dentro de


cuatro capas principales representadas en la figura 2.5.
19
Digium Asterisk Hardware Device Interface
20
Open Handset Alliance: consorcio de 86 compañías en los sectores de hardware, software y teleco-
municaciones, dedicados a fomentar estándares abiertos para los dispositivos móviles.

27
CAPÍTULO 2. C ONCEPTOS G ENERALES

TABLA 2.2: Versiones de Android.

Versión Nombre Nivel API


1.5 Cupcake 3
1.6 Donut 4
2.1 Eclair 7
2.2 Froyo 8
2.3 - 2.3.2 Gingerbread 9
2.3.3 - 2.3.7 - 10
3.1 Honeycomb 12
3.2 - 13
4.0 - 4.0.2 Ice Cream Sandwich 14
4.0.3 - 4.0.4 - 15
4.1.x Jelly Bean 16
4.2.x - 17
4.3 - 18
4.4 KitKat 19

* Linux Kernel: kernel en el que se basa Android. Esta capa contiene todos los
drivers de bajo nivel para los componentes hardware de un terminal.

* Librerías: contiene todo el código que proporciona las características principales


del SO Android.

* Android Runtime: Contiene una conjunto de librerías que permiten a los desarro-
lladores escribir aplicaciones Android usando el lenguaje Java. También incluye
la máquina virtual Dalvik, que está diseñada y optimizada específicamente para
terminales Android.

* Application Framework: expone las diversas capacidades del SO Android a los


desarrolladores para que puedan utilizarlas en sus aplicaciones.

* Aplicaciones: todas las aplicaciones instaladas en un terminal: aplicaciones in-


cluidas en el propio terminal (teléfono, contactos, navegador, etc.), aplicaciones
descargadas e instaladas a través de Google Play (antiguo Android Market) y
aplicaciones desarrolladas por el propio usuario.

2.3.1.2 A PLICACIONES

Las aplicaciones Android se escriben en lenguaje Java. Las herramientas Android SDK
compilan el código, junto con los datos y archivos necesarios, en un paquete Android
(archivo con extensión .apk). Este archivo es lo que utilizan los dispositivos Android

28
2.3. A NDROID

FIGURA 2.5: Esquema de la arquitectura del sistema Android.

para instalar la aplicación.

El sistema Android implementa el principio del mínimo privilegio. Es decir, cada


aplicación tiene acceso sólo a los componentes que requiere para ejecutarse y a nada
más. Esto crea un entorno seguro en el que una aplicación no puede tener acceso a
partes del sistema para el que no tenga permisos.

2.3.1.2.1 A NATOMÍA DE UNA APLICACIÓN


La estructura de una proyecto para una aplicación Android está formada por las
siguientes carpetas:
* src: contiene todos los archivos de código .java.

* Android 2.3.3 library: contiene el archivo android.jar donde se encuentran to-


das las librerías necesarias.

29
CAPÍTULO 2. C ONCEPTOS G ENERALES

* gen: contiene el archivo R.java, que referencia todos los recursos del proyecto.
No hay que modificarlo ya que se regenera cada vez que se realiza una compi-
lación.

* assets: contiene todos los bienes de la aplicación: HTML, archivos de texto, bases
de datos, etc.

* res: contiene todos los recursos de la aplicación: imágenes, layouts, strings, etc.
En la carpeta res/layout se encuentran los archivos XML, donde se definen las
IUs de las distintas actividades de la aplicación.

* AndroidManifest.xml: archivo muy importante que contiene información deta-


llada de la aplicación. En él se especifican varios aspectos de la misma: los
permisos, las actividades involucradas y los intent-filters, entre otros.

2.3.1.2.2 A NDROID M ANIFEST


Toda aplicación debe tener un archivo con el nombre AndroidManifest.xml. En
él se define la información detallada sobre la aplicación que el sistema Android debe
tener antes de poder ejecutar cualquier código de la misma.

Los aspectos más importantes que deben especificarse en el AndroidManifest son:

* Nombre del paquete Java para la aplicación.

* Nivel mínimo de la API Android que la aplicación requiere para ejecutarse.

* Descripción de todos los componentes de la aplicación: actividades, servicios,


broadcast receivers y content providers. Para cada componente se especifica: el
nombre de la clase que los implementa y lo que pueden hacer.

* Permisos que requiere la aplicación para acceder a partes protegidas de la API e


interactuar con otras aplicaciones.

* Aspectos de hardware y software usados o requeridos por la aplicación.

* Librerías que la aplicación necesita (aparte de las propias del framework de


Android).

30
2.3. A NDROID

2.3.2 A CTIVIDADES

La actividad es el componente fundamental de la mayoría de aplicaciones Android. El


concepto de actividad va ligado a la idea de interfaz de usuario (IU). Cada actividad
nos muestra una interfaz de usuario y nos permite interactuar con ella, programando
el comportamiento de la aplicación según la interacción del usuario.

Una aplicación consiste, normalmente, en varias actividades relacionadas de alguna


manera entre ellas. Para completar la aplicación se pueden utilizar otros componentes
como los servicios, los broadcast receivers, etc. Aunque no es común, si la aplicación
no requiere de intervención por parte del usuario, puede no tener ninguna actividad.

2.3.2.1 C ICLO DE VIDA DE UNA A CTIVIDAD

La clase Actividad define una serie de métodos imprescindibles que gobiernan su ciclo
de vida y cuya implementación es crucial para desarrollar aplicaciones flexibles y
robustas.

El ciclo de vida de una actividad y los métodos que lo definen pueden observarse en
la figura 2.6.

* onCreate(): se llama cuando una actividad se crea por primera vez. Aquí se
deben inicializar los componentes esenciales de la actividad, así como especificar
el layout que se usará como IU. Este método también recupera el estado previo
de la actividad, en caso de haber sido guardado en una ejecución anterior.

* onStart(): se llama cuando la actividad aparece en la pantalla del usuario.

* onResume(): se llama cuando la actividad empieza a interactuar con el usuario.


En este estado, la actividad está activa, al frente de la pantalla.

* onPause(): se llama cuando la actividad actual se pausa y se reanuda la activi-


dad anterior. En este estado la actividad actual sigue viva, mantiene su estado
y su información, pero puede destruirse por el sistema en caso de problemas de
memoria. Aquí se debe guardar cualquier cambio que se haya hecho y que se
quiera conservar, en caso de que la actividad sea destruida. También se deben
detener animaciones u otras cosas que puedan consumir CPU.

* onStop(): se llama cuando la actividad deja de ser visible por el usuario. En este
estado, igual que onPause(), el sistema puede destruir la actividad en caso de
necesitar la memoria ocupada por ésta.

31
CAPÍTULO 2. C ONCEPTOS G ENERALES

FIGURA 2.6: Ciclo de vida de una actividad.

* onDestroy(): se llama cuando la actividad es destruida por el sistema. Esto puede


ocurrir de forma voluntaria (desde la propia programación de la aplicación) o de
forma involuntaria (cuando el sistema necesita conservar memoria).
* onRestart(): se llama cuando la actividad se había parado y es reanudada de
nuevo.

2.3.3 I NTENTS

El intent es un concepto único y muy importante en Android. Se puede definir como


una declaración de necesidad, una descripción abstracta de una operación que se
quiere realizar. Se utiliza principalmente para: lanzar una actividad/servicio/broadcast
receiver o hacer que una actividad/servicio existente haga algo nuevo.

32
2.3. A NDROID

En función de las necesidades del usuario, los objetos de tipo Intent pueden
utilizarse para pasar información necesaria al componente que los recibe o al sistema
Android.

Los parámetros principales son los siguientes:


* component name: nombre del componente que recibirá el intent (componente
que se quiere lanzar).

* action: descripción de la acción que se quiere realizar.

* data: la información requerida para realizar la acción, expresada en forma de Uri.

* extras: pares de tipo key/value para pasar información adicional al componente


que recibirá el intent.
Por otra parte, el intent filter sirve para especificar los tipos de intents que un
componente puede recibir. Estos filtros no se definen en el código, sino en el Android
Manifest. Los parámetros principales son: action, category y data.

Todas las categorías añadidas a un objeto Intent tienen que coincidir con el Intent
Filter para que el componente deseado pueda ser invocado.

2.3.4 I NTERFAZ DE U SUARIO

Una actividad, por si misma, no tiene presencia en la pantalla, sino que debe dibujar
los elementos de la IU utilizando objetos de tipo View (vistas) y ViewGroup (layouts).
Normalmente, la IU se define mediante un archivo XML, donde se especifican todos sus
componentes. Dependiendo de las necesidades del usuario, la IU puede programarse
dinámicamente, en tiempo de ejecución.

2.3.4.1 C OMPONENTES DE LA PANTALLA

2.3.4.1.1 V ISTAS
Una vista es un widget que tiene presencia en la pantalla. Una ViewGroup propor-
ciona el layout en el que se ordenan todas las vistas que aparecen en la pantalla de una
actividad. A través de las vistas, el usuario es capaz de interactuar con la actividad.

Las vistas más comunes son:


* TextView: se utiliza para mostrar texto al usuario.

* EditText: muestra texto y permite al usuario editar su contenido.

33
CAPÍTULO 2. C ONCEPTOS G ENERALES

FIGURA 2.7: Ejemplo de un Linear Layout con las vistas más comunes y los dos tipos
de menús existentes.

* Button: representa un botón pulsable. Al pulsar, se ejecuta la acción que se le


haya programado.
* ToggleButton: botón con dos estados (on/off) que se muestran con un indicador
de luz.
* ListView: muestra una lista de elementos.
El aspecto de la mayoría de estas vistas se puede observar en la pantalla mostrada
en la figura 2.7.

2.3.4.1.2 L AYOUTS
Los layouts son la arquitectura de la IU en una actividad: definen la estructura de la
pantalla y la posición de los elementos que la componen (vistas).

Los layouts más comunes son:


* Linear Layout: organiza las vistas en un sola fila o columna.

34
2.3. A NDROID

* Table Layout: agrupa las vistas en forma de tabla (filas y columnas).

* Relative Layout: permite especificar la posición de las vistas en relación a otras o


al propio layout.
En la práctica, es común combinar varios layouts en un sola actividad para diseñar
la apariencia deseada para la IU.

No todos los componentes de la interfaz de usuario deben construirse mediante


objetos View y ViewGroup. Dentro de una aplicación, Android proporciona varios
componentes que tienen un layout estándar predefinido de manera que el usuario sólo
necesita definir su contenido, sin preocuparse de la forma. Entre estos componentes se
encuentran: los menús, los diálogos y las notificaciones.

2.3.4.2 M ENÚS

Los menús se utilizan en las actividades para mostrar opciones adicionales que no se
ven directamente en la IU. En Android nos encontramos con dos tipos:
* Options menu: muestra opciones relacionadas con la actividad actual. En la ver-
sión de Android 2.3 o inferior, este menú se muestra en la parte baja de la pantalla
al pulsar la tecla MENU del terminal. A partir de la versión 3.0, estas opciones
se muestran en la Action Bar, que es una barra situada permanentemente en la
parte superior de la actividad. En esta barra aparecen accesos directos del menú
y un listado de opciones.

* Context menu: muestra opciones relacionadas con una vista específica de la activi-
dad. Este menú se activa al mantener pulsada una vista de la IU. Aparece como
una lista flotante de opciones en la pantalla. Se puede definir un context menu
diferente para cada elemento de la IU.
El aspecto de estos menús se puede observar en la pantalla mostrada en la figura 2.7.

2.3.4.3 D IÁLOGOS

Un diálogo es una ventana pequeña que aparece al frente de la actividad actual. Los
diálogos interrumpen la actividad para notificar algo al usuario o para realizar algunas
tareas relacionadas con la actividad en curso.

Los tipos más utilizados son:


* Alert Dialog: se usa desde las actividades para obtener una confirmación del
usuario antes de ejecutar una acción.

35
CAPÍTULO 2. C ONCEPTOS G ENERALES

* Progress Dialog: se usa para mostrar algún progreso relativo a la actividad, como
por ejemplo, el estado de una descarga.

2.3.4.4 N OTIFICACIONES

Las notificaciones se utilizan para informar al usuario de un evento ocurrido en la


aplicación. Algunas notificaciones pueden ser simplemente avisos, otras pueden
requerir una interacción por parte del usuario.

Los tipos de notificaciones más utilizados son:


* Toast Notification: un mensaje en forma de pop up que aparece en la pantalla
durante unos segundos. Esta notificación no acepta ningún tipo de interacción
por parte del usuario.
* Status Notification: aparece en la barra de estado del sistema, en la zona marcada
como Notificaciones. Muestra un icono y un mensaje. Su aparición puede
indicarse mediante una alerta sonora o de vibración. Si se necesita que el usuario
realice una acción, se puede programar el lanzamiento de un intent al pulsar
sobre el mensaje.

2.3.5 S ERVICIOS

Un servicio es un componente de la aplicación que corre en background, sin necesidad


de interactuar con el usuario. Se utiliza para aplicaciones que necesiten realizar opera-
ciones sin mostrar una interfaz de usuario, por ejemplo, la descarga de contenidos de
una página web.

Un servicio puede ser de dos formas:


* Started: cuando un componente de la aplicación lanza el servicio con el método
StartService(). Al iniciar el servicio, éste corre indefinidamente, incluso si se cierra
la aplicación que lo había iniciado. Al finalizar la tarea requerida, se debe detener
el servicio lo antes posible para liberar los recursos que esté utilizando.
* Bound: cuando uno o más componentes de la aplicación se enlazan con el ser-
vicio. Un bound service permite a los componentes interactuar con el servicio,
utilizando sus métodos públicos. Este tipo de servicio sigue corriendo hasta que
no hay ningún componente enlazado a él.
Como en el caso de este proyecto, puede crearse un servicio que combine estos dos
tipos: inicializado por un componente y con varios componentes enlazados.

36
2.3. A NDROID

2.3.6 B ROADCAST R ECEIVERS

Un broadcast receiver es un componente de la aplicación que permite recibir eventos


emitidos u originados por el sistema y/o por otras aplicaciones. Estos avisos se reciben
en forma de intents.

Normalmente, este componente se utiliza como una puerta hacia otros compo-
nentes y se pretende que haga el mínimo trabajo posible: recibe el evento y activa
otro componente para que lo maneje. Aunque la aplicación no esté funcionando, el
broadcast receiver puede continuar escuchando por si llegan nuevos eventos.

2.3.7 P ERSISTENCIA DE D ATOS

Android proporciona diversas opciones para guardar datos de la aplicación. La opción


que se escoja dependerá de las necesidades que se tengan (si los datos deben ser
privados o accesibles para otras aplicaciones) y del tamaño requerido.

2.3.7.1 S HARED P REFERENCES

Esta opción consiste en un mecanismo ligero que permite guardar datos simples de
la aplicación, por ejemplo, las preferencias de usuario. El objeto SharedPreferences
guarda, de forma automática, en un archivo XML, los datos que se especifiquen con
el formato de pares key/value. Estos datos persisten aunque se finalice la aplicación
(tanto de forma manual como forzada por el sistema).

2.3.7.2 B ASE DE DATOS LOCAL

Android ofrece también la posibilidad de guardar información en una base de datos,


usando el sistema SQLite database. Esta base de datos local es propia de cada aplicación
y, por tanto, es accesible desde cualquier clase de la misma, pero no desde fuera de la
aplicación.

La base de datos local puede crearse en tiempo de ejecución (como es el caso


de este proyecto) o en la etapa de diseño de la aplicación. Para esto último existen
herramientas como el SQLite Database Browser.

37
CAPÍTULO 2. C ONCEPTOS G ENERALES

2.3.8 LBS (L OCATION B ASED S ERVICES )

La aparición de los GPS en los smartphones ha propiciado una demanda de servicios


relacionados con este dispositivo. Con este fin, Google permite la utilización de su
programa Google Maps para mostrar mapas y datos relacionados en las aplicaciones
Android.

Android, por su parte, proporciona una serie de herramientas de localización


que permiten obtener datos de posicionamiento que el usuario puede utilizar según
convenga: mostrar en mapas, alertas de posición, etc.

Las principales funciones que se pueden realizar con los LBS en Android son las
siguientes:

* Mostrar mapas, navegar por ellos, hacer zoom y cambiar de vista (satélite, calle-
jero, tráfico).

* Navegar a una localización específica.

* Obtener la localización pulsada en un mapa.

* Geocoding y geocoding inverso.

* Añadir objetos que se dibujen encima del mapa, como por ejemplo, marcadores o
letreros.

* Obtener datos de localización del terminal de distintos proveedores: receptor


GPS, red de telefonía y red WiFi.

* Determinar la localización del terminal y obtener actualizaciones periódicas de la


misma.

* Monitorizar una localización: mediante alertas de proximidad, puede progra-


marse el comportamiento de una aplicación al acercarse o alejarse de una locali-
zación concreta.

Si se desea utilizar Google Maps hay que especificarlo en la build target del proyecto,
ya que Google Maps no forma parte del Android SDK estándar.

38
3
Implementación de la Centralita

3.1 O BJETIVO
en la introducción de este documento, uno de los ob-
C OMO SE HA COMENTADO
jetivos del proyecto es la implantación de un sistema de telefonía VoIP con la
implementación de una centralita telefónica para la residencia de ancianos. Para ello
se ha escogido Asterisk, ya que permite, de forma sencilla, construir una PBX en un
ordenador convencional.

3.2 E NTORNO DE SIMULACIÓN

del sistema de VoIP y la PBX de la residencia se realiza en un


L A IMPLEMENTACIÓN
entorno de simulación donde se ejecutarán todas las pruebas necesarias para com-
probar su correcto funcionamiento. En la figura 3.1 se puede observar un esquema de
este entorno, que consta de los siguientes elementos:
* Un ordenador convencional con sistema operativo Ubuntu 10.04 que se utiliza
como servidor con la IP pública 147.83.39.132.
* Una tarjeta Digium TDM808 que se utiliza para conectar Asterisk a la red de
telefonía. En este caso, la tarjeta se conecta a Ibercom, que es una red privada
virtual de Movistar utilizada en el ámbito de las comunicaciones de empresa.
* Dos cables de teléfono que conectan los puertos 1 y 2 de la tarjeta con las exten-
siones internas 17479 y 17480 de la red Ibercom.
* Un teléfono analógico conectado a la extensión interna 54081 que se utiliza para
comprobar el funcionamiento de la PBX.

39
CAPÍTULO 3. I MPLEMENTACIÓN DE LA C ENTRALITA

FIGURA 3.1: Esquema del entorno de simulación.

3.3 I NSTALACIÓN DEL ENTORNO

de la centralita es instalar el software y


E L PRIMER PASO PARA LA IMPLEMENTACIÓN
hardware necesario en el servidor.

Normalmente, Asterisk se suele instalar conjuntamente con otros dos paquetes:


DAHDI y libPRI. Si se deseara implementar una centralita que utilizara solamente
VoIP, con el paquete Asterisk tendríamos suficiente. En este caso, al disponer de una
tarjeta para conectar con la red de telefonía, debemos instalar los controladores de
harware de DAHDI. Además, también instalamos la librería para puertos primarios
libPRI. Aunque de momento no se desea conectar con una red RDSI, se recomienda su
instalación antes que Asterisk por si se quiere utilizar en un futuro.

Las últimas versiones estables de estos paquetes se pueden encontrar y descargar


desde la página web oficial de Asterisk: http://www.asterisk.org/downloads. En la
ultima actualización de este proyecto, las versiones utilizadas fueron:

* Asterisk 10.0.0

* DAHDI Complete 2.5.0.2 + 2.5.0.2

* libPRI 1.4.12

40
3.3. I NSTALACIÓN DEL ENTORNO

Una vez descargados estos archivos, se guardan y se descomprimen en el directorio


/usr/src de Linux. Los pasos a seguir para su instalación se pueden ver en el anexo A.1.

Además de estos paquetes básicos, también se instalarán otros que servirán para
añadir funcionalidades y mejorar la calidad de los servicios ofrecidos por la centralita.
Estos paquetes son:

* Oslec, un cancelador de eco software para las llamadas de la red analógica.

* SSMTP, un gestor de correo electrónico para utilizar con el buzón de voz.

* CMUSphinx, un programa de reconocimiento de voz para integrar en el fun-


cionamiento de la centralita.

* SFLphone, un softphone para poder hacer las simulaciones.

3.3.1 TARJETA D IGIUM TDM808

Para comunicar Asterisk con la red de telefonía se instala en el servidor una tarjeta
analógica de Digium, la TDM808. Las tarjetas de la serie 800 soportan hasta ocho
conexiones por tarjeta utilizando sus ocho puertos. Estos puertos pueden tener dos
tipos de interfaces diferentes y se distinguen visualmente por su color: FXO (rojo) y
FXS (verde). La TDM808 está compuesta por ocho módulos rojos, de tipo FXO.

Después de instalar la tarjeta, se comprueba el listado de los dispositivos detecta-


dos por el bus PCI para ver si la tarjeta es detectada correctamente con el siguiente
comando:
> lspci -n

La detección de la tarjeta se confirma al aparecer en el listado un dispositivo con el


identificador de Digium d161 seguido del identificador de la tarjeta 800.
07:04.0 0200: d161 :0800 ( rev 11)

3.3.2 C ANCELADOR DE ECO O SLEC

Por defecto, el cancelador de eco software para las líneas analógicas que maneja
DAHDI es el mg2. Dado que el rendimiento del cancelador por defecto no es
demasiado bueno, se decide utilizar Oslec en su lugar. Oslec es un cancelador de
eco de línea open source de alto rendimiento que, aunque no viene incluido en el
paquete DAHDI, se puede integrar de forma fácil para que funcione con DAHDI. A
continuación se detallarán los pasos a seguir para instalar Oslec en el sistema. La

41
CAPÍTULO 3. I MPLEMENTACIÓN DE LA C ENTRALITA

posterior configuración e integración con DAHDI se explicará más adelante. Los pasos
seguidos para su instalación se pueden observar en el anexo A.1.5.

3.3.3 G ESTOR DE CORREO

SSMTP es un programa que sirve para enviar correos electrónicos desde un ordenador
local a un host de correo configurado (mailhub). Uno de sus principales usos es el
reenvío de correos electrónicos automatizados desde el ordenador a una dirección de
correo externa.

Este programa se utiliza con la funcionalidad de buzón de voz de Asterisk. Al


configurar las cuentas de buzón de voz, se especifica una dirección de correo elec-
trónico para cada usuario. Al dejar un mensaje en el buzón de voz, se envía de forma
automática un correo electrónico a esa dirección para avisar al usuario de que tiene
un mensaje nuevo. Este correo incluye además un archivo de audio adjunto con el
mensaje de voz.

Para instalar SSMTP en el servidor, se utiliza el gestor de paquetes Synaptic incluido


en el sistema operativo.

3.3.4 R ECONOCIMIENTO DE VOZ

El menú principal de la centralita permite la introducción de la extensión deseada


por dos medios distintos: teclado del teléfono y reconocimiento de voz. Como
se ha comentado anteriormente, Asterisk no incluye ninguna herramienta para el
reconocimiento de voz, pero permite la utilización de motores de reconocimiento de
terceros. Por este motivo se utiliza en el servidor el proyecto CMUSphinx.

CMUSphinx es un toolkit de reconocimiento de voz que incluye varias herramientas


para construir aplicaciones de reconocimiento. De estas herramientas sólo se utilizarán
dos: Pocketsphinx (librería de reconocimiento) y Sphinxbase (librería de soporte). Los
paquetes necesarios para instalar estas librerías se pueden descargar desde la página
del proyecto: http://cmusphinx.sourceforge.net/. La instalación de estas librerías
se puede observar en el anexo A.1.6.

3.3.5 S OFTPHONE

Un softphone es un programa que simula el comportamiento de un teléfono y que


se utiliza para realizar llamadas VoIP desde un ordenador. En este proyecto se ha

42
3.4. C ONFIGURACIONES

utilizado para simular a los diversos usuarios conectados al servidor Asterisk.

Se escoge el softphone SFLphone para Linux, principalmente, porque es de código


abierto y dispone de una comunidad muy activa, facilitando así la resolución de
cualquier duda o problema que pueda surgir. Además, permite la utilización de
mecanismos de securización (como SRTP) por si se quieren añadir en un futuro. Para
instalarlo en el servidor, se utiliza el gestor de paquetes Synaptics.

3.4 C ONFIGURACIONES

instalado en el servidor, ya se pueden realizar las configu-


C ON TODO LO NECESARIO
raciones necesarias que permitirán poner en marcha todo el sistema de VoIP de
la residencia. Como en cualquier empresa, este sistema consta de una parte interna
(residentes y trabajadores de la residencia) y de una parte externa (PBX para las
llamadas procedentes del exterior).

3.4.1 TARJETA D IGIUM Y C ANCELADOR DE ECO O SLEC

El primer paso para poder poner la PBX en funcionamiento es la configuración del


entorno para poder comunicar el servidor con el mundo exterior (la red de telefonía).
Con ese fin, hay que configurar el interfaz DAHDI para que trabaje con la tarjeta
instalada y con el cancelador de eco Oslec.

Sabiendo que el servidor detecta correctamente la tarjeta Digium TDM808, se


puebla el fichero /etc/dahdi/system.conf escribiendo la siguiente instrucción en un
terminal:
> dahdi_genconf

Esta instrucción comprueba las tarjetas disponibles en el ordenador y configura el


fichero system.conf con la información que obtiene de dichas tarjetas. Al inspeccionar
el archivo después de ejecutar este comando, vemos el nombre de la tarjeta detectada
y dos líneas por cada módulo detectado (ocho en este caso). Para cada módulo se
especifica el tipo y señalización (fxsks1 ) y el cancelador de eco asociado. También hay
dos líneas especificando el país de utilización para los tonos. Se cambia el cancelador
de eco por defecto (mg2) por el que se ha instalado (Oslec) y el país de utilización a
España.

1
Los módulos FXO se definen con la nomenclatura contraria ’fxs’. Estos módulos usan señalización
’ks’ (Kewlstart Signalling), que corresponde a señalización loopstart con supervisión de desconexión.

43
CAPÍTULO 3. I MPLEMENTACIÓN DE LA C ENTRALITA

Finalmente, el fichero /etc/dahdi/system.conf tiene este aspecto:


# Span 1: WCTDM /0 " Wildcard TDM800P Board 1" ( MASTER )
fxsks =1
echocanceller = oslec ,1
fxsks =2
echocanceller = oslec ,2
fxsks =3
echocanceller = oslec ,3
fxsks =4
echocanceller = oslec ,4
fxsks =5
echocanceller = oslec ,5
fxsks =6
echocanceller = oslec ,6
fxsks =7
echocanceller = oslec ,7
fxsks =8
echocanceller = oslec ,8

# Global data
loadzone = es
defaultzone = es

A continuación hay que cargar los drivers de DAHDI en el kernel mediante la si-
guiente instrucción. El driver adecuado para la serie 800 es el wctdm24xxp.
> cd / etc / dahdi
> modprobe wctdm24xxp

Para habilitar el cancelador de eco Oslec, hay que modificar las siguientes líneas en
dos archivos ubicados en el directorio /etc/dahdi del sistema:
> nano / etc / dahdi / init . conf
# Descomentamos esto :
DAHDI_UNLOAD_MODULES = " dahdi echo " # If you use OSLEC

> nano / etc / dahdi / genconf_parameters


# Descomentamos esto :
echo_can oslec

Algunas tarjetas Digium incluyen un cancelador de eco hardware (HWEC) que


aparece configurado por defecto y que puede utilizarse en combinación con Oslec. De
todas formas, si se deseara deshabilitar el cancelador hardware, debe modificarse la
siguiente línea del archivo /etc/modprobe.d/dahdi.conf:
> vi / etc / modprobe . d / dahdi . conf

options wctdm24xxp vpmsupport =0

44
3.4. C ONFIGURACIONES

Las configuraciones de señalización y los códigos utilizados para los tonos en la red
de telefonía varían en función de la zona o el país en el que nos encontremos. Por eso
hay que realizar unos cambios para conseguir que la configuración de la tarjeta sea la
adecuada para operar en España. Con este fin, se hacen las siguientes modificaciones
en estos archivos:
> nano / etc / asterisk / indications . conf
country = es

> nano / etc / modprobe . d / dahdi . conf


options wctdm24xxp opermode = SPAIN

Por último, se verifica que la configuración de los módulos de la tarjeta sea la co-
rrecta y que se hayan aplicado correctamente todos los cambios. Para ello se utiliza
una instrucción que muestra por pantalla un resumen de los puertos de la tarjeta y su
configuración.
> dahdi_cfg - vvv

DAHDI Tools Version - 2.5.0.2


DAHDI Version : 2.5.0.2
Echo Canceller ( s ) : HWEC , OSLEC

Configuration
======================
Channel map :
Channel 01: FXS Kewlstart ( Default ) ( Echo Canceler : oslec ) ( Slaves : 01)
Channel 02: FXS Kewlstart ( Default ) ( Echo Canceler : oslec ) ( Slaves : 02)
Channel 03: FXS Kewlstart ( Default ) ( Echo Canceler : oslec ) ( Slaves : 03)
Channel 04: FXS Kewlstart ( Default ) ( Echo Canceler : oslec ) ( Slaves : 04)
Channel 05: FXS Kewlstart ( Default ) ( Echo Canceler : oslec ) ( Slaves : 05)
Channel 06: FXS Kewlstart ( Default ) ( Echo Canceler : oslec ) ( Slaves : 06)
Channel 07: FXS Kewlstart ( Default ) ( Echo Canceler : oslec ) ( Slaves : 07)
Channel 08: FXS Kewlstart ( Default ) ( Echo Canceler : oslec ) ( Slaves : 08)

8 channels to configure .

Setting echocan for channel 1 to oslec


Setting echocan for channel 2 to oslec
Setting echocan for channel 3 to oslec
Setting echocan for channel 4 to oslec
Setting echocan for channel 5 to oslec
Setting echocan for channel 6 to oslec
Setting echocan for channel 7 to oslec
Setting echocan for channel 8 to oslec

Se hace una última comprobación mediante la instrucción dmesg, que lista el buffer
de mensajes del núcleo, y se buscan las líneas relativas a las configuraciones que se han

45
CAPÍTULO 3. I MPLEMENTACIÓN DE LA C ENTRALITA

llevado a cabo. A continuación se muestran estas líneas, donde vemos que se detecta
la tarjeta Digium con los puertos de tipo FXO configurados para funcionar con los tonos
de España y que se han encontrado también los dos canceladores de eco: hardware
(HWEC VPMADT032) y software (Oslec).
wctdm24xxp 0000:07:04.0: Freed a Wildcard
wctdm24xxp 0000:07:04.0: PCI INT A disabled
dahdi : Telephony Interface Unloaded
dahdi : Telephony Interface Registered on major 196
dahdi : Version : 2.5.0.2
wctdm24xxp 0000:07:04.0: PCI INT A -> GSI 20 ( level , low ) -> IRQ 20
wctdm24xxp 0000:07:04.0: Port 1: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Port 2: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Port 3: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Port 4: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Port 5: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Port 6: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Port 7: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Port 8: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Booting VPMADT032
wctdm24xxp 0000:07:04.0: VPM present and operational ( Firmware
version 125)
wctdm24xxp 0000:07:04.0: Found a Wildcard TDM : Wildcard TDM800P (0
BRI spans , 8 analog channels )
wctdm24xxp 0000:07:04.0: Freed a Wildcard
wctdm24xxp 0000:07:04.0: PCI INT A disabled
dahdi : Telephony Interface Unloaded
dahdi : Telephony Interface Registered on major 196
dahdi : Version : 2.5.0.2
wctdm24xxp 0000:07:04.0: PCI INT A -> GSI 20 ( level , low ) -> IRQ 20
wctdm24xxp 0000:07:04.0: Port 1: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Port 2: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Port 3: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Port 4: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Port 5: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Port 6: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Port 7: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Port 8: Installed -- AUTO FXO ( SPAIN mode )
wctdm24xxp 0000:07:04.0: Found a Wildcard TDM : Wildcard TDM800P (0
BRI spans , 8 analog channels )
dahdi_echocan_oslec : Registered echo canceler ' OSLEC '

3.4.2 C ANALES DAHDI

El último paso relativo a la configuración de la parte externa es la modificación del


archivo chan_dahdi.conf que se encuentra ubicado en el directorio /etc/asterisk.
Este archivo es la capa de configuración entre DAHDI y Asterisk y sirve para definir las
características esenciales de los canales relativos a la tarjeta instalada.

46
3.4. C ONFIGURACIONES

El archivo chan_dahdi.conf consta de dos partes: la definición de las opciones


generales de los canales y la definición de los propios canales. Las características gene-
rales de los canales incluyen, por ejemplo: la utilización de identificación de llamada, la
posibilidad de aparcar y transferir llamadas, la utilización del cancelador de eco, tipos
de señalización utilizados, etc. A continuación hay que definir los canales relativos a
los módulos de la tarjeta para que Asterisk sea capaz de reconocerlos y utilizarlos. En
este caso, la definición de los canales se realiza de la siguiente forma:
; FXO Modules
group =1
callgroup =1
pickupgroup =1
signalling = fxs_ks
callerid = asreceived
context = from - pstn
channel = > 1 -8

Se definen los ocho canales disponibles dentro de un único grupo (1), por lo
tanto, todos los canales tendrán las mismas características. Se especifica el tipo de
señalización (fxs_ks) y que el identificador de llamada de estos canales venga marcado
por el obtenido de la red telefónica. También se define el contexto que utilizarán todos
los canales ([f rom − pstn]). Esto quiere decir que todas las llamadas que utilicen estos
canales (entrantes desde la red telefónica) ejecutarán las instrucciones del dialplan
correspondientes a este contexto. Como se puede deducir, el contexto [f rom − pstn] es
donde se ubica la definición de la centralita (PBX).

La configuración completa de este archivo puede encontrarse en el anexo A.2.1.

3.4.3 A STERISK

En este apartado se detalla la configuración del sistema de telefonía VoIP que se ha


implementado para el escenario de la residencia. Para ello se detallarán los archivos
de configuración relativos a los módulos de Asterisk que se han utilizado. Todos estos
ficheros se encuentran en el directorio /etc/asterisk.

3.4.3.1 U SUARIOS

La definición de los clientes SIP que se pueden registrar en el servidor de VoIP se


realiza en el archivo /etc/asterisk/sip.conf. Cada usuario (cliente SIP) debe tener
un nombre que lo identifique y una clave de acceso para poder registrarse. También
deben especificarse otros aspectos, como los códecs que pueden utilizar y el contexto

47
CAPÍTULO 3. I MPLEMENTACIÓN DE LA C ENTRALITA

TABLA 3.1: Listado de usuarios SIP.

Residentes [PermisosResidentes]
200, 201, 202
501 (recepción)
502 (trabajadora social)
503 - 505 (gerocultoras)
506 (despacho directora)
Trabajadores [PermisosTrabajadores]
507 (móvil directora)
508 (casa directora)
509 (psicóloga)
500 (jefa de enfermeras)

que tratará las llamadas.

Para realizar las simulaciones se han definido una serie de clientes que representan
a los posibles usuarios del sistema implementado en la residencia de ancianos. Se
diferencian dos tipos: los residentes y los trabajadores. A cada tipo se le asigna un
contexto diferente ya que no todos podrán acceder a las mismas extensiones en el
dialplan. A todos los usuarios se les habilita el códec G.711 en sus dos versiones (a-law
y u-law).

En la tabla 3.1 se encuentra un resumen de los usuarios creados. La definición


completa de estos usuarios se puede encontrar en el anexo A.2.2.

3.4.3.2 D IALPLAN

El dialplan es el núcleo del sistema Asterisk. En él se indica el manejo de todas las


llamadas que llegan al servidor. La descripción del dialplan se realiza en el archivo
/etc/asterisk/extensions.conf. Este fichero se estructura en contextos, y esos
contextos, a su vez, en extensiones.

En este caso se han definido una serie de contextos que permitirán realizar una serie
de acciones dependiendo del tipo de usuario o del punto de acceso. A continuación se
listan los contextos utilizados y se resumen sus funciones:
* [usuarios]: este contexto contiene las extensiones que permiten: acceder a la
macro de llamadas para todos los usuarios (trabajadores y residentes) y acceder
a la sala de conferencias 101 (que se explicará más adelante).
* [macro−U naExten]: las macros son contextos especiales que se pueden reutilizar
en otros contextos. Este contexto sólo contiene la extensión s, que es modificada

48
3.4. C ONFIGURACIONES

en los consiguientes contextos por el número de extensión que invoca. En este


caso, se utiliza una macro para realizar las llamadas locales (entre los usuarios
internos). Se comprueba que la extensión no esté en la lista negra, si hay desvíos
activos y entonces se realiza el marcado. Si no hay respuesta, salta el buzón de
voz.
* [Buzon_de_voz]: contiene la extensión 99, que da acceso al buzón de voz para
que los usuarios puedan escuchar sus mensajes.
* [grabadora]: contiene las extensiones que permiten grabar las locuciones de voz
para la PBX en formato WAV. Los archivos de audio grabados se guardan en el
directorio /var/lib/asterisk/sounds/custom.
* [android_V A]: contiene las extensiones que se utilizarán para notificar a los
usuarios internos de las alertas originadas por los softphones implementados en
Android. Su contenido se detalla en el capítulo 4.
* [P C_a_RT C]: permite a los usuarios internos realizar llamadas a números exter-
nos marcando previamente 00. Estas llamadas se transmiten por una de las líneas
analógicas conectadas a la tarjeta TMD808.
* [f rom − pstn]: trata todas las llamadas entrantes procedentes del exterior.
Este contexto, junto con [centralita_ASR] y [menu − privado] se explicarán
detalladamente más adelante.

Asterisk permite el anidamiento de contextos, es decir, contextos dentro de con-


textos. Esto se utiliza para restringir el acceso a algunas funcionalidades depen-
diendo del usuario. Con este fin se crean los contextos [P ermisosResidentes] y
[P ermisosT rabajadores], que dan acceso a los contextos cuyas extensiones se pueden
utilizar por los diferentes usuarios:
* [P ermisosResidentes]: contexto donde se tratan las llamadas de los residentes
(usuarios 200, 201 y 202). Éste da acceso a los contextos: [usuarios],
[Buzon_de_voz] y [Android_V A].
* [P ermisosT rabajadores]: contexto donde se tratan las llamadas de los traba-
jadores (usuarios del 500 al 509). Éste da acceso a los contextos: [usuarios],
[Buzon_de_voz], [grabadora], [Android_V A], [P C_a_RT C] y [parkedcalls] (nece-
saria para poder transferir y aparcar llamadas). También incluye las extensiones
que permiten activar/desactivar el desvío de llamadas y el acceso a la sala de
conferencias 600 (limitada a 3 usuarios y sólo para empleados).

La configuración completa del dialplan se puede encontrar en el anexo A.2.3.

49
CAPÍTULO 3. I MPLEMENTACIÓN DE LA C ENTRALITA

3.4.3.3 M ÚSICA EN ESPERA

Asterisk ofrece la posibilidad de utilizar música en espera cuando un usuario queda a


la espera durante una llamada. También se puede reproducir música en substitución
de los tonos de marcado.

La configuración de la música en espera se realiza en el archivo


/etc/asterisk/musiconhold.conf y se puede encontrar en el anexo A.2.4. En
este fichero se especifican la localización y el modo de reproducción de los archivos
de audio. En este caso existen dos posibilidades: dos archivos de audio en formato
WAV y una emisora de radio gratuita shoutcast (Big B Radio). La emisora de radio es
la música en espera por defecto en todas las extensiones de la PBX. Los archivos de
audio, que se reproducen de forma aleatoria, se utilizan para el resto de los casos.

3.4.3.4 B UZÓN DE VOZ

El servicio de voicemail que ofrece Asterisk es similar al de cualquier buzón de voz


añadiendo más funcionalidades. La más destacable es la capacidad de enviar un
correo electrónico al usuario para avisarle de que tiene nuevos mensajes. Este correo
electrónico incluye, además, un fichero adjunto con el mensaje de voz en el formato
especificado. Como se ha comentado anteriormente, para utilizar esta funcionalidad, el
servidor debe contar con un gestor de correo, en este caso, el SSMTP. La configuración
de este gestor se encuentra en el anexo A.2.5.1.

La configuración de los buzones de voz se realiza en el archivo


/etc/asterisk/voicemail.conf y se puede encontrar en el anexo A.2.5. En
este fichero se definen todas las cuentas de voicemail, asociando a cada usuario un
nombre, una cuenta de correo electrónico para recibir los mensajes y una contraseña
para acceder al buzón de voz desde el teléfono. En este caso se define una cuenta para
cada usuario definido en sip.conf. También se pueden configurar varias opciones
generales para todas las cuentas, como por ejemplo: especificar el cuerpo del correo
electrónico, el formato del archivo de audio enviado o el tamaño y duración del
mensaje. Para evitar que el buzón de voz bloquee la línea demasiado tiempo, se ha
modificado la longitud máxima de los mensajes y el tiempo de silencio antes de parar
la grabación a 30 y 10 segundos respectivamente.

3.4.3.5 F OLLOW M E

La funcionalidad Follow Me sirve para intentar localizar a un usuario llamando a


distintas localizaciones (en serie o en paralelo). La configuración de este servicio

50
3.4. C ONFIGURACIONES

se realiza en el archivo /etc/asterisk/followme.conf. En él se especifican, por


orden, las extensiones a las que llamar y el tiempo que se debe esperar hasta pasar a
la siguiente destinación. En este caso se utiliza en la extensión de la centralita que
contacta con la directora del centro. Primero se intenta en el despacho, y si no hay
respuesta, se llama al móvil y por último, a su casa.

La configuración completa del protocolo de seguimiento se puede encontrar en el


anexo A.2.6.

3.4.3.6 S ALA DE C ONFERENCIAS

Las salas de conferencia permiten crear conversaciones entre múltiples usuarios como
si estuvieran todos en una misma localización física. Algunas de las principales
características de este servicio incluyen: la creación de varias salas distintas con
acceso protegido por contraseña, la posibilidad de regular el número de participantes
(fijando un número máximo, echando usuarios o bloqueando la sala), la capacidad de
enmudecer a uno o varios participantes, etc.

En este caso se crean dos salas de conferencias con diferentes contraseñas. La sala
número 600 sólo es accesible por los trabajadores de la residencia. La sala número
101 permite el acceso a usuarios tanto internos como externos. El acceso exterior se
encuentra en una extensión del menú privado de la centralita. El acceso interior se
encuentra en el contexto [usuarios] disponible tanto para los residentes como para los
trabajadores.

La configuración de las salas de conferencias se realiza en el archivo


/etc/asterisk/meetme.conf y se puede encontrar en el anexo A.2.7.

3.4.3.7 C OLAS

La distribución automática de llamadas, o cola de llamadas, proporciona a la PBX una


forma de encolar llamadas entrantes de un grupo de usuarios. En este caso se utiliza
desde la extensión de la centralita que contacta con la jefa de enfermeras. Al marcar la
extensión, si no se consigue contactar con la jefa enfermeras se coloca la llamada en la
cola, donde se mantendrá hasta que sea atendida por alguna gerocultora o se alcance
el tiempo máximo de espera en cola.

La configuración de la cola de llamadas se realiza en el archivo


/etc/asterisk/queues.conf y se puede encontrar en el anexo A.2.8. En este
fichero se especifican los miembros que atenderán la cola de llamadas por orden de

51
CAPÍTULO 3. I MPLEMENTACIÓN DE LA C ENTRALITA

prioridad. En este caso, los miembros serán las gerocultoras (usuarios 503, 504 y
505, en este orden). También se pueden fijar varias opciones, como por ejemplo: tipo
de anuncios que se hacen al llamante mientras está en cola, música que se escucha
mientras se espera a ser atendido, número de reintentos, tiempo máximo de espera en
cola, etc.

3.4.3.8 T RANSFERENCIA Y PARKING DE LLAMADAS

La transferencia y el aparcado de llamadas son funcionalidades típicas de las PBX.


La transferencia de llamadas permite redireccionar una llamada desde la extensión
que la está atendiendo a cualquier otra. El parking de llamadas consiste en dejar una
llamada en espera en una extensión y recogerla en cualquier otra. Estas funciones
están disponibles por todos los usuarios internos del sistema.

La configuración de éstas y otras funcionalidades se realiza en el archivo


/etc/asterisk/features.conf y se puede encontrar en el anexo A.2.9. En este
archivo se pueden especificar, entre otras cosas, las extensiones en las que pueden
aparcarse las llamadas o las secuencias DMTF que hay que marcar para poder transferir
llamadas. Las transferencias pueden ser de dos tipos: ciegas (se transfiere la llamada
sin más) o guiadas (primero se contacta con la extensión deseada y luego se realiza la
transferencia).

3.4.4 C ENTRALITA PBX

Todas las llamadas entrantes procedentes de la red de telefonía (exterior) llegan a


la centralita que se ha implementado y son recibidas por una operadora virtual que
las direccionará a la extensión deseada. Como se ha avanzado en la explicación
del dialplan, los contextos que se utilizan para la configuración de la PBX son:
[f rom − pstn] (entrada a la centralita), [centralita_ASR] (definición de las extensiones
de la centralita) y [menu − privado] (definición de las extensiones del menú privado de
la centralita).

Las llamadas entrantes exteriores son tratadas por el contexto [f rom − pstn]. En
él se encuentra la puerta de entrada a la centralita. Si la llamada se recibe den-
tro del horario de recepción, se pasa la llamada al contexto [centralita_ASR] dando
acceso al menú de la PBX. Si no, se envía la llamada al buzón de voz de recepción (501).

En el contexto [centralita_ASR] se encuentra la definición de la parte pública de


la PBX. Mediante locuciones de voz grabadas, se da la bienvenida al llamante y se le
informa de las posibles extensiones a las que puede acceder (0 a 5). Las extensiones

52
3.4. C ONFIGURACIONES

pueden introducirse de forma oral (mediante reconocimiento de voz) o mediante el


teclado del teléfono. Se dan dos oportunidades para especificar la extensión deseada
por voz. Si no se reconoce una extensión válida, se pide la introducción vía teclado y
si no, se redirige la llamada a recepción (extensión 0) para que se le pueda atender
o redireccionar a la extensión adecuada. Los pasos que sigue una llamada entrante
desde que llega a la centralita hasta que se escoge una extensión válida se pueden ver
en el diagrama de la figura 3.2.

A continuación se hace un breve resumen de las extensiones disponibles desde este


contexto y su funcionamiento:

* Extensión 0: Recepción. Se realiza una llamada al usuario recepción (501).


Desde aquí se puede atender la llamada y transferirla a la extensión o usuario
adecuados. A esta extensión se puede llegar directamente desde el menú o al
agotar el número máximo de intentos de introducir una extensión válida. Su
funcionamiento se puede observar en el diagrama de la figura 3.3.

* Extensión 1: Trabajadora social. Se realiza una llamada a la trabajadora social


(502). Si no está disponible, se pasa la llamada al buzón de voz, como se puede
ver en el diagrama de la figura 3.4.

* Extensión 2: Enfermería. Se realiza una llamada a la jefa de enfermeras (500)


y si está ocupada se pasa la llamada a la cola donde será atendida por alguna de
las gerocultoras, como se puede ver en el diagrama de la figura 3.5.

* Extensión 3: Dirección. Se realiza una llamada al despacho de la directora del


centro (506). Si no hay respuesta, se inicia el protocolo de seguimiento follow
me para intentar ubicarla en otros emplazamientos (el móvil y su casa). Se pide
el nombre del llamante para anunciarlo al llamado en cada ubicación. Si no se
consigue contactar con la directora, se dirige la llamada al buzón de voz corres-
pondiente. Este comportamiento se puede ver en el diagrama de la figura 3.6.

* Extensión 4: Psicóloga. Se realiza una llamada a la psicóloga del centro (509).


La psicóloga puede redirigir su teléfono a la recepción si no quiere ser molestada
durante las sesiones. Primero se comprueba si hay una redirección y después se
llama a la extensión adecuada, como se puede ver en el diagrama de la figura 3.7.

* Extensión 5: Llamada exterior. Permite llamar a cualquier número del exterior


pasando por Asterisk. En este caso, el número debe tener un máximo de 5 cifras.

* Extensión 6: Menú privado. Permite el acceso al menú privado, que se explicará


más adelante. Esta extensión no se nombra en el menú de inicio ya que está
pensada para que sólo trabajadores autorizados de la residencia puedan acceder.

53
CAPÍTULO 3. I MPLEMENTACIÓN DE LA C ENTRALITA

De todas formas, aunque se entrara por error, el acceso está protegido por una
contraseña.

* Extensión #: Colgado. Después de pasar por cualquier extensión, todas las lla-
madas son dirigidas a ésta. Aquí se despide al llamante mediante una locución
de voz y se cuelga la llamada.

* Extensión i: Extensión incorrecta. Se llega a esta extensión de forma automática


al marcar una extensión incorrecta (no existente). Después de informar del
error, se reenvía la llamada al menú de extensiones del inicio. Si se ha alcan-
zado el número máximo de errores, se envía la llamada a recepción (extensión 0).

En el contexto [menu − privado] se encuentra la definición de la parte privada de


la PBX. El menú privado está pensado para uso exclusivo de la directora del centro
y permite entrar en la sala de conferencias 101 y realizar escuchas desde cualquier
teléfono exterior a la residencia. El acceso está controlado mediante contraseña
para que nadie pueda entrar por error. Se dan tres oportunidades de introducir la
contraseña correcta, si no, se cuelga la llamada automáticamente. Al acceder a esta
zona, se reproduce la locución de voz que informa de las opciones del menú privado
y se espera la introducción por teclado de la extensión deseada. Su funcionamiento se
puede ver en el diagrama de la figura 3.8.

Las extensiones disponibles en este contexto son las siguientes:

* Extensión 1: Sala de conferencias. Da acceso a la sala de conferencias 101


mediante la contraseña correspondiente. A esta sala también tienen acceso los
usuarios internos. Se especifican las siguientes opciones: se reproduce música si
sólo hay una persona en la sala y se puede salir de ella pulsando la tecla #.

* Extensión 2: Escucha de llamadas. Permite espiar cualquier conversación que


se esté realizando entre extensiones internas de la residencia. Pulsando la tecla *
se detiene el espionaje del canal actual y se cambia a una conversación diferente.
Pulsando la tecla # se sale de la extensión de escuchas y se llega a la extensión
de colgado de la centralita.

* Extensión i: Extensión incorrecta. Se llega a esta extensión de forma automática


al marcar una extensión incorrecta (no existente). Después de informar del error,
se reenvía la llamada al menú de extensiones privado.

La configuración completa de la PBX se puede encontrar en el anexo A.2.3.

54
3.4. C ONFIGURACIONES

3.4.4.1 I NTEGRACIÓN DEL RECONOCIMIENTO DE VOZ

El reconocimiento de voz se usa para seleccionar la extensión deseada en el menú


principal de la centralita. Para ello se utiliza el proyecto CMUSphinx. Este proyecto
ofrece una aplicación llamada pocketsphinx_continuous que se lanza desde un
terminal y que hace el reconocimiento de voz de la entrada del micro. También incluye
la posibilidad de utilizar como entrada del reconocimiento un fichero de audio en
formato WAV.

La utilización de esta aplicación en Asterisk se hace mediante el script asr2.sh. A


continuación se muestra el código de la PBX donde se utiliza el reconocimiento de voz
y se explica su funcionamiento detalladamente:
1 exten = > s ,1 , Answer ()
2 same = > 2 , Background ( custom / asr_bienvenida )
3 same = > 3 , Set ( k =1)
4 same = > 4 , While ( $ [ $ { k } <3])
5 same = > n , Background ( custom / asr_extension_voz )
6 same = > n , Background ( custom / asr_menu )
7 same = > n , Record ( custom / recon / voz . wav , ,5)
8 same = > n , System (/ var / lib / asterisk / sounds / custom / recon / asr2 . sh )
9 same = >
n , Set ( num = $ { FILE (/ var / lib / asterisk / sounds / custom / recon / num . txt ,0 ,1) })
10 same = > n , NoOp ( num = $ { num })
11 same = > n , GotoIf ( $ [ " $ { num } " = " " ]? null )
12 same = > n , GotoIf ( $ [ $ { num } <0 | $ { num } >6]?: ok )
13 same = > n , Set ( num = i )
14 same = > n ( ok ) , Goto ( $ { num } ,1)
15 same = > n ( null ) , Set ( k = $ [ $ { k }+1])
16 same = > n , EndWhile
17 same = > n , Background ( custom / asr_extension & beep )
18 same = > n , WaitExten (15 , m ( radio ) )
19 same = > n ( max ) , PlayBack ( custom / asr_max_intentos )
20 same = > n , Goto (0 ,1)

Después de escuchar la locución de voz que informa del menú de extensiones


principal, se pide al llamante que diga la extensión que desea. La respuesta se graba
en un archivo de audio (voz.wav) mediante la instrucción Record() (línea 7). A
continuación, se lanza el script encargado de hacer el reconocimiento de la respuesta
grabada utilizando la instrucción System() (línea 8). Por último, se guarda el número
de extensión obtenido del reconocimiento en la variable num del dialplan (línea 9). El
valor de esta variable se utiliza para dirigir la llamada a la extensión deseada mediante
la instrucción Goto() (línea 14).

El shell script asr2.sh utiliza la aplicación pocketsphinx_continuous para hacer el


reconocimiento de la siguiente manera:

55
CAPÍTULO 3. I MPLEMENTACIÓN DE LA C ENTRALITA

# ! / bin / sh

dir = " / var / lib / asterisk / sounds / custom / recon "

pocketsphinx_continuous - hmm en / tidigits - lm en / tidigits . DMP - dict


en / tidigits . dic - infile $ { dir }/ voz . wav - samprate 8000 | tail -c +12
> $ { dir }/ out . txt

cat $ { dir }/ numbers . txt | agrep -f $ { dir }/ out . txt | head -c 1 >
$ { dir }/ num . txt

Primero se realiza el reconocimiento de voz del fichero voz.wav mediante la apli-


cación pocketsphinx_continuous, utilizando el modelo acústico y diccionario tidigits.
Este diccionario permite el reconocimiento de dígitos del 0 al 9 en inglés. La salida del
reconocimiento devuelve mucha información y con la instrucción tail se obtiene sólo
el dato deseado, el nombre del dígito reconocido, que se guarda en el archivo out.txt.
Por último se obtiene el dígito reconocido en formato numérico para que Asterisk
pueda utilizarlo para especificar la extensión. Esto se hace con la ayuda del fichero
numbers.txt, convirtiendo el nombre del número en su dígito correspondiente y
guardando el resultado en el fichero num.txt. El fichero numbers.txt es simplemente
un archivo de texto que contiene once líneas (una para cada palabra posible) con la
siguiente nomenclatura:

(número) (nombre del número)

Todos los archivos utilizados para el reconocimiento de voz se encuentran ubicados


en el directorio /var/lib/asterisk/sounds/custom/recon.

3.4.5 E JECUCIÓN

Una vez instalados y configurados todos los componentes necesarios se debe poner en
marcha todo el sistema. Para ello hay que iniciar los servicios DAHDI y Asterisk (en ese
orden) mediante las siguientes instrucciones:
> service dahdi start
> service asterisk start

Para acceder a la consola propia de Asterisk (CLI) se escribe la siguiente línea en un


terminal:
> asterisk - rvvvvvvvvvvvvvvvv

En la CLI se puede observar el log de las actividades que se producen en Asterisk

56
3.4. C ONFIGURACIONES

en tiempo real, como por ejemplo: logado/deslogado de usuarios en el servidor,


instrucciones ejecutadas en el dialplan, errores producidos, etc.

Después de realizar cualquier cambio en los archivos de configuración se deben


volver a cargar los módulos afectados para que Asterisk opere con la versión más
actual de los mismos. Esto puede hacerse con los comandos adecuados en la consola
CLI o reiniciando el servicio Asterisk desde cualquier terminal.

57
CAPÍTULO 3. I MPLEMENTACIÓN DE LA C ENTRALITA

FIGURA 3.2: Diagrama de flujo de la centralita (Inicio).

58
3.4. C ONFIGURACIONES

FIGURA 3.3: Diagrama de flujo de la extensión 0 de la centralita (Recepción).

59
CAPÍTULO 3. I MPLEMENTACIÓN DE LA C ENTRALITA

FIGURA 3.4: Diagrama de flujo de la extensión 1 de la centralita (Trabajadora Social).

60
3.4. C ONFIGURACIONES

FIGURA 3.5: Diagrama de flujo de la extensión 2 de la centralita (Enfermería).

61
CAPÍTULO 3. I MPLEMENTACIÓN DE LA C ENTRALITA

FIGURA 3.6: Diagrama de flujo de la extensión 3 de la centralita (Dirección).

62
3.4. C ONFIGURACIONES

FIGURA 3.7: Diagrama de flujo de la extensión 4 de la centralita (Psicóloga).

63
CAPÍTULO 3. I MPLEMENTACIÓN DE LA C ENTRALITA

FIGURA 3.8: Diagrama de flujo de la extensión 6 de la centralita (Menú privado).

64
4
Implementación de los Softphones

4.1 O BJETIVO

en la introducción de este documento, uno de los objetivos


C OMO SE HA COMENTADO
del proyecto es la implementación de dos aplicaciones Android para utilizar el
sistema de VoIP implantado en la residencia. Estas aplicaciones son dos softphones:
uno para uso de los residentes y el otro para la recepción del centro. Aunque se
podría utilizar cualquier softphone disponible en el mercado, se decide implementar
aplicaciones propias con el propósito de añadir funcionalidades extras y exclusivas
para los residentes y trabajadores del centro.

A lo largo de este capítulo se irán explicando, en profundidad, los pasos seguidos


para implementar estas aplicaciones y su funcionamiento.

4.2 I NSTALACIÓN Y CONFIGURACIÓN DEL ENTORNO DE


TRABAJO

del proyecto se requiere la instalación y configuración de


P ARA REALIZAR ESTA PARTE
una serie de elementos que se explicarán en este apartado:

* Un entorno de programación adecuado formado por Eclipse, Android SDK y el


plugin ADT, necesarios para la implementación de cualquier aplicación Android.

* Una base de datos en el servidor, para lo que se instala LAMP, y una serie de
scripts PHP que servirán para acceder, consultar y modificar esta base de datos
desde las aplicaciones Android.

65
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

* Unas extensiones especiales en Asterisk que servirán para comunicar las situa-
ciones de emergencia entre los residentes y la recepción. Estas extensiones están
definidas en el dialplan de Asterisk bajo el contexto [android_V A].

4.2.1 D ESARROLLO DE APLICACIONES A NDROID

Para poder implementar cualquier aplicación Android hay que instalar el entorno
de programación y simulación adecuado. Todas las herramientas necesarias para
desarrollar aplicaciones Android son gratuitas (libres) y están disponibles para todas
las plataformas (Linux, Mac, Windows). En este caso se utilizarán las herramientas
recomendadas en Android Developers: Eclipse + Android SDK + ADT.

Eclipse
El primer paso para desarrollar cualquier aplicación es obtener un entorno de de-
sarrollo integrado (IDE). Un IDE es un programa compuesto por un conjunto de
herramientas de programación y normalmente consiste en: un editor de código,
herramientas de compilación y un depurador. En el caso de aplicaciones Android,
el IDE recomendado es Eclipse, un entorno de programación multi-lenguaje con un
extensible sistema de plug-in. La última versión disponible al iniciar este proyecto, y
por tanto la versión instalada, es la Helios.

Android SDK
El SDK1 es un conjunto de herramientas de desarrollo que permite a un programador
crear aplicaciones para un sistema concreto, por ejemplo ciertos paquetes de software,
frameworks, plataformas de hardware, videoconsolas, sistemas operativos, etc. Es
algo tan sencillo como una interfaz de programación de aplicaciones (API) creada
para permitir el uso de cierto lenguaje de programación, o puede, también, incluir
hardware sofisticado para comunicarse con un determinado sistema embedido.

El Android SDK contiene un depurador, librerías, un emulador, documentación,


ejemplos de código y tutoriales. Se puede descargar desde la página web de Android
Developers: http://developer.android.com/sdk/index.html. La versión instalada es
la 14.

ADT
El plug-in ADT2 para Eclipse es una extensión del entorno de desarrollo que permite la
creación y depuración de aplicaciones Android. Gracias a este plugin se puede hacer
1
Kit de Desarrollo de Software
2
Android Development Tools

66
4.2. I NSTALACIÓN Y CONFIGURACIÓN DEL ENTORNO DE TRABAJO

lo siguiente: crear proyectos para aplicaciones Android, acceder a las herramientas de


emuladores Android, compilar y debugar aplicaciones, crear paquetes APK (ejecutables
de Android), crear certificados digitales para firmar los APKs, entre otras cosas. Su
instalación se realiza directamente desde Eclipse.

Una vez instalado esto hay que crear una ADV 3 para poder testear las aplicaciones
que se van a programar. Esta máquina virtual emula el comportamiento de un
smartphone con las características que se le especifiquen. Sin embargo, debido a
la naturaleza de este proyecto, la mayoría de las pruebas se han realizado directa-
mente sobre dispositivos físicos (smartphones con sistema operativo Android 2.3,
Gingerbread).

La guía completa para instalar estos componentes se encuentra en el anexo B.1.

4.2.2 B ASE DE DATOS REMOTA

Se instala una base de datos en el servidor que se utilizará para los sistemas de alerta
de los residentes: de posicionamiento y batería baja. Para crear la base de datos se
instala el paquete LAMP4 en el servidor. Con la idea de facilitar la tarea de creación
y gestión de la base de datos, se instala también el programa MySQL Navigator, que
permite manejar la base de datos mediante una interfaz gráfica.

El acceso desde las aplicaciones Android a esta base de datos se hace de la siguiente
manera: las aplicaciones hacen peticiones HTTP contra Apache, que ejecuta los
script PHP correspondientes, accediendo a la base de datos MySQL y devolviendo los
resultados obtenidos en formato JSON a las aplicaciones.

La instalación del paquete LAMP, y la creación de la base de datos mediante MySQL


Navigator se encuentra en el anexo B.2.1.

4.2.2.1 E STRUCTURA DE LA BASE DE DATOS

Como puede verse en la figura 4.1, la base de datos está formada por dos tablas:
MyAlerts y MyCoordinates.

* MyAlerts: Esta tabla se utiliza para controlar el estado de los residentes. Al dar
3
Android Virtual Machine
4
LAMP: Acrónimo referido a la primera letra de Linux (sistema operativo), Apache HTTP (servi-
dor), MySQL (software de base de datos) y PHP (software de scripting), componentes principales para
construir un web server.

67
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

FIGURA 4.1: Tablas de la base de datos ubicada en el servidor.

de alta a un residente en el sistema, se crea una entrada con el número y nombre


de usuario y dos flags de alerta desactivados. El flag alert_flag se utiliza para
controlar la ubicación del residente: mientras éste permanezca dentro de la zona
permitida, el flag se mantendrá a 0; si sale de dicha zona, el flag cambiará a 1.
Del mismo modo, battery_flag se utiliza para controlar el estado de batería del
dispositivo del residente: si la batería baja del 15%, el flag se pone a 1.

* MyCoordinates: Esta tabla se utiliza para controlar la ubicación de los residentes


que están fuera de la zona permitida. Mientras el residente se encuentre
fuera de esta zona, se van almacenando en la tabla sus coordenadas GPS para
poder localizarlo. Para ello se crean entradas con el número de usuario, y las
coordenadas en formato (latitud, longitud).

4.2.2.2 S CRIPTS PHP

El acceso a la base de datos MySQL se hace mediante scripts PHP. Estos scripts permiten
realizar consultas y/o modificar los atributos de la base de datos desde las aplicaciones
Android.

A continuación se explica la función y utilización de los scripts implementados en


este proyecto, diferenciando los utilizados por cada aplicación. El código de estos
scripts se encuentra en el anexo B.2.2.

Softphone A: residentes

68
4.2. I NSTALACIÓN Y CONFIGURACIÓN DEL ENTORNO DE TRABAJO

insert_alert_user.php , get_alert_user.php , update_alert_user.php ,


delete_alert_user.php
Se utilizan desde la gestión de cuentas de la aplicación y afectan únicamente a la tabla
de alertas MyAlerts. Insertan, borran, o modifican los datos del usuario en la base de
datos (nombre y número de cuenta, únicamente).

update_alert_flag.php
Se utiliza desde el servicio de alertas de localización de la aplicación y afecta
únicamente a la tabla de alertas MyAlerts. Actualiza el valor del flag de alerta de
posicionamiento del usuario que lo ejecuta.

update_battery_flag.php
Se utiliza desde el broadcast receiver de alerta de batería de la aplicación y afecta
únicamente a la tabla de alertas MyAlerts. Actualiza el valor del flag de alerta por
batería baja del usuario que lo ejecuta.

insert_coordinates.php
Se utiliza desde el servicio de alertas de localización de la aplicación y afecta única-
mente a la tabla de coordenadas MyCoordinates. Inserta una coordenada GPS (latitud,
longitud) en la base de datos, indicando el número del usuario al que pertenece.

Softphone B: recepción del centro

get_alert_coordinates.php
Se utiliza desde el mapa de localización de la aplicación y afecta a ambas tablas. Ob-
tiene un listado con todos los residentes que se encuentran en estado de alerta (fuera
de la zona permitida, con alert_flag=1) y la última coordenada GPS introducida por
cada uno de ellos.

get_user_coordinates.php
Se utiliza desde el mapa de localización de la aplicación y afecta a ambas tablas. Ob-
tiene la última coordenada introducida en la base de datos por el usuario especificado.

check_battery_alert.php
Se utiliza desde un servicio de la aplicación y afecta a la tabla de alertas MyAlerts.
Comprueba si hay alguna alerta de batería baja activada (battery_flag=1).

get_battery_alerts.php
Se utiliza desde el listado de alertas de batería de la aplicación y afecta a la tabla de
alertas MyAlerts. Obtiene un listado con todos los residentes que se encuentran en
estado de alerta por batería baja (número y nombre de usuario) ordenados por nombre.

69
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

4.2.3 E XTENSIONES DE EMERGENCIA EN A STERISK

Como se ha explicado en la introducción, se utilizan unas extensiones especiales


en el servidor SIP para avisar a las aplicaciones de que deben iniciar una serie de
acciones. Estas extensiones están definidas en el dialplan de Asterisk bajo el contexto
[android_V A].

Las aplicaciones de los residentes y la recepción se comunican entre ellas (de forma
interna) mediante llamadas perdidas a estas extensiones especiales, de forma invisible
a los usuarios. Para ello se lanzan o reciben llamadas procedentes de estas extensiones,
marcadas como de emergencia, que se deben procesar de forma diferente al resto, ya
que se utilizarán como disparador para que las aplicaciones ejecuten ciertas acciones.
La utilidad de éstas se explicará con más detalle para cada aplicación en los siguientes
apartados.

* Extensión 033: Alerta de localización. Esta extensión se marca automática-


mente desde el softphone de un residente al salir/entrar de la zona permitida. Se
origina entonces una llamada entre la recepción y el llamante, informando a la
recepción, al descolgar, del número de usuario del residente que ha generado la
alerta.
* Extensión 034: Petición de inicio de seguimiento. Esta extensión se marca
automáticamente desde el softphone de recepción al solicitarse el seguimiento
de la ubicación de un residente. Esto genera una llamada perdida al usuario
pertinente, que empezará a enviar sus coordenadas de posición a la base de datos.
* Extensión 035: Petición de finalización de seguimiento. Esta extensión
se marca automáticamente desde el softphone de recepción al solicitarse la
finalización del seguimiento de un residente. Opera de la misma forma que la
anterior, generando una llamada perdida al usuario pertinente, que en este caso
detendrá el envío de coordenadas a la base de datos.

La definición de estas extensiones se encuentra detallado en el anexo B.3.

4.3 D ESARROLLO DE LAS APLICACIONES

consisten en dos softphones: uno para los residentes y


L AS APLICACIONES FINALES
otro para la recepción del centro, que también pueden utilizar los trabajadores del

70
4.3. D ESARROLLO DE LAS APLICACIONES

mismo.

Primero se ha desarrollado un softphone básico, con unas prestaciones que


cualquier softphone en el mercado puede ofrecer: realizar y recibir llamadas, listado
de cuentas y contactos, registro de llamadas, etc. Aunque esta aplicación también
puede instalarse en un terminal, se ha declarado como librería para facilitar la herencia
en las otras dos aplicaciones.

Las otras aplicaciones heredan de este softphone básico, añadiendo funcionalidades


y características diferentes para cada una de ellas:

* Softphone A: destinado para el uso de los residentes del centro. Añade dos fun-
cionalidades: sistema de alerta en caso de batería baja y sistema de alerta en
caso de que el residente salga de una zona permitida (se aleje demasiado de la
residencia) utilizando el sensor GPS del dispositivo físico.

* Softphone B: destinado para el uso de la recepción del centro. Añade tres


funcionalidades: mapa con la ubicación de los residentes que estén fuera de la
zona permitida, petición de seguimiento de cualquier residente (ubicación del
residente) y comprobación de alertas por batería baja en los softphones de los
residentes.

La interacción entre las dos aplicaciones se realiza mediante las extensiones de


emergencia de Asterisk y la base de datos remota (ubicada en el servidor). Estas dos
aplicaciones acceden y modifican el contenido de esta base datos para los eventos
relacionados con las alertas de posicionamiento y batería.

A continuación se ofrece una explicación más detallada de la estructura y el


funcionamiento de estas aplicaciones, con ejemplos de código cuando sea relevante.

4.3.1 S OFTPHONE BÁSICO

La primera aplicación desarrollada, llamada LDDSoftphoneLibrary, consiste en un


softphone básico. Esta aplicación tiene el funcionamiento de un softphone con
prestaciones muy básicas: recepción y emisión de llamadas VoIP, agenda de contactos,
lista de cuentas SIP (clientes SIP) con las que poder logarse en el servidor de VoIP
y listado de registro de llamadas. En el transcurso de una llamada se dispone de:
función de altavoz y acceso a un teclado para mandar códigos DTMF (por ejemplo,
para el buzón de voz).

71
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

FIGURA 4.2: Menú tab de la aplicación con: a) Pantalla principal de la aplicación. b)


Lista de contactos. c) Registro de llamadas.

Los datos de la agenda de contactos y la lista de cuentas SIP se guardan en una


base de datos interna (en el dispositivo físico). También se guardan en ella los datos
de las llamadas del registro de llamadas. Esta base de datos, de tipo SQLite, es propia
de cada aplicación y por tanto no se puede acceder a ella desde otras aplicaciones.
Su acceso, así como todas las peticiones que se pueden realizar sobre ella, se han
encapsulado en una clase llamada DBAdapter, facilitando así el acceso desde cualquier
clase de la aplicación que lo requiera.

El aspecto que presenta la aplicación al iniciarla se puede observar en la


figura 4.2(a). Como se aprecia en dicha figura, la pantalla principal consta de un menú
tipo TAB con tres pestañas. Estos menús tienen la siguiente apariencia: una barra con
pestañas en la parte superior de la pantalla y en el resto, una zona donde aparece la
actividad relativa a cada pestaña. En la primera aparece el teclado que permite realizar
llamadas una vez logados en el servidor de VoIP. La segunda, en la figura 4.2(b),
muestra un listado de todos los contactos que hay guardados en la aplicación, con la
posibilidad de realizar una marcación directa al pulsar sobre cada uno de ellos. En la
tercera se encuentra el registro de llamadas, donde se muestran los datos de todas las
llamadas realizadas y recibidas: número llamante, número llamado, tipo de llamada

72
4.3. D ESARROLLO DE LAS APLICACIONES

FIGURA 4.3: a) Menú principal de la aplicación para los residentes. b) Diálogo que
aparece al cerrar las aplicaciones.

(entrante, saliente, perdida), fecha, hora y duración de la llamada, como se puede ver
en la figura 4.2(c). Al pulsar sobre una llamada del registro, se ofrece la posibilidad de
rellamar o devolver una llamada a ese número de forma directa (sin tener que marcar).

Como se puede ver en la figura 4.3(a), el menú de la pantalla principal permite:


acceder al listado de cuentas SIP, añadir un nuevo contacto y cerrar la aplicación. La
aplicación puede cerrarse de dos formas: mediante la tecla BACK del dispositivo o
mediante la opción Cerrar del menú. La primera opción permite seguir recibiendo
llamadas SIP aunque la aplicación no sea visible en pantalla. La segunda, en cambio,
cierra por completo la aplicación y por tanto no se pueden recibir llamadas. Por eso,
al cerrar la aplicación desde el menú, se muestra al usuario un diálogo de advertencia
informándole de este hecho (figura 4.3(b)).

La lista de cuentas aparece en la figura 4.4(a) y muestra los datos de las cuentas
SIP (número y nombre) que el usuario puede utilizar para registrarse en el servidor
de VoIP. Los datos que se guardan para cada cuenta son: número y nombre de
usuario, dirección del servidor de VoIP y contraseña requerida por el servidor para
logarse. Desde esta pantalla pueden crearse cuentas nuevas, así como modificar o

73
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

FIGURA 4.4: a) Listado de cuentas con menú abierto. b) Menú context de una cuenta
(opciones de la cuenta).

eliminar los datos de las ya existentes. La aplicación está programada para logarse
automáticamente en el servidor con la última cuenta que se utilizó, por lo que si el
usuario desea cambiar de cliente SIP (cambiar la cuenta activa), debe hacerlo desde
esta pantalla, mediante el menú context de la figura 4.4(b).

Al realizar o recibir una llamada, aparecerá en el dispositivo la pantalla de la


figura 4.5, donde se muestra el número o identificador del llamante/llamado y varios
botones que permiten: descolgar/colgar la llamada, activar/desactivar la función de
altavoz y acceder a un teclado para poder introducir tonos DTMF durante la llamada,
permitiendo al usuario interactuar con el servidor, por ejemplo, para navegar por el
buzón de voz. La aplicación utiliza el sensor de proximidad del terminal físico para
bloquear y apagar la pantalla si ésta se acerca demasiado a la cara. Este mecanismo se
utiliza para evitar tocar los botones de la pantalla con la cara o la oreja durante una
llamada.

Las notificaciones son muy importantes en esta aplicación, ya que informan al


usuario del estado del softphone y de las posibles incidencias relacionadas con el
servidor SIP, permitiendo la interacción del mismo para solventarlas. Al abrir la apli-

74
4.3. D ESARROLLO DE LAS APLICACIONES

FIGURA 4.5: Pantalla mostrada durante las llamadas en las aplicaciones.

cación, aparece una notificación en la barra de estado con el nombre de la aplicación


LDDSoftphone y la cuenta con la que se ha logado el terminal al servidor SIP (cuenta
activa). Esta notificación es permanente y sólo desaparece al cerrarse la aplicación
mediante la opción Cerrar del menú principal. Si no hay una cuenta activa (no se ha
podido logar en el servidor SIP o no existen los datos de esa cuenta), se informa al
usuario mediante otra notificación que le permite ir directamente al listado de cuentas
para realizar las modificaciones pertinentes. También aparece una notificación para
informar al usuario de que tiene llamadas perdidas, con acceso directo al registro de
llamadas para poder comprobarlas.

4.3.1.1 I NTEGRACIÓN DE LA V O IP EN LA APLICACIÓN

La integración de la VoIP en la aplicación se consigue gracias a la utilización de la API


SIP nativa de Android. Esta API se encuentra disponible en todas las versiones a partir
de la 2.3 (Gingerbread). Su integración permite añadir características de telefonía
VoIP basada en el protocolo SIP en los softphones desarrollados. De esta forma, se
puede utilizar para establecer llamadas de voz entrantes y salientes de forma sencilla,
sin tener que manejar sesiones ni comunicaciones a nivel de transporte.

En la tabla 4.1 se puede ver un resumen de las clases y la interfaz incluidas en la

75
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

TABLA 4.1: Clases e interfaz incluidos en la API SIP de Android.

Clase / Interfaz Descripción


SipAudioCall Maneja las llamadas SIP.
SipAudioCall.Listener Listener para eventos relacionados con llamadas SIP.
SipErrorCode Define códigos de error retornados durante acciones SIP.
SipManager Proporciona APIs para tareas SIP, como iniciar conexiones
SIP, y proporciona acceso a servicios SIP relacionados.
SipProfile Define un perfil SIP, incluyendo información de una cuenta
SIP, dominio y servidor.
SipProfile.Builder Clase de ayuda para crear un SipProfile.
SipSession Representa una sesión SIP asociada a una diálogo SIP o a
una transacción independiente fuera del diálogo.
SipSession.Listener Listener para eventos relacionados con sesiones SIP.
SipSession.State Define estados de la sesión SIP.
SipRegistrationListener Interface, listener para eventos del registro SIP.

API SIP de Android.

Para integrar esta API en las aplicaciones desarrolladas se crean tres clases que se
encargarán de lo siguiente:
* ServiceSIP: servicio que se encarga de casi todo lo relacionado con la API SIP.
* CallReceiverSIP: broadcast receiver que maneja las llamadas SIP entrantes.
* ServiceBinder: clase de ayuda que actúa como puente entre el servicio ServiceSIP
y el resto de clases de la aplicación.

A continuación se explica el desarrollo y funcionamiento de estas clases más


detalladamente.

4.3.1.1.1 S ERVICE SIP


Este servicio es el alma de la aplicación y la clase más importante de la misma. En
él se encuentra todo el código relacionado con la API SIP de Android y contiene, por
tanto, todos los métodos que permiten a la aplicación interactuar con el servidor SIP.
Sus funciones principales son: registrar/desregistrar una cuenta SIP en el servidor y
realizar llamadas. Las clases de la aplicación que necesiten interactuar con el servidor
SIP (para realizar/colgar llamadas, logar/deslogar un cliente SIP, etc.) pueden hacerlo
a través de este servicio mediante la clase ServiceBinder.

76
4.3. D ESARROLLO DE LAS APLICACIONES

El servicio ServiceSIP se lanza al abrir la aplicación y no se detiene hasta que el


usuario sale de la misma mediante la opción Cerrar del menú principal. Si se sale de la
aplicación con la tecla BACK, el servicio sigue activo, ya que se deben seguir recibiendo
llamadas SIP y eventos relacionados con la aplicación aunque ésta no esté visible en la
pantalla del dispositivo.

Lo primero que se hace al crearse el servicio es especificar el broadcast receiver que


se encargará de recibir las llamadas entrantes (CallReceiverSIP, en este caso), cuyo
funcionamiento se explicará más adelante.
protected void prepareReceiver () {
/* * se especifica un IntentFilter que se encargara de lanzar el
broadcast receiver CallReceiverSIP al interceptar el aviso de
recepcion de una llamada entrante */
IntentFilter filter = new IntentFilter () ;
filter . addAction ( " softphone . LDD . INCOMING_CALL " ) ;
callReceiver = new CallReceiverSIP () ;
this . registerReceiver ( callReceiver , filter ) ;
}

Al iniciar el servicio por primera vez, se crea un objeto de tipo SipManager, propio
de la API SIP de Android y se registra la cuenta de usuario (cliente SIP) que se va a
utilizar para logarse en el servidor SIP. A través de este objeto se podrán realizar las
siguientes acciones: iniciar sesiones SIP, realizar y recibir llamadas, registrar/desregis-
trar cuentas SIP en el servidor y verificar la conectividad de la sesión.

Para registrar la cuenta de usuario SIP en el servidor se utiliza el método


initiateLocalProfile, cuyas variables de entrada son los datos de la cuenta (nombre
o número, dirección del servidor y contraseña de acceso). Al iniciar la aplicación,
se intenta recuperar la información de la última cuenta utilizada para registrarse de
nuevo. Si no es posible, se muestra la notificación de la figura 4.6(a) para informar al
usuario de que no hay cuenta activa y no se ejecuta este método. Hasta que el usuario
no especifique una cuenta válida para registrarse en el servidor SIP, la aplicación no
podrá enviar ni recibir llamadas SIP.

Al utilizar la API SIP, cada cuenta SIP está representada por un objeto de tipo
SipProfile. Por tanto, para registrar una cuenta, primero se crea el objeto SipProfile
con los datos de las variables de entrada.
SipProfile . Builder builder = new SipProfile . Builder ( username , domain ) ;
builder . setPassword ( password ) ;
me = builder . build () ;

A continuación, se habilita el perfil creado (se da la orden de registro de la cuenta en


el servidor) para que se puedan enviar/recibir llamadas SIP, especificando de nuevo,

77
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

FIGURA 4.6: a) Notificación que aparece cuando no hay ninguna cuenta activa. b)
Notificación permanente que aparece cuando hay una cuenta logada en el servidor SIP.

mediante el pending intent (pi), el broadcast receiver que se encargará de recibir las
llamadas entrantes.
manager . open ( me , pi , null ) ;

Finalmente, se crea un listener que se encargará de manejar los eventos relacionados


con el registro del cliente SIP en el servidor.
manager . setRegistrationListener ( me . getUriString () , new
SipRegistrationListener () {
public void onRegistering ( String localProfileUri ) {
// Noop .
}
public void onRegistrationDone ( String localProfileUri , long
expiryTime ) {
/* * al registrarse la cuenta en el servidor SIP , se cancela la
notificacion de error de registro y se envia la notificacion de
cuenta activa */
NM . cancelFalloRegistro () ;
NM . showNotificationCuentaActiva ( me . getUserName () + " @ " +
me . getSipDomain () ) ;
}

78
4.3. D ESARROLLO DE LAS APLICACIONES

FIGURA 4.7: a) Notificación que aparece al no poder registrar la cuenta especificada


en el servidor SIP. b) Notificación que indica la existencia de llamadas perdidas.

public void onRegistrationFailed ( String localProfileUri , int


errorCode , String errorMessage ) {
/* * si no se puede registrar la cuenta , se envia una notificacion
de cuenta incorrecta para informar al usuario */
if ( errorCode != -4) {
NM . showNotificationFalloRegistro ( me . getUserName () + " @ " +
me . getSipDomain () ) ;
}
}
}) ;

Si se ha realizado el registro de la cuenta de forma satisfactoria en el servidor


SIP, se actualiza la notificación permanente en la barra de estado con los datos
(número@servidor) de la cuenta activa, como se puede ver en la figura 4.6(b). A
partir de este momento, la aplicación está lista para poder enviar/recibir llamadas SIP.
En caso de no poderse registrar (porque no se dispone de conectividad con el servidor
SIP, la cuenta es incorrecta, etc.), se informa al usuario mediante la notificación de la
figura 4.7(a) para que pueda solventar el problema.

Si ya no se desea utilizar más el perfil actual (se quiere cambiar de cuenta activa

79
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

o se cierra la aplicación), se utiliza el método closeLocalProfile para deslogarse del


servidor. Si no se está cerrando la aplicación, se muestra una notificación para informar
al usuario de que no hay ninguna cuenta logada en el servidor (figura 4.6(a)) y desde
ese momento no se pueden enviar ni recibir llamadas SIP en la aplicación.

public void closeLocalProfile () {


/* * cancela la notificacion de cuenta activa */
NM . cancelCuentaActiva () ;
/* * si no se esta parando el servicio , informa al usuario de que
no hay cuenta activa */
if (! isOnDestroy ) {
NM . showNotificationNoHayCuenta () ;
}
/* * si no existe el manager , no hace nada */
if ( manager == null ) {
return ;
}
try {
/* * desloga la cuenta SIP */
if ( me != null ) {
manager . close ( me . getUriString () ) ;
}
} catch ( Exception ee ) {
Log . d ( " ServiceSIP / onDestroy " , " Failed to close local
profile . " , ee ) ;
}
}

Como se ha comentado anteriormente, en este servicio se encuentran todos los


métodos relacionados con la API SIP de Android, que el resto de clases de la aplicación
utilizan para realizar distintas acciones como: realizar/colgar una llamada SIP,
activar/desactivar el altavoz del dispositivo durante una llamada, enviar tonos DTMF
e introducir una llamada en el registro de llamadas. De estos métodos se destacan
los dos más importantes: realizar una llamada SIP y crear una nueva entrada en el
registro de llamadas.

Para realizar una llamada SIP se utiliza el método initiateCall:


/* * Realiza una llamada saliente a la direccion especificada por
sipAddress * */
public void initiateCall ( String sipAddress ) {
try {
/* * Listener para eventos relacionados con la llamada SIP
saliente */
SipAudioCall . Listener listener = new SipAudioCall . Listener () {
/* * se ejecuta al establecer la llamada */
@Override

80
4.3. D ESARROLLO DE LAS APLICACIONES

public void onCallEstablished ( SipAudioCall call ) {


time_ini = SystemClock . uptimeMillis () ;
date = new SimpleDateFormat ( " HH : mm
dd / MM / yy " ) . format ( new Date () ) ;
call . startAudio () ;
call . setSpeakerMode ( false ) ;
}
/* * se ejecuta cuando el otro extremo finaliza la llamada */
@Override
public void onCallEnded ( SipAudioCall call ) {
time_end = SystemClock . uptimeMillis () ;
sendBroadcast ( new Intent ( Const . CALL_ENDED ) ) ;
}
};
/* * se realiza la llamada SIP */
call = manager . makeAudioCall ( me . getUriString () , sipAddress ,
listener , 30) ;
}
catch ( Exception e ) {
Log . i ( " ServiceSIP / InitiateCall " , " Error when trying to
close manager . " , e ) ;
if ( me != null ) {
try {
/* * desloga la cuenta SIP */
manager . close ( me . getUriString () ) ;
} catch ( Exception ee ) {
Log . i ( " ServiceSIP / InitiateCall " , " Error when
trying to close manager . " , ee ) ;
ee . printStackTrace () ;
}
}
/* * si hay una llamada en curso , la cierra */
if ( call != null ) {
call . close () ;
}
}
}

Para ejecutar este método se necesitan tres cosas: un SipProfile local registrado
(cuenta activa del softphone logada correctamente al servidor SIP), una dirección SIP
válida para recibir la llamada y un objeto de tipo SipManager.

Primero se crea un listener de tipo SipAudioCall.Listener que se encarga de


monitorizar y manejar los eventos relacionados con la llamada SIP saliente. Como se
verá más adelante, el listener encargado de las llamadas entrantes se encuentra en el
broadcast receiver CallReceiverSIP. En este listener se define el comportamiento de
la aplicación al establecer y colgar la llamada. Al establecerse la llamada, se guardan

81
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

datos para el registro de llamadas (tiempo de inicio y fecha) y a continuación se activa


el audio de la llamada. Al colgarse la llamada, se guarda el tiempo de finalización de
la llamada y se lanza el broadcast que activará el registro de la llamada.

Una vez definido el listener, se realiza la llamada mediante el método makeAudioCall


del objeto SipManager, utilizando los siguientes parámetros: perfil local SIP (cuenta
llamante), dirección SIP del llamado, listener definido antes y timeout en segundos.
call = manager . makeAudioCall ( me . getUriString () , sipAddress , listener ,30) ;

Al finalizar cualquier llamada (tanto entrantes, salientes o perdidas) se ejecuta el


método entradaRegistro que se encarga de añadir una nueva entrada al registro de
llamadas en la base de datos local. En esta tabla se guardan, para cada llamada, los
siguientes datos: tipo de llamada (saliente, entrante, perdida), número de cliente
SIP llamante, número de cliente SIP llamado, fecha y hora de inicio y duración de la
llamada. Si se trata de una llamada perdida, se muestra una notificación en la barra
de estado para informar al usuario, como se puede ver en la figura 4.7(b).

El servicio ServiceSIP se detiene al salir de la aplicación mediante la opción Cerrar


del menú principal. En este caso deben realizarse una serie de acciones para asegurarse
de que se corta todo contacto con el servidor SIP: se desloga la cuenta SIP activa del
servidor, se desactiva el broadcast receiver (para que no se puedan recibir llamadas) y
se cancelan todas las notificaciones que estén activas en la barra de estado.
/* * se ejecuta al cerrar el servicio */
@Override
public void onDestroy () {
Toast . makeText ( this , R . string . local_service_stopped ,
Toast . LENGTH_SHORT ) . show () ;
/* * si hay una llamada en curso , la finaliza */
if ( call != null ) {
call . close () ;
}
/* * desloga al usuario del servidor SIP */
isOnDestroy = true ;
closeLocalProfile () ;
/* * desregistra el broadcast receiver de las llamadas entrantes */
if ( callReceiver != null ) {
this . unregisterReceiver ( callReceiver ) ;
}
/* * cancela todas las notificaciones activas */
NM . cancelAll () ;
hasStarted = false ;
super . onDestroy () ;
}

82
4.3. D ESARROLLO DE LAS APLICACIONES

4.3.1.1.2 C ALL R ECEIVER SIP


Como se ha visto en el apartado anterior, el servicio ServiceSIP sirve para preparar
la aplicación para utilizar SIP, realizar llamadas salientes y manejar las llamadas
en curso. Para recibir llamadas entrantes, se crea este broadcast receiver, que se
ejecuta de manera automática cada vez que el terminal recibe una llamada SIP.
CallReceiverSIP procesa todas las llamadas SIP entrantes, las recoge y las cede
a la actividad CallDisplay, que se encarga de manejarlas mediante los métodos
contenidos en el servicio ServiceSIP.

De forma análoga al caso de la generación de una llamada saliente, lo primero que


se hace es definir un listener de tipo SipAudioCall.Listener que se encarga de moni-
torizar y manejar los eventos relacionados con la llamada SIP entrante. En este caso
sólo es necesario definir el comportamiento al colgar la llamada: se envía el broadcast
para añadir la llamada finalizada al registro de llamadas, si procede.
/* * Listener para eventos relacionados con la llamada SIP entrante */
listener = new SipAudioCall . Listener () {
/* * se ejecuta al entrar una nueva llamada */
@Override
public void onRinging ( SipAudioCall call , SipProfile caller ) {
try {
// Noop .
} catch ( Exception e ) {
e . printStackTrace () ;
}
}
/* * se ejecuta al finalizar la llamada entrante */
public void onCallEnded ( SipAudioCall call ) {
/* * si la linea no esta ocupada , se registra y finaliza la
llamada */
if (! noRegister ) {
setEndingTime () ;
} else {
noRegister = false ;
}
}
};

A continuación se recoge la llamada mediante el método takeAudioCall del objeto


SipManager, utilizando los siguientes parámetros: intent perteneciente a la llamada en-
trante y listener definido antes. Como los broadcast receivers no pueden conectarse a los
servicios mediantes binders, para poder recoger la llamada se utiliza el objeto sipService,
que es de tipo ServiceSIP y que hace referencia al servicio que está corriendo en el
terminal. Se debe aclarar que recoger la llamada no implica descolgarla. Esto sólo
significa que la llamada ha llegado al terminal y que en el otro extremo ya se recibe
tono.

83
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

incomingCall = sipService . manager . takeAudioCall ( intent , listener ) ;

Una vez recogida, se pasa la llamada al servicio, se obtiene el identificador de lla-


mada y se lanza la actividad CallDisplay, cuya pantalla es la que permitirá al usuario
interactuar con la llamada entrante (colgar/descolgar la llamada, activar/desactivar
altavoz, etc.). Esta pantalla es la mostrada en la figura 4.5.

La aplicación está programada de manera que sólo se puede llevar a cabo una
conversación a la vez. Si se recibe una nueva llamada entrante cuando ya hay una en
curso, la nueva llamada se cuelga automáticamente (desviando al llamante al buzón
de voz correspondiente) y no se refleja en el registro de llamadas.

4.3.1.1.3 S ERVICE B INDER


Como se ha comentado en la explicación de ServiceSIP, la mayoría de los métodos
declarados en este servicio se utilizan desde otras clases de la aplicación. Esto es
posible mediante la utilización de binders, que permiten a las clases conectarse con el
servicio e interactuar con él, pudiendo así utilizar sus métodos, como: realizar una
llamada, colgar/descolgar, logar/deslogar una cuenta SIP, etc.

Con este fin se crea la clase de ayuda ServiceBinder, que actúa como clase
intermedia y se encarga de crear el enlace (bind) entre el servicio y la clase que lo
necesite. Por otra parte, algunas clases necesitan realizar ciertas acciones una vez
establecida la conexión con el servicio (por ejemplo, realizar una llamada). Estas
acciones se definen también en esta clase, evitando así que se intente acceder al
servicio antes de que se haya realizado el enlace.

4.3.2 S OFTPHONE PARA RESIDENTES

La aplicación LDDSoftphoneA está desarrollada específicamente para su utilización por


parte de los residentes del centro. Su funcionamiento base es el mismo que el del
softphone básico, con las siguientes características añadidas:

* Por motivos de seguridad, se quiere evitar que los residentes se alejen demasiado
del centro. Para ello se crea un sistema de alertas que utiliza el sensor GPS del
terminal físico para determinar la ubicación del usuario y alertar a la residencia
si éste sale de una zona concreta.

* También se quiere evitar que los residentes se queden sin batería en el terminal,
dejando totalmente inutilizado el sistema de alertas anterior. Por ese motivo se
crea también un mecanismo para que los trabajadores de la residencia puedan

84
4.3. D ESARROLLO DE LAS APLICACIONES

FIGURA 4.8: Listado de cuentas con acceso protegido por contraseña.

saber si el nivel de batería del terminal de un residente desciende del 15%.

Los cambios de estado de los residentes (alertas activadas/desactivadas) así como


las coordenadas de posicionamiento se guardan en la base de datos remota. El acceso
a esta base de datos así como todas las peticiones que se pueden realizar sobre ella
se han encapsulado en una clase llamada DBRemoteHelperA, facilitando así el acceso
desde cualquier clase de la aplicación que lo requiera.

Cada residente tiene una entrada en la tabla de alertas (MyAlerts) que se crea, de
forma automática, al asignarle una cuenta SIP en el listado de cuentas de la aplicación.
A partir de ese momento, se puede monitorizar al usuario del terminal. Cada cambio
que se realice sobre el listado de cuentas (añadir, editar o borrar una cuenta) queda
reflejado también en la base de datos remota. Por ese motivo, el acceso al listado
de cuentas de esta aplicación está protegido por contraseña, de forma que sólo los
trabajadores del centro pueden acceder a ella, como se puede ver en la figura 4.8. Así
se evita que los residentes puedan realizar cualquier modificación sobre las cuentas
SIP (como cambiar la cuenta con la que están logados o eliminarla). De esta forma, se
evita también que puedan modificar los datos relativos a la cuenta (nombre y número)
que constan en la base de datos remota y que sirven a los trabajadores del centro para
identificarlos.

85
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

4.3.2.1 A LERTAS DE BATERÍA

El sistema Android genera dos eventos relacionados con el nivel de batería del
terminal: cuando la batería está baja (por debajo del 15%) y cuando la batería se
encuentra en proceso de carga (cargando y por encima del 20% de su capacidad). En
esta aplicación se capturan estos eventos y se actúa acorde a la situación, evitando así
que la aplicación tenga que monitorizar el nivel de batería del dispositivo de forma
continua, lo que resulta ineficiente.

Con este objetivo, se crea BatteryLevelReceiver, un broadcast receiver que se


encargará de manejar las alertas de batería generadas por el propio terminal. Para
que la aplicación sea capaz de capturar estos eventos, se define el broadcast receiver
en el AndroidManifest de la siguiente manera, indicando el nombre de los even-
tos a recoger (BATTERY_LOW, BATTERY_OK) y la clase que se encargará de manejarlos
(BatteryLevelReceiver).
< receiver
android:name = " . battery . BatteryLevelReceiver " >
< intent - filter >
< action android:name = " android . intent . action . BATTERY_LOW " / >
< action android:name = " android . intent . action . BATTERY_OKAY " / >
</ intent - filter >
</ receiver >

Cuando se produce una alerta de batería (batería baja / en proceso de carga),


se activa/desactiva el flag correspondiente al residente en la base de datos remota
(battery_flag). Como estos eventos son generados por el sistema y, por tanto, pueden
ocurrir cuando la aplicación esté cerrada, se comprueba si hay conectividad a la red
(tanto por WiFi como por datos) antes de acceder a la base de datos.

4.3.2.2 A LERTAS DE POSICIONAMIENTO

Esta aplicación está diseñada para utilizar el sensor GPS del terminal físico donde está
instalada para controlar la ubicación de su usuario (en este caso, el residente) y evitar
así que éste salga de una zona marcada como segura o permitida. También se añade
la opción de monitorizar la ubicación de un residente en el interior de esta zona de
manera temporal, referido en este documento como seguimiento. Los pasos seguidos
para lograr esto se detallan a continuación.

Para poner en marcha las alertas de posicionamiento ha sido necesario modi-


ficar parte del softphone básico así como añadir un nuevo servicio a la aplicación,

86
4.3. D ESARROLLO DE LAS APLICACIONES

AlertsService, que se encarga de manejar las alertas de posicionamiento y que se


explicará más adelante.

El sistema Android proporciona una serie de herramientas de localización que se


utilizan en este caso para monitorizar la posición del usuario de la aplicación y activar
las alertas de posicionamiento cuando convenga. Estas alertas, que permiten saber si
el usuario entra/sale de la zona permitida, se activan mediante este método, que se
ejecuta al iniciarse la aplicación:
private void alertasGPS () {
/* * inicializa el objeto que se encargara de monitorizar las
coordenadas GPS */
lm = ( LocationManager ) getSystemService ( Context . LOCATION_SERVICE ) ;
/* * especifica el servicio que se lanzara al recibir una alerta
( AlertsService ) */
AlertsPendIntent = PendingIntent . getService ( this , 0 , new
Intent ( MainLDDSoftphoneA . this , AlertsService . class ) , 0) ;
/* * activa el localizador que lanzara una alerta de proximidad al
salir / entrar de la zona especificada */
lm . addProximityAlert ( ConstA . res_latitude , ConstA . res_longitude ,
ConstA . radio , -1 , AlertsPendIntent ) ;
}

El objeto LocationManager se encarga de monitorizar las coordenadas GPS del


terminal. Para activar las alertas se utiliza el método addProximityAlert, que genera
una alerta de proximidad al salir/entrar el usuario de la zona especificada por los
siguientes parámetros: latitud y longitud (punto central), radio que delimita la zona
alrededor del punto central, duración de la alerta (siempre encendida) y clase que
manejará la alerta (AlertsService). En este caso, las coordenadas (latitud, longitud)
pertenecen a las coordenadas de la residencia y el radio está definido en unos 100
metros (aunque al no disponer de conexión de datos en el terminal de prueba, el radio
utilizado es de sólo 10 metros). Al cerrar la aplicación se eliminan estas alertas de
proximidad para que no se activen una vez cerrada.

Las peticiones de seguimiento, que también maneja el servicio AlertsService,


se reciben en esta aplicación a través de llamadas procedentes de las extensiones de
seguimiento de Asterisk. El encargado de lanzar el servicio en este caso, por tanto, es
el broadcast receiver que maneja las llamadas entrantes y hay que modificarlo para que
trate de forma diferente este tipo de llamadas. Si el identificador de la llamada recibida
pertenece a una de las extensiones de seguimiento de Asterisk definidas anteriormente
(034 o 035), se inicia/detiene el protocolo de seguimiento. Estas llamadas deben pasar
desapercibidas por el usuario del terminal, por tanto, ni se descuelgan ni se registran.

Para iniciar/detener el protocolo de seguimiento del usuario cuyo terminal recibe

87
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

la llamada, se utiliza el siguiente método que, análogamente, inicia/detiene el servicio


AlertsService en modo seguimiento:
private void seguimiento ( String callerID ) {
if ( callerID . equals ( " 034 " ) ) {
/* * se inicia el servicio AlertsService en modo seguimiento */
Intent i = new Intent ( contexto , AlertsService . class ) ;
contexto . startService ( i ) ;
} else {
/* * se para el servicio AlertsService */
contexto . stopService ( new Intent ( contexto ,
AlertsService . class ) ) ;
}
}

Por último, también se realizan modificaciones en el servicio ServiceSIP,


concretamente, se añaden dos métodos nuevos que se utilizarán desde el servicio
AlertsService. El método initiateLostCall realiza una llamada perdida a la extensión
de emergencia de Asterisk (033, alerta de localización) para notificar a la recepción
del centro que ha habido un evento (entrada/salida de la zona permitida). Este tipo
de llamadas se realizan de forma automática, sin conocimiento por parte del usuario
del terminal y, por tanto, no aparecen en el registro de llamadas. El método whoAmI
se usa para obtener el número de usuario de la cuenta SIP con la que está logado el
residente al servidor SIP.

4.3.2.2.1 A LERTS S ERVICE


El servicio AlertsService es la clase más importante de esta aplicación y se encarga
de manejar las alertas de posicionamiento y las peticiones de seguimiento de los
residentes por parte de la recepción del centro.

Este servicio se lanza al producirse una de estas dos situaciones: al generarse una
alerta de proximidad (entrada/salida del terminal del residente de la zona permitida);
al recibirse una llamada desde una de las extensiones de seguimiento de Asterisk
(034, inicio de seguimiento). Al iniciarse el servicio, se comprueba desde dónde se ha
ejecutado la llamada (cuál de estas situaciones ha ocurrido) y se actúa en consecuencia.

Para diferenciar entre estas situaciones, se utiliza el parámetro extra contenido en


el objeto intent que se le pasa al servicio, de forma automática, al iniciarlo. Al pro-
ducirse una alerta de localización, se inicia este servicio añadiendo un extra. Este ex-
tra es un booleano (LocationManager.KEY_PROXIMITY_ENTERING) que toma diferente
valor en función de si se ha producido una entrada (true) o una salida (false) de la zona
permitida. En caso de haberse solicitado un seguimiento, este extra no existe.

88
4.3. D ESARROLLO DE LAS APLICACIONES

private void getIntentExtras ( Intent intent ) {


Bundle extras = intent . getExtras () ;
if ( extras != null ) {
/* * se ha producido una alerta de proximidad */
isEntering =
extras . getBoolean ( LocationManager . KEY_PROXIMITY_ENTERING ) ;
seguimiento = false ;
} else {
/* * se ha solicitado un seguimiento */
seguimiento = true ;
}
}

El siguiente paso es definir la forma de actuar del sistema en función del tipo de
alerta (entrada/salida o seguimiento) y del estado anterior del servicio. Esto último
se tiene en cuenta a fin de corregir los errores derivados de la utilización de las
coordenadas GPS obtenidas del dispositivo, que pueden generar varias alertas del
mismo tipo seguidas, debiendo actuar sólo la primera vez e ignorando las siguientes.

Alertas generadas por una alerta de proximidad (entrada/salida de la zona permitida)

Si el residente sale de la zona permitida (y este servicio no está corriendo ya), se


prepara el servicio para que monitorice los cambios de posicionamiento del dispositivo.
Como se ha comentado anteriormente, la obtención de las coordenadas GPS del termi-
nal se realiza mediante un objeto de tipo LocationManager. Este objeto dispone de un
método (requestLocationUpdates) que permite realizar acciones siempre que se produz-
can cambios de posicionamiento definidos con los siguientes parámetros: proveedor de
localización (GPS), intervalo mínimo entre notificaciones en milisegundos (30.000) y
metros (5) y listener para gestionar los eventos (locListener).
/* * se ejecuta si se sale de la zona permitida y el servicio no esta
corriendo ya o si se ha solicitado un seguimiento */
private void checkExitingZone () {
if (! isEntering & ! isAlreadyOn ) {
/* * crea el enlace con el servicio ServiceSIPA */
doBindService () ;
/* * inicializa el objeto que sirve para obtener las
coordenadas de localizacion */
lm = ( LocationManager )
getSystemService ( Context . LOCATION_SERVICE ) ;
/* * crea el listener que nos servira para monitorizar los
cambios de posicionamiento y definir la actuacion */
locListener = new MyLocationListener () ;
/* * se usa este metodo para que se notifiquen los cambios en
la localizacion */
lm . requestLocationUpdates ( LocationManager . GPS_PROVIDER , 30000 ,
5 , locListener ) ;

89
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

isAlreadyOn = true ;
}
}

Como se ha visto en el código anterior, el objeto de tipo LocationListener es el


encargado de actuar cada vez que se produce un cambio en las coordenadas GPS del
dispositivo. En este caso se ha implementado una clase propia (MyLocationListener)
que permite definir el comportamiento deseado para esta aplicación. Aunque hay que
definir todos los métodos de la clase, sólo se implementa el método onLocationChange:
al detectarse un cambio de posición, se envían las nuevas coordenadas al servidor,
insertándolas en la tabla MyCoordinates de la base de datos remota.
protected class MyLocationListener implements LocationListener {
/* * se ejecuta cuando se produce un cambio en la localizacion del
dispositivo */
@Override
public void onLocationChanged ( Location location ) {
if ( location != null ) {
db . insertCoordinates ( user , getDate () ,
Double . toString ( location . getLatitude () ) ,
Double . toString ( location . getLongitude () ) ) ;
dbR . insertCoordinate ( user , location . getLatitude () ,
location . getLongitude () ) ;
}
}
/* * se ejecuta al desactivar el proveedor especificado */
@Override
public void onProviderDisabled ( String provider ) {
// Noop .
}
/* * se ejecuta al activar el proveedor especificado */
@Override
public void onProviderEnabled ( String provider ) {
// Noop .
}
/* * se ejecuta cuando hay cambios de estado en el proveedor
especificado */
@Override
public void onStatusChanged ( String provider , int status , Bundle
extras ) {
// Noop .
}
}

A continuación, se realiza de forma automática una llamada a la extensión de emer-


gencia de Asterisk (033, alerta de localización). Esta llamada pondrá en contacto al re-
sidente que ha generado la alarma con el softphone de recepción mediante una llamada

90
4.3. D ESARROLLO DE LAS APLICACIONES

SIP. Mientras tanto, se activa el flag de alerta de la base de datos remota y se envía
la primera coordenada. De esta forma, se asegura que siempre habrá una coordenada
introducida en la base de datos para ese residente, evitando problemas al obtener las
coordenadas desde el softphone de recepción (si se intentan obtener coordenadas antes
de que el listener haya podido insertarlas).
protected void iniciarProtocolo () {
/* * obtiene el numero de usuario que ha generado la alerta */
user = sb . getBinder () . whoAmI () ;
/* * realiza la llamada perdida a la extension de emergencia */
sb . getBinder () . initiateLostCall ( ConstA . sipEmergencyAddress ) ;
/* * si se ha producido una salida de la zona permitida , se activa
el flag de alerta del usuario en la DB remota y se envia la
ultima posicion conocida del usuario a la DB remota */
if (! isEntering ) {
dbR . updateFlag ( " alert " , user , true ) ;
sendFirstCoordinate () ;
}
/* * si se ha producido una entrada en la zona permitida , se
desactiva el flag de alerta del usuario en la DB remota y se
detiene el servicio */
else {
dbR . updateFlag ( " alert " , user , false ) ;
stopSelf () ;
}
}

A partir de este momento, y hasta que no se vuelva a entrar en la zona permitida,


la aplicación estará introduciendo la ubicación del residente en la base de datos remota.

Cuando el residente entra en la zona permitida, se vuelve a realizar una lla-


mada a la extensión de emergencia de Asterisk y a continuación se desactiva el flag
de alerta del usuario en la base de datos remota y se detiene el servicio. Al dete-
nerse, se desactivan las actualizaciones de posicionamiento, logrando así que el servicio
deje de enviar sus coordenadas GPS a la base de datos, debido a que ya no es necesario.

Al encontrarse el usuario en el borde del radio de la zona permitida, se pueden


obtener falsas entradas/salidas de la zona que afectarían al buen funcionamiento de
la aplicación. En caso de recibirse una falsa salida (el residente ya se encuentra fuera
de la zona) el servicio no hace nada. En caso de recibir una falsa entrada (el residente
ya se encuentra dentro), se detiene el servicio que se acaba de iniciar y no se realiza
ninguna acción más.

Petición de seguimiento del residente

91
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

Si en cambio, se ha recibido una solicitud de inicio de seguimiento del residente,


el funcionamiento es muy similar al de una alerta por salida de la zona permitida. El
servicio debe enviar las coordenadas GPS con la posición del residente a la base de
datos remota. En este caso, se ejecuta también el método checkExitingZone, explicado
antes, que pone en marcha la actualización de posicionamiento y se inserta, igual que
en el caso anterior, la primera coordenada.
protected void iniciarSeguimiento () {
/* * obtiene el numero de usuario al que se quiere seguir */
user = sb . getBinder () . whoAmI () ;
/* * se envia la ultima localizacion conocida */
sendFirstCoordinate () ;
}

Si la solicitud recibida es para finalizar el seguimiento del residente, no se lanza


el servicio, simplemente se ejecuta el método onDestroy del mismo, que detiene el
servicio y desactiva las actualizaciones de posicionamiento, dejando de enviar las
coordenadas a la base de datos remota.

4.3.3 S OFTPHONE PARA LA RECEPCIÓN DEL CENTRO

La aplicación LDDSoftphoneB está diseñada especialmente para su utilización desde un


dispositivo que se encuentre en la recepción del centro. Partiendo de las características
del softphone básico, se añaden las siguientes funcionalidades:

* Se crea un sistema de comprobación de alertas de posicionamiento consistente en


un mapa que permite monitorizar la ubicación de los residentes que se encuen-
tran fuera de la zona permitida. Además, por motivos de seguridad, se añade la
posibilidad de solicitar el seguimiento de un residente en concreto aunque éste se
encuentre dentro de la zona permitida. Su ubicación también aparecerá marcada
en el mapa.

* Se incluye un sistema de comprobación de las alertas de batería baja generadas


por los dispositivos de los residentes. De esta manera, los trabajadores podrán
alertar a los residentes de éste problema y solventarlo.

Para comprobar si hay residentes en estado de alerta (de posicionamiento o


batería) y obtener sus coordenadas, esta aplicación debe consultar a la base de datos
remota. Por lo tanto, se crea una clase de ayuda llamada DBRemoteHelperB similar a la
utilizada en la aplicación anterior, pero con peticiones a la base de datos adaptadas a
las necesidades de esta aplicación.

92
4.3. D ESARROLLO DE LAS APLICACIONES

FIGURA 4.9: Menú principal del softphone para la recepción del centro.

Se añaden al menú principal dos opciones que permiten al usuario acceder a las
pantallas que le permitirán comprobar si hay alertas de posicionamiento o batería
activadas. Por tanto, el aspecto del menú de la pantalla principal de esta aplicación es
el mostrado en la figura 4.9.

4.3.3.1 C OMPROBACIÓN DE ALERTAS DE BATERÍA

Los terminales físicos de los residentes no deben quedarse nunca sin batería, ya que
esto inutilizaría el sistema de alertas de posicionamiento detallado en la aplicación
anterior. Para evitarlo, se diseña un mecanismo que permita a los trabajadores del
centro (en este caso, al personal de recepción) comprobar el estado de la batería de
los terminales de los residentes mediante consultas a los flags de alerta battery_flag de
la base de datos remota.

El sistema Android proporciona una herramienta que permite activar una especie
de alarma que se utiliza, en este caso, para comprobar de forma periódica si hay alertas
por batería baja en la base de datos remota. Esta alarma se activa mediante el siguiente
método, que se ejecuta al iniciarse la aplicación:
/* * Activa una alarma cada 30 minutos que comprueba si hay alertas de
bateria baja en la DB remota */

93
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

protected void checkForBatteryAlerts () {


AlarmManager aM = ( AlarmManager )
getSystemService ( Context . ALARM_SERVICE ) ;
/* * se define un pending intent con el servicio que se quiere
lanzar al saltar la alarma ( BatteryLevelChecker ) */
PendingIntent pendingIntent = PendingIntent . getService ( this , 0 ,
new Intent ( this , BatteryLevelChecker . class ) , 0) ;
/* * la primera alarma se configura para que salte al minuto de
iniciar la aplicacion (30 s para test ) */
long startTime = SystemClock . uptimeMillis () +30000;
/* * tiempo de repeticion de alarma cada 30 mins (1 min para test ) */
long repeat_alarm_every = 60000;
/* * se establece la repeticion de alarma */
aM . setRepeating ( AlarmManager . RTC_WAKEUP , startTime ,
repeat_alarm_every , pendingIntent ) ;
}

El objeto AlarmManager permite activar una alarma cada n minutos, indicando


qué se debe hacer cada vez que salte (en este caso, comprobar las alertas de batería
de la base de datos remota). La alarma se activa mediante el comando setRepeating,
especificando los siguientes parámetros: tipo de alarma, tiempo de inicio, cada
cuánto debe repetirse y la clase que manejará la alarma (BatteryLevelChecker).
Este tipo de alarmas se activan aunque la aplicación no esté corriendo, pero se
deshabilitan al reiniciar el terminal. Se debe tener en cuenta que los tiempos finales
establecidos para esta alarma son los que se han utilizado para realizar las pruebas y,
en ningún caso serían los definitivos si se decidiera utilizar esta aplicación para uso real.

El servicio BatteryLevelChecker, de tipo IntentService, se encarga de comprobar


si hay alertas de batería en la base de datos ubicada en el servidor. A diferencia de los
servicios utilizados hasta ahora en las aplicaciones desarrolladas, los IntentService se
utilizan para manejar peticiones asíncronas bajo demanda y se detienen por si mismos
al acabar de ejecutar su código. Su funcionamiento es simple: si hay alertas de batería
baja, muestra una notificación en la barra de estado para informar al usuario de la
aplicación (a la recepción del centro), como se puede ver en la figura 4.10(a); si no
hay alertas, no hace nada y, en caso de haber una notificación anterior no comprobada
en la barra de estado, la cancela.

Como interesa que la recepción del centro sepa en todo momento si los terminales
de los residentes se quedan sin batería, este servicio se ejecuta periódicamente aunque
la aplicación no esté abierta. Por ello, antes de acceder a la base de datos remota, se
comprueba si el terminal está conectado a la red tanto por WiFi como por conexión de
datos.

Al pulsar sobre la notificación que indica que hay alertas de batería se accede a

94
4.3. D ESARROLLO DE LAS APLICACIONES

FIGURA 4.10: a) Notificación de alertas de batería. b) Listado de alertas de batería.

un listado con los nombres y números de usuario de los residentes cuyos terminales
tienen un nivel de batería por debajo del 15% de su capacidad. Este listado, que se
muestra en la figura 4.10(b), no se actualiza de forma automática, por lo que si se
deja visible esta pantalla por tiempo indefinido, la información mostrada puede ser
falsa. Por ello se incluye, en la parte superior de la pantalla, una línea de texto donde
se indica la fecha y hora de la última actualización. La actualización de los datos se
puede realizar de dos maneras: mediante la opción Actualizar listado disponible en el
menú de esta pantalla o pulsando de nuevo sobre la notificación de alerta de batería
(en caso de estar presente en la barra de estado).

A este listado también se puede acceder mediante la opción Alertas Batería del
menú principal de la aplicación. Si al acceder o actualizar el listado no hay ninguna
alerta activa, se muestra un diálogo informando de ello al usuario.

4.3.3.2 C OMPROBACIÓN DE ALERTAS DE POSICIONAMIENTO

Como se ha explicado anteriormente en este capítulo, al producirse una entrada/salida


de la zona permitida por parte de un residente, lo primero que hace la aplicación del
residente es realizar una llamada a la extensión de emergencia de Asterisk (033, alerta

95
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

de localización). Esta llamada hace que Asterisk ponga en contacto, mediante una
llamada SIP, a estas dos partes: el residente que ha generado la alerta y la recepción
del centro (es decir, el usuario de esta aplicación). Al finalizarse la llamada, se muestra
un plano de la zona (alrededor de la residencia) con la ubicación de los residentes
que se encuentran fuera de la zona permitida. De esta forma, la recepción del centro
puede saber la localización del residente con el que acaba de hablar.

Con este objetivo, se crea la actividad ShowLocationMap, que muestra el plano


con la ubicación de los residentes en estado de alerta o en seguimiento. La solicitud
de inicio/finalización de un seguimiento se realiza también desde este plano. El
funcionamiento concreto de esta clase se detallará más adelante.

Igual que en la aplicación diseñada para los residentes, se han realizado algunas
modificaciones respecto al softphone básico para adaptarlo a las necesidades de esta
aplicación. En este caso, se destacan los cambios realizados en el broadcast receiver
CallReceiverSIP y en el servicio ServiceSIP.

Como ya se ha comentado, estas aplicaciones no están diseñadas para manejar


más de una llamada a la vez. Si se recibe una llamada nueva durante una llamada
en curso, la llamada nueva se cuelga (enviándola al buzón de voz) y no consta en el
registro de llamadas. En este caso, si la llamada nueva es una llamada de emergencia,
aunque no se descuelgue, sí que aparece en la pantalla del terminal el mapa de la zona
con la localización de los residentes que están en estado de alerta de posicionamiento.
De esta forma, aunque no se pueda poner en contacto al residente que ha generado la
alerta con la recepción del centro, sí se avisa del estado de alerta del mismo.

Para mostrar el mapa de localización en este caso, se utiliza el siguiente método


desde el broadcast receiver que maneja las llamadas entrantes:
protected void emergencyCall ( String callerID ) {
if ( callerID . equals ( " Emergency Call " ) ) {
Intent showMapIntent = new Intent ( contexto ,
ShowLocationMap . class ) ;
showMapIntent . setFlags ( Intent . FLAG_ACTIVITY_NEW_TASK ) ;
contexto . startActivity ( showMapIntent ) ;
}
}

Por último, se añade un método nuevo en el servicio ServiceSIP que se utilizará


desde el mapa de localización para solicitar el inicio/finalización de un seguimiento.
El método initiateFollowUpCall es muy similar al que utiliza la aplicación para realizar
llamadas SIP pero con algunas modificaciones. En este caso, se realiza una llamada
perdida a la extensión de seguimiento de Asterisk indicada (034 o 035), que se encar-

96
4.3. D ESARROLLO DE LAS APLICACIONES

gará de notificar al softphone del residente indicado que inicie/detenga el protocolo


de seguimiento (envío de las coordenadas GPS a la base de datos remota). El número
de usuario del residente al que se quiere monitorizar se indica a Asterisk al estable-
cer la llamada mediantes tonos DTMF, como se puede ver en el código mostrado a
continuación. Este tipo de llamada no se hace constar en el registro de llamadas.
public void initiateFollowUpCall ( String sipFUuser , String sipFUext ) {
/* * define la extension del servidor Asterisk a la que se
realizara la llamada */
String extension = sipFUext + " @ " + me . getSipDomain () ;
/* * fuUser = numero de usuario relacionado con el seguimiento */
fuUser = sipFUuser . toCharArray () ;
try {
/* * Listener para eventos relacionados con la llamada de
seguimiento */
SipAudioCall . Listener listenerLost = new
SipAudioCall . Listener () {
/* * se ejecuta al establecer la llamada */
@Override
public void onCallEstablished ( SipAudioCall call ) {
/* * se activa el audio y se desactiva el modo altavoz */
call . startAudio () ;
call . setSpeakerMode ( false ) ;
/* * se envia el numero de usuario al que se desea
hacer el seguimiento */
call . sendDtmf ( Character . getNumericValue ( fuUser [0]) ) ;
call . sendDtmf ( Character . getNumericValue ( fuUser [1]) ) ;
call . sendDtmf ( Character . getNumericValue ( fuUser [2]) ) ;
}
/* * se ejecuta cuando el otro extremo finaliza la llamada */
@Override
public void onCallEnded ( SipAudioCall call ) {
/* * no se hace nada ( no se debe registrar esta llamada ) */
// Noop .
}
};
/* * se realiza la llamada SIP */
call = manager . makeAudioCall ( me . getUriString () , extension ,
listenerLost , 30) ;
}
........
}

4.3.3.2.1 S HOW L OCATION M AP


La actividad ShowLocationMap, de tipo MapActivity, muestra un mapa de los
alrededores de la residencia con la ubicación de los residentes que se encuentran fuera
de la zona permitida. También permite solicitar la localización de un residente que

97
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

FIGURA 4.11: a) Mapa de alertas con 2 usuarios (mostrando la información de uno


de ellos). b) Mapa con 2 usuarios fuera de la zona permitida (rojos) y un usuario en
seguimiento (verde).

esté dentro de la zona permitida (seguimiento) siempre y cuando se puedan obtener


sus coordenadas GPS (se esté al aire libre). Se utilizan marcadores sobre el mapa de
colores distintos para distinguir entre los dos casos: rojos (residentes en estado de
alerta) y verde (residente en seguimiento). Al pulsar sobre estos marcadores, aparece
en pantalla información sobre el residente al que representan: nombre y número de
usuario. La información mostrada en este mapa se actualiza cada 30 segundos.

En la figura 4.11(a) se puede ver el mapa con dos usuarios en estado de


alerta (fuera de la zona permitida) y la información de uno de ellos en pantalla. En la
figura 4.11(b) se muestra, además, la posición de un usuario en estado de seguimiento.

Para poder utilizar mapas en una aplicación de Android, se debe obtener una
clave (Google Maps API key) que permita integrar Google Maps en la aplicación. Esta
clave se puede conseguir en la página http://code.google.com/android/add-ons/
google-apis/mapkey.html de forma gratuita. Una vez obtenida, debe añadirse en la
definición del layout de la actividad que utiliza el mapa, concretamente como uno de
los parámetros del objeto MapView:

98
4.3. D ESARROLLO DE LAS APLICACIONES

< com . google . android . maps . MapView


android:id = " @ + id / mapView "
android:layout_width = " fill_parent "
android:layout_height = " wrap_content "
android:enabled = " true "
android:clickable = " true "
android:apiKey = " 0 _ECbuvJC9Z_29i2PIT6CYcSI4TrabnEapFsXiQ "
/>

El acceso a este mapa se puede realizar de dos formas distintas: al colgar una
llamada entrante de emergencia, de forma automática; o a través de la opción Mapa
Alertas del menú principal de la aplicación.

Al lanzar la actividad, antes de poder mostrar el mapa, hay que configurar algunos
aspectos del mismo, así como de los componentes que aparecerán en él (marcadores).
Esta definición se puede ver en el código siguiente:
private void defineMapSettings () {
/* * define el marcador para los usuarios en estado de alerta
( rojos ) */
marker = this . getResources () . getDrawable ( R . drawable . marker ) ;
marker . setBounds (0 , 0 , marker . getIntrinsicWidth () ,
marker . getIntrinsicHeight () ) ;
/* * define el marcador para el usuario en seguimiento ( verde ) */
gmarker = this . getResources () . getDrawable ( R . drawable . marker_green ) ;
gmarker . setBounds (0 , 0 , gmarker . getIntrinsicWidth () ,
gmarker . getIntrinsicHeight () ) ;
/* * crea una referencia al objeto mapa y lo configura en modo
vista de satelite */
mapView = ( MapView ) findViewById ( R . id . mapView ) ;
mapView . setSatellite ( true ) ;
/* * objeto MapController que permite trabajar con el mapa */
mc = mapView . getController () ;
/* * configura el nivel de zoom del mapa */
mc . setZoom (17) ;
/* * elimina todos los posts pendientes que pueda haber en cola */
mHandler . removeCallbacks ( mUpdateTimeTask ) ;
/* * programa el objeto de tipo Runnable ( mUpdateTimeTask ) para que
se ejecute su metodo run () al cabo de 100 ms */
mHandler . postDelayed ( mUpdateTimeTask , 100) ;
}

Primero se definen los marcadores que aparecerán sobre el mapa (rojos y verdes). A
continuación se crea una referencia al mapa mapView y se especifican algunos paráme-
tros de su configuración inicial: aspecto tipo satélite y nivel de zoom (17). Por último,
utilizando un objeto de tipo Handler, se inicia el proceso de marcar sobre el mapa la
posición de los residentes que se encuentren en estado de alerta. Los objetos Handler

99
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

FIGURA 4.12: Diálogo mostrado cuando no hay alertas de posicionamiento en el


mapa.

permiten, entre otras cosas, programar la ejecución de un objeto Runnable cada cierto
tiempo. En este caso, se utiliza el objeto mUpdateTimeTask, cuyo código se muestra a
continuación, y que refresca la información mostrada en el mapa cada 30 segundos.
private Runnable mUpdateTimeTask = new Runnable () {
public void run () {
/* * actualiza la posicion de los marcadores y refresca el
mapa */
updateMarkersPosition () ;
long startTime = SystemClock . uptimeMillis () ;
/* * programa este objeto para que ejecute su metodo run () al
cabo de 30 s */
mHandler . postAtTime ( this , startTime + 30000) ;
}
};

El método updateMarkersPosition es el encargado de actualizar la posición de los


marcadores en el mapa y refrescarlo. Para ello, se comprueba la base de datos remota
con el fin de obtener la información relativa a los residentes que se encuentran fuera de
la zona permitida y se muestra en el mapa su última localización disponible (últimas
coordenadas introducidas en la tabla MyCoordinates para cada residente). En caso de
no existir ningún usuario en estado de alerta, se muestra un diálogo informando al

100
4.3. D ESARROLLO DE LAS APLICACIONES

usuario de la aplicación de este hecho y dándole la opción de solicitar un seguimiento


(figura 4.12). Además, si hay algún residente en seguimiento, se muestra también su
última localización disponible.
private void updateMarkersPosition () {
/* * crea un punto geografico con la ubicacion de la residencia */
p = getPoint ( ConstB . res_latitude , ConstB . res_longitude ) ;
/* * centra el mapa en el punto definido antes */
mc . animateTo ( p ) ;
/* * obtiene una lista con los datos de los usuarios en estado de
alerta y sus coordenadas mas recientes */
List < String [] > alert_points = dbR . getAlertCoordinates () ;
/* * si no hay ningun usuario en estado de alerta , muestra un
dialogo para informar de ello */
if ( alert_points . size () == 0 & ! conSeguimiento ) {
showDialog (0) ;
}
else {
/* * borra todos los marcadores que hubiera en el mapa */
mapView . getOverlays () . clear () ;
/* * si hay usuarios en estado de alerta , anade los marcadores
correspondientes utilizando el objeto MapOverlay y
definiendo el tipo de marcador y los datos que se usaran */
if ( alert_points . size () != 0) {
mapView . getOverlays () . add ( new MapOverlay ( marker ,
alert_points ) ) ;
}
/* * si hay algun usuario en seguimiento , obtiene las ultimas
coordenadas introducidas en la DB remota y anade el
marcador correspondiente en el mapa mediante el objeto
MapOverlay , definiendo el tipo de marcador y los datos que
se usaran */
if ( conSeguimiento ) {
String [] person = dbR . getUserCoordinates ( usuario ) ;
if ( person [0] == null ) {
/* * si el usuario no tiene ninguna coordenada en la DB
remota al solicitar el seguimiento , se muestra un
mensaje de espera hasta que se vuelva a refrescar
la informacion */
Toast . makeText ( getBaseContext () , " Esperando
coordenadas ... " , Toast . LENGTH_SHORT ) . show () ;
} else {
mapView . getOverlays () . add ( new MapOverlay ( gmarker ,
person ) ) ;
}
}
/* * fuerza el mapa a redibujarse */
mapView . invalidate () ;
}
}

101
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

Para poder dibujar elementos encima del mapa (como los marcadores) se debe uti-
lizar un objeto de tipo Overlay. Para esta aplicación, se ha creado una clase propia
(MapOverlay) que extiende a una clase de tipo lista de Overlays, modificando su com-
portamiento. Se crean dos constructores distintos (uno para cada tipo de marcador)
que, a partir de la información obtenida de la base de datos, crearán los objetos de
tipo Overlay que se dibujarán encima del mapa. También se incluyen varios métodos
que permiten, entre otras cosas, dibujar los marcadores (draw) y especificar el compor-
tamiento de éstos al pulsar sobre ellos (onTap).
private class MapOverlay extends ItemizedOverlay < OverlayItem > {
/* * lista donde se guardan todos los objetos OverlayItem
( marcadores ) que se dibujaran sobre el mapa */
private List < OverlayItem > items = new ArrayList < OverlayItem >() ;
private Drawable marker = null ;

/* * constructor de la clase para marcadores de alertas de


proximidad
* marker = marcador rojo
* list = lista con los datos de los usuarios en situacion de
alerta */
public MapOverlay ( Drawable marker , List < String [] > list ) {
super ( marker ) ;
this . marker = marker ;
/* * recorre la lista de usuarios en estado de alerta ( list ) y
crea un objeto de tipo OverlayItem para cada usuario . Anade
todos los objetos a la lista item */
for ( int i =0; i < list . size () ; i ++) {
String [] p = list . get ( i ) ;
items . add ( new
OverlayItem ( getPoint ( Double . parseDouble ( p [0]) ,
Double . parseDouble ( p [1]) ) , p [2] , p [3]) ) ;
}
/* * crea los objetos que hay en la lista item ( mediante el
metodo createItem () ) y los dibuja en el mapa ( mediante el
metodo draw () )
* se debe llamar en cuanto se tengan objetos en la lista */
populate () ;
}

/* * constructor de la clase para el marcador de seguimiento


* marker = marcador verde
* p = datos del usuario que este en seguimiento */
public MapOverlay ( Drawable marker , String [] p ) {
super ( marker ) ;
this . marker = marker ;
/* * crea un objeto de tipo OverlayItem con los datos del
usuario en seguimiento . Anade el objeto a la lista item */

102
4.3. D ESARROLLO DE LAS APLICACIONES

items . add ( new OverlayItem ( getPoint ( Double . parseDouble ( p [0]) ,


Double . parseDouble ( p [1]) ) , p [2] , p [3]) ) ;
/* * crea los objetos que hay en la lista item ( mediante el
metodo createItem () ) y los dibuja en el mapa ( mediante el
metodo draw () )
* se debe llamar en cuanto se tengan objetos en la lista */
populate () ;
}

/* * crea los objetos que hay en la lista item . Se llama desde el


metodo populate () */
@Override
protected OverlayItem createItem ( int i ) {
return ( items . get ( i ) ) ;
}

/* * dibuja un marcador para cada objeto de la lista */


@Override
public void draw ( Canvas canvas , MapView mapView , boolean shadow ) {
super . draw ( canvas , mapView , shadow ) ;
/* * centra el marcador para que apunte exactamente a la
coordenada correspondiente */
boundCenterBottom ( marker ) ;
}

/* * Devuelve el numero de objetos que hay que dibujar */


@Override
public int size () {
return ( items . size () ) ;
}

/* * Define el comportamiento al pulsar sobre un marcador en el


mapa . Identifica el marcador pulsado y muestra el numero y el
nombre de usuario al que representa */
@Override
protected boolean onTap ( int i ) {
OverlayItem item = getItem ( i ) ;
String str = item . getTitle () + " \ n \ t " + item . getSnippet () ;
Toast . makeText ( getBaseContext () , str ,
Toast . LENGTH_SHORT ) . show () ;
return ( true ) ;
}
}

Como se ha indicado antes, desde este mapa, el usuario de la aplicación puede


iniciar/finalizar el seguimiento de la posición de un residente que no se encuentre
en situación de alerta (dentro de la zona permitida). Para ello, como se ve en la
figura 4.13(a), se incluyen las opciones Iniciar Seguimiento y Finalizar Seguimiento en

103
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

FIGURA 4.13: a) Menú del mapa de alertas. b) Diálogo para iniciar un seguimiento.

el menú de esta pantalla.

Al seleccionar Iniciar Seguimiento, aparece en pantalla el diálogo de la


figura 4.13(b) solicitando el número de usuario del residente al que se quiere localizar.
Al introducir el número deseado, se realiza de forma automática una llamada a la ex-
tensión de inicio de seguimiento de Asterisk (034) para avisar al softphone de dicho
residente que se ha pedido un seguimiento y que por tanto debe empezar a enviar sus
coordenadas GPS a la base de datos remota. Por último, se fuerza una actualización de
la información del mapa.
private void startSeguimiento () {
conSeguimiento = true ;
/* * realiza una llamada a la extension de inicio de seguimiento */
sb . getBinder () . initiateFollowUpCall ( usuario , " 034 " ) ;
/* * actualiza la posicion de los marcadores en el mapa */
updateMarkersPosition () ;
}

Si se selecciona Finalizar Seguimiento, se realiza de forma automática una llamada


a la extensión de finalización de seguimiento de Asterisk (035) para avisar al softphone
del residente que ya puede dejar de enviar sus coordenadas a la base de datos remota.

104
4.3. D ESARROLLO DE LAS APLICACIONES

Por último, como en el caso anterior, se fuerza una actualización del mapa.
private void stopSeguimiento () {
if ( conSeguimiento ) {
conSeguimiento = false ;
/* * realiza una llamada a la extension de fin de seguimiento */
sb . getBinder () . initiateFollowUpCall ( usuario , " 035 " ) ;
/* * actualiza la posicion de los marcadores en el mapa */
updateMarkersPosition () ;
}
}

Como se ha comentado previamente, la información mostrada sobre el mapa se


actualiza de forma automática cada 30 segundos. De todos modos, si se desea forzar
una actualización en un momento concreto, se puede hacer desde la opción Actualizar
disponible en el menú de esta pantalla.

105
CAPÍTULO 4. I MPLEMENTACIÓN DE LOS S OFTPHONES

106
5
Conclusiones y líneas de futuro

y después de revisar los objetivos planteados en la introduc-


L LEGADOS A ESTE PUNTO
ción de esta memoria, podemos decir que se han cumplido los objetivos definidos
para este proyecto.

Hay que recalcar que, aunque este proyecto está enfocado como un caso real
(implementación de una plataforma VoIP en una residencia de ancianos), no está
realmente desarrollado para su utilización inmediata, sería más bien como una prueba
piloto.

Se ha realizado todo el trabajo posible con los recursos disponibles (que a veces
resultaron limitadores) tanto a la hora de desarrollar el proyecto como de realizar las
pruebas correspondientes. A continuación se comentan los principales problemas y
factores que habría que mejorar en revisiones futuras:

* Para este proyecto se buscó una forma de integrar la VoIP en una aplicación
Android, utilizando el protocolo SIP, que es el más extendido entre los usuarios
de VoIP. Al final se decidió utilizar la API SIP nativa que proporciona el propio
Android. De todas formas, esta API está muy limitada y, aunque fue suficiente
para la realización de este proyecto, se ha descubierto que no es la más apro-
piada para ello.
Aunque la API SIP va incluida en todas las versiones de Android a partir de la 2.3,
se ha descubierto que algunas marcas de smartphones tienen capada esta API
para congraciarse con las operadoras de telefonía móvil. En este caso, se tuvieron
que rootear los dos terminales de pruebas para poder desbloquear su utilización.
Además, esta API no soporta la utilización conjunta con servidores STUN, con lo
que no se han podido solucionar los problemas de NAT (inherentes a SIP) que
ya se comentaron en el capítulo 2. También se descubrió que, aunque no se
especificaba de ninguna manera en la documentación de la API, su utilización

107
CAPÍTULO 5. C ONCLUSIONES Y LÍNEAS DE FUTURO

con conexión de datos no es automática: hay que modificar archivos internos del
smartphone a los que, en principio, un usuario normal no debería tener acceso.
Por estos motivos, si se deseara utilizar los softphones desarrollados en un entorno
práctico, habría que buscar otra API SIP externa e integrarla en las aplicaciones.
* El softphone de recepción consulta la base de datos cada cierto tiempo para ver
si hay alertas de batería activadas, método que resulta ineficiente. La decisión de
controlar el nivel de batería de los dispositivos de los residentes se tomó una vez
finalizada la programación de las aplicaciones, por lo que se buscó una solución
rápida que permitiera obtener los resultados requeridos, pero sin tener que estu-
diar opciones fuera del conocimiento que se tenía en aquel momento. Se debería
buscar una alternativa para evitar que la aplicación realice accesos y comproba-
ciones innecesarias a la base de datos, mejorando así la autonomía del dispositivo.
* Añadir securización en Asterisk utilizando el protocolo de seguridad SRTP
(Secure Real-time Transport Protocol). Debido a la evolución que sufrió el
proyecto, esta funcionalidad quedó en un segundo plano y queda entonces para
revisiones futuras.
* Durante el desarrollo de la centralita de telefonía aparecieron dos problemas para
los cuales, a la fecha de entrega, no se ha encontrado solución. El tratamiento de
estas cuestiones queda, por tanto, pendiente para resolver en futuras revisiones.
1. Detección de colgado: Asterisk no es capaz de detectar cuando una llamada
entrante a la PBX cuelga. Si la finalización de la llamada proviene del ex-
terior, Asterisk no lo detecta y sigue haciendo la rutina marcada hasta que
llega a un Hangup() (Asterisk cuelga y libera la línea). Si no se llega a un
Hangup(), la línea queda bloqueada y para desbloquearla hay que reiniciar
el servicio Asterisk. Se proporciona una solución provisional al problema
haciendo que se libere la línea en casos de bloqueo mediante timeouts.
2. Identificador de llamada: Asterisk no obtiene el CallerID de las llamadas que
llegan a la PBX. Esto puede ser debido a varios motivos, entre los que se
destacan: que la red Ibercom no ofrece este servicio; o existe algún elemento
intermedio que elimina el CallerID. Por este motivo, no se ha utilizado esta
funcionalidad en la PBX.
* El entorno de pruebas de este proyecto sería un aspecto a mejorar. Las aplica-
ciones deben estar conectadas a la red en todo momento. Esto supone un pro-
blema ya que el campus universitario no dispone de una red wifi uniforme en
toda su extensión (hay zonas sin cobertura fuera de los edificios). Lo ideal hu-
biera sido disponer de smartphones con conexión de datos para poder realizar
algunas de las pruebas, pero diversos factores (como la elección de la API SIP) no
lo permitieron.

108
5.1. VALORACIÓN PERSONAL

5.1 VALORACIÓN PERSONAL

NIVEL PERSONAL , debo decir que he aprendido mucho con este proyecto, ya que
A todas las tecnologías que se han tratado en él (Android, Asterisk, bases de datos
MySQL, etc.) eran totalmente nuevas para mi.

La mayor parte del trabajo que se ve en este proyecto es fruto del auto aprendizaje,
ya sea mediante la consulta y lectura de libros, como la lectura de infinitas páginas
web, foros de grupos y comunidades especializadas en cada una de dichas tecnologías.
Esto es algo que valoro mucho, ya que es una situación habitual en el mundo laboral.

Desde que empecé a trabajar en este proyecto me he dado cuenta de que el


desarrollo de aplicaciones Android es algo que me interesa bastante y en lo que me
gustaría trabajar en un futuro.

En conclusión, considero que este proyecto ha resultado ser una experiencia muy
positiva (aunque algo dura) de cara a mi futuro laboral y me ha permitido aprender y
aplicar nuevas tecnologías que me pueden resultar muy útiles para esta nueva etapa de
mi vida.

109
CAPÍTULO 5. C ONCLUSIONES Y LÍNEAS DE FUTURO

110
6
Bibliografía

Publicaciones:

* Madsen, Leif; Van Meggelen, Jim; Bryant, Russell. Asterisk: The Definitive Guide
(3rd Edition). O’Reilly, 2011.

* Digium 800 Series User Manual. Digium, 2009.

* Lee, Wei-Meng. Beginning Android Application Development. Wiley Publishing,


2011.

* Murphy, Mark L. The Busy Coder’s Guide to Advanced Android Development.


CommonsWare, 2010.

* Kelly, Timothy. VoIP for Dummies. Wiley Publishing, 2005.

* International Development Research Centre. Escudero-Pascual, Alberto;


Berthilson, Louise. VoIP para el desarrollo [en línea]. 2006.

* Margarit, Genís. Administración de sistemas Asterisk [apuntes cursillo]. 2011.

Enlaces de interés:

* www.voip-info.org
Guía de referencia para todo lo relacionado con VoIP.
Wiki con documentación sobre Asterisk: consultada para la configuración de los
módulos de Asterisk y las funciones y aplicaciones utilizadas en el dialplan.

* www.asterisk.org
Página oficial de Asterisk. Contiene documentación de Asterisk y Dahdi.

111
CAPÍTULO 6. B IBLIOGRAFÍA

* http://stackoverflow.com
Foro para programadores tanto profesionales como amateurs.
Utilizado para resolver problemas relacionados con la programación de las apli-
caciones Android.

* http://developer.android.com/index.html
Página web oficial para desarrolladores de aplicaciones Android. Contiene
documentación, guías de referencia, ejemplos de código, etc.

112
Instalaciones y configuraciones relacionadas con
A
Asterisk

A.1 Instalaciones relacionadas con Asterisk

A.1.1 P RERREQUISITOS

Antes de empezar, hay que verificar que se tienen instaladas en el servidor todas las
dependencias que los paquetes básicos necesitan. Para no tener que hacerlo manual-
mente (uno a uno), el paquete Asterisk contiene un script que se encarga de instalar
todas las dependencias y prerrequisitos necesarios. Para ejecutar el script, escribimos
las siguientes líneas en un terminal:
> cd / usr / src / asterisk -10.0.0/ contrib / scripts /
> ./ install_prereq install

A.1.2 DAHDI

Con el paquete descargado y descomprimido, compilamos e instalamos DAHDI escri-


biendo los siguientes comandos en un terminal:
> cd / usr / src / dahdi - linux - complete -2.5.0.2+2.5.0.2
> make all
> make install
> make config

Para poder integrar el cancelador de eco Oslec con DAHDI se deben hacer algunos
cambios en este paquete. Es por eso que, una vez instalado, deberá recompilarse.

113
CAPÍTULO A. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON A STERISK

A.1.3 LIB PRI

La compilación e instalación de la librería libPRI es bastante similar al proceso seguido


para DAHDI. Con el paquete descargado y descomprimido, se escriben las siguientes
líneas en un terminal:
> cd / usr / src / libpri -1.4.12
> make
> make install

A.1.4 A STERISK

La compilación e instalación de Asterisk es un poco más compleja que las anteriores,


ya que añadiremos algunos elementos extras a su instalación básica (por defecto).

Primero se instala la compatibilidad mp3 para que Asterisk pueda manejar archivos
con este formato. Como en el caso de los prerrequisitos, el paquete Asterisk incluye un
script con este fin. Para ejecutarlo, se escriben las siguientes líneas en un terminal:
> cd / usr / src / asterisk -10.0.0
> ./ contrib / scripts / get_mp3_source . sh
> ./ contrib / scripts / get_mp3_source . sh install

A continuación, ya se puede empezar con la instalación de Asterisk. Se ejecutan los


primeros comandos en un terminal:
> cd / usr / src / asterisk -10.0.0
> ./ configure
> make menuselect

Con el último comando aparece un menú con interfaz gráfica que permite especi-
ficar los módulos de Asterisk que se quieren incluir en la instalación. Los módulos de
la instalación por defecto ya aparecen marcados. Además de estos, se seleccionan unas
aplicaciones del dialplan que estaban incluidas por defecto en versiones anteriores y los
paquetes de sonidos (en inglés y castellano) y de música en espera en varios formatos.
Applications
[*] app_meetme
[*] app_readfile
[*] app_setcallerid

Core Sounds Packages


[*] CORE - SOUNDS - EN - WAV
[*] CORE - SOUNDS - EN - ULAW
[*] CORE - SOUNDS - EN - ALAW
[*] CORE - SOUNDS - EN - GSM

114
A.1. I NSTALACIONES RELACIONADAS CON A STERISK

[*] CORE - SOUNDS - EN - G729


[*] CORE - SOUNDS - EN - G722

[*] CORE - SOUNDS - ES - WAV


[*] CORE - SOUNDS - ES - ULAW
[*] CORE - SOUNDS - ES - ALAW
[*] CORE - SOUNDS - ES - GSM
[*] CORE - SOUNDS - ES - G729
[*] CORE - SOUNDS - ES - G722

[*] CORE - SOUNDS - EN_AU - WAV


[*] CORE - SOUNDS - EN_AU - ULAW
[*] CORE - SOUNDS - EN_AU - ALAW
[*] CORE - SOUNDS - EN_AU - GSM
[*] CORE - SOUNDS - EN_AU - G729
[*] CORE - SOUNDS - EN_AU - G722

Music On Hold File Packages :


[*] MOH - OPSOUND - WAV
[*] MOH - OPSOUND - ULAW
[*] MOH - OPSOUND - ALAW
[*] MOH - OPSOUND - GSM
[*] MOH - OPSOUND - G729
[*] MOH - OPSOUND - G722

Extra Sound Packages :


[*] EXTRA - SOUNDS - EN - WAV
[*] EXTRA - SOUNDS - EN - ULAW
[*] EXTRA - SOUNDS - EN - ALAW
[*] EXTRA - SOUNDS - EN - GSM
[*] EXTRA - SOUNDS - EN - G729
[*] EXTRA - SOUNDS - EN - G722

Una vez marcados los paquetes, se salva la selección y se vuelve al terminal


pulsando el botón Save and Exit.

Con todos los módulos especificados, ya se puede continuar con la compilación e


instalación de Asterisk. Para ello, se escriben las siguientes líneas en el terminal:
> make
> make install
> make config
> make samples

Por último, se ejecuta el siguiente comando, que comprime los archivos tipo log que
genera Asterisk, ahorrando espacio en disco:
> make install - logrotate

115
CAPÍTULO A. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON A STERISK

A.1.5 C ANCELADOR DE ECO O SLEC

Los archivos necesarios para descargar e instalar Oslec no se encuentran en un paquete


propio, sino que están incluidos en el kernel de Linux. Por tanto, se descarga el Linux
Kernel source de la versión que hay instalada en el servidor y se descomprime. Para este
proyecto, la versión adecuada es la 2.6.32.
> cd / usr / src
> wget http :// kernel . org / pub / linux / kernel / v2 .6/ linux -2.6.32. tar . bz2
> tar xjf linux -2.6.32. tar . bz2

A continuación, se crean dentro del paquete DAHDI los directorios donde se deberán
ubicar los archivos obtenidos del kernel y se copian los archivos relativos a Oslec en
estos directorios.
> mkdir dahdi - linux - complete -2.5.0.2+2.5.0.2/ linux / drivers / staging
> mkdir
dahdi - linux - complete -2.5.0.2+2.5.0.2/ linux / drivers / staging / echo
> cp linux -2.6.32/ drivers / staging / echo /*
dahdi - linux - complete -2.5.0.2+2.5.0.2/ linux / drivers / staging / echo /

Para utilizar Oslec, hay que descomentar y modificar las dos líneas relativas al can-
celador en el archivo Kbuild del paquete DAHDI.
> vi dahdi - linux - complete -2.5.0.2+2.5.0.2/ linux / drivers / dahdi / Kbuild

# descomentar y modificar estas lineas


obj - m += dahdi_echocan_oslec . o
obj - m += ../ staging / echo / echo . o

Para aplicar los cambios, se vuelve a compilar e instalar el paquete DAHDI como
se especifica en el apartado anterior. Verificamos que se han ejecutado los cambios
mirando el resultado de la compilación. Si aparecen las siguientes líneas, Oslec está
instalado e integrado con DAHDI y sólo hay que configurarlo.
CC [ M ]
/ usr / src / dahdi - linux - complete -2.5.0.2+2.5.0.2/ linux / drivers / dahdi /
dahdi_echocan_oslec . o
CC [ M ]
/ usr / src / dahdi - linux - complete -2.5.0.2+2.5.0.2/ linux / drivers / dahdi /
../ staging / echo / echo . o

A.1.6 R ECONOCIMIENTO DE VOZ

Los paquetes necesarios para instalar las librerías Pocketsphinx (librería de re-
conocimiento) y Sphinxbase (librería de soporte) se pueden descargar desde la página

116
A.2. A RCHIVOS DE CONFIGURACIÓN A STERISK

del proyecto: http://cmusphinx.sourceforge.net/. Como se ha hecho con los otros


paquetes, se descargan, se ubican en el directorio /usr/src y se descomprimen.

Primero se instala la librería de soporte Sphinxbase en el servidor mediante los


siguientes comandos en un terminal:
> cd / usr / src / sphinxbase -0.7
> ./ autogen . sh
> make
> make install

Para asegurar que el sistema es capaz de cargar las librerías correctamente, se con-
figura el path para que sepa dónde buscar las librerías compartidas.
> export LD_LIBRARY_PATH =/ usr / local / lib
> export PKG_CONFIG_PATH =/ usr / local / lib / pkgconfig

A continuación se instala la librería Pocketsphinx, utilizando el mismo procedi-


miento:
> cd / usr / src / pocketsphinx -0.7
> ./ autogen . sh
> make
> make install

Para comprobar que la instalación de ambas librerías se ha realizado correctamente


se deben obtener las siguientes líneas al ejecutar este comando:
> pkg - config -- cflags -- libs pocketsphinx sphinxbase

-I / usr / local / include -I / usr / local / include / sphinxbase


-I / usr / local / include / pocketsphinx
-L / usr / local / lib - lpocketsphinx - lsphinxbase - lsphinxad

A.2 Archivos de configuración Asterisk

A.2.1 C ANALES DAHDI

Se añaden las siguientes líneas al final del archivo /etc/asterisk/chan_dahdi.conf:


; General options
usecallerid = yes
hidecallerid = no
callwaiting = yes
usecallingpres = yes
callwaitingcallerid = yes
threewaycalling = yes

117
CAPÍTULO A. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON A STERISK

transfer = yes
canpark = yes
callreturn = yes
cancallforward = yes
echocancel = yes
echocancelwhenbridged = yes
echotraining = no
rxgain = 10.0
txgain = 5.0
cid_rxgain = 8.0

hanguponpolarityswitch = yes
tonezone =6
ringtimeout =8000
immediate = yes
busydetect = yes
busycount =6
usedistinctiveringdetection = yes

; FXO Modules
group =1
callgroup =1
pickupgroup =1
signalling = fxs_ks
callerid = asreceived
context = from - pstn
channel = > 1 -8

A.2.2 U SUARIOS

Se añaden las siguientes líneas al final del archivo /etc/asterisk/sip.conf:


; residentes

[200]
type = friend
secret =12345
host = dynamic
qualify = yes
canreinvite = no
context = PermisosResidentes
disallow = all
allow = ulaw
allow = alaw
[201](200)
[202](200)

; trabajadores residencia

118
A.2. A RCHIVOS DE CONFIGURACIÓN A STERISK

[501] ; recepcion
type = friend
secret =12345
host = dynamic
qualify = yes
canreinvite = no
context = PermisosTrabajadores
disallow = all
allow = ulaw
allow = alaw
[502](501) ; trabajadora social
[503](501) ; gerocultora 1
[504](501) ; gerocultora 2
[505](501) ; gerocultora 3
[506](501) ; despacho directora
[507](501) ; movil directora
[508](501) ; casa directora
[509](501) ; psicologa
[500](501) ; jefa enfermeras

A.2.3 D IALPLAN

Se añaden las siguientes líneas al final del archivo /etc/asterisk/extensions.conf:


[ usuarios ]
; para llamadas entre usuarios internos
exten = > _X0X ,1 , macro ( UnaExten )
; codigo para las llamadas de emergencia
same = > 2 , SayDigits ( $ { EXTEN })
same = > n , Goto (1)

; para entrar en la conferencia de la centralita Dahdi (101)


exten = > 101 ,1 , Answer ()
same = > n , MeetMe (101 , pM )
same = > n , Hangup ()

[ PermisosResidentes ]
include = > usuarios
include = > Buzon_de_voz
include = > android_VA

[ PermisosTrabajadores ]
include = > usuarios
include = > Buzon_de_voz
include = > grabadora
include = > android_VA

119
CAPÍTULO A. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON A STERISK

include = > PC_a_RTC


include = > parkedcalls

; desvio de llamadas activo de llamante a 50 X


exten = > _ *21*50 X ,1 , Answer ()
same = > n , Set ( DB ( CFIM / $ { CALLERID ( num ) }) = $ { EXTEN : -3})
same = > n , Hangup ()

; desvio de llamadas de extension 50 X desactivado


exten = > _ # 21#50 X ,1 , Answer ()
same = > n , Verbose ( Cancelado desvio extension $ { EXTEN : -3} a
$ { DB_DELETE ( CFIM / $ { EXTEN : -3}) })
same = > n , Hangup ()

; sala de conferencias interna limite 3 personas


exten = > 600 ,1 , Answer ()
same = > 2 , MeetMeCount (600 , count )
same = > 3 , NoOp ( $ { count })
same = > 4 , GotoIf ( $ [ $ { count } >= 3]?7)
same = > 5 , Authenticate (5678)
same = > 6 , MeetMe (600 , pM )
same = > 7 , PlayBack ( conf - kicked )
same = > 8 , Hangup ()

; pruebas centralita
exten = > 00 ,1 , Goto ( from - pstn ,s ,1)

[ android_VA ]

exten = > 033 ,1 , Answer ()


same = > n , PlayBack ( beep )
; Origina una llamada entre SIP /501 ( recepcion ) y CALLERID ( num )
llama a SIP /501 y luego ejecuta la instruccion de la extension
CALLERID ( num ) , prioridad 2
same = > n , Originate ( SIP /501 , exten , usuarios , $ { CALLERID ( num ) } ,2)
same = > n , Hangup ()

exten = > 034 ,1 , Answer ()


same = > n , Read ( num , ,3)
same = > n , Set ( CALLERID ( num ) =034)
same = > n , Dial ( SIP / $ { num } ,10)
same = > n , Hangup ()

exten = > 035 ,1 , Answer ()


same = > n , Read ( num , ,3)
same = > n , Set ( CALLERID ( num ) =035)
same = > n , Dial ( SIP / $ { num } ,10)
same = > n , Hangup ()

120
A.2. A RCHIVOS DE CONFIGURACIÓN A STERISK

[ macro - UnaExten ]
; si no te cogen el telefono salta al buzon de voz
; comprueba primero si el numero esta en la blacklist
; comprueba si hay desvio de llamadas
; con parking de llamadas ( t / T en Dial para poder transferir )
; con grabacion de la llamada si es para 200 ( monitorizacion ) ( pruebas )
exten = > s ,1 , Answer ()
exten = > s ,2 , Set ( exten = $ { DB ( CFIM / $ { MACRO_EXTEN }) })
exten = > s ,3 , GotoIf ( $ [ " $ { exten } " = " " ]?4:5)
exten = > s ,4 , Set ( exten = $ { MACRO_EXTEN })
exten = > s ,5 , GotoIf ( $ { BLACKLIST () }? bl )
exten = > s ,6 , GotoIf ( $ [ $ { exten }=200]?:9)
exten = > s ,7 , Set ( CALLFILENAME = $ { MACRO_EXTEN } a $ { CALLERID ( num ) } -
$ { STRFTIME ( $ { EPOCH } , GMT -2 ,% e % b % R ) })
exten = > s ,8 , Monitor ( wav , $ { CALLFILENAME } , m )
exten = > s ,9 , Dial ( SIP / $ { exten } ,30 , t / T )
exten = > s ,n , NoOp ( $ { DIALSTATUS })
exten = > s ,n , PlayBack ( vm - nobodyavail )
exten = > s ,n , VoiceMail ( $ { exten })
exten = > s ,n , Hangup ()
exten = > s , n ( bl ) , PlayBack ( tt - somethingwrong )
exten = > s ,n , Hangup ()

[ Buzon_de_voz ]
; Consulta el buzon de voz
exten = > 99 ,1 , VoiceMailMain ()

[ grabadora ]
; para grabar las locuciones de voz de la centralita
exten = > 111 ,1 , PlayBack ( beep )
; same = > n , Record ( custom / asr_oficina_cerrada . wav )
; same = > n , Record ( custom / asr_bienvenida . wav )
; same = > n , Record ( custom / asr_extension_voz . wav )
; same = > n , Record ( custom / asr_menu . wav )
; same = > n , Record ( custom / asr_extension . wav )
; same = > n , Record ( custom / asr_max_intentos . wav )
; same = > n , Record ( custom / asr_recepcion . wav )
; same = > n , Record ( custom / asr_trabajador_social . wav )
; same = > n , Record ( custom / asr_enfermeria . wav )
; same = > n , Record ( custom / asr_no_disponible . wav )
; same = > n , Record ( custom / asr_cola . wav )
; same = > n , Record ( custom / asr_max_t_cola . wav )
; same = > n , Record ( custom / asr_directora . wav )
; same = > n , Record ( custom / asr_psicologa . wav )
; same = > n , Record ( custom / asr_desvio . wav )
; same = > n , Record ( custom / asr_exterior . wav )
; same = > n , Record ( custom / asr_despedida . wav )

121
CAPÍTULO A. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON A STERISK

; same = > n , Record ( custom / asr_opcion_incorrecta . wav )


; same = > n , Record ( custom / asr_bienvenida_privado . wav )
; same = > n , Record ( custom / asr_menu_privado . wav )
; same = > n , Record ( custom / asr_error_privado . wav )
; same = > n , Record ( custom / asr_conferencia . wav )
; same = > n , Record ( custom / asr_escucha . wav )
same = > n , Hangup ()

; para escuchar las locuciones de voz de la centralita


exten = > 112 ,1 , PlayBack (/ tmp / ivr )
; same = > n , PlayBack ( custom / asr_oficina_cerrada )
; same = > n , PlayBack ( custom / asr_bienvenida )
; same = > n , PlayBack ( custom / asr_extension_voz )
; same = > n , PlayBack ( custom / asr_menu )
; same = > n , PlayBack ( custom / asr_extension )
; same = > n , PlayBack ( custom / asr_max_intentos )
; same = > n , PlayBack ( custom / asr_recepcion )
; same = > n , PlayBack ( custom / asr_trabajador_social )
; same = > n , PlayBack ( custom / asr_enfermeria )
; same = > n , PlayBack ( custom / asr_no_disponible )
; same = > n , PlayBack ( custom / asr_cola )
; same = > n , PlayBack ( custom / asr_max_t_cola )
; same = > n , PlayBack ( custom / asr_directora )
; same = > n , PlayBack ( custom / asr_psicologa )
; same = > n , PlayBack ( custom / asr_desvio )
; same = > n , PlayBack ( custom / asr_exterior )
; same = > n , PlayBack ( custom / asr_despedida )
; same = > n , PlayBack ( custom / asr_opcion_incorrecta )
; same = > n , PlayBack ( custom / bienvenida_privado )
; same = > n , PlayBack ( custom / asr_menu_privado )
; same = > n , PlayBack ( custom / asr_error_privado )
; same = > n , PlayBack ( custom / asr_conferencia )
; same = > n , PlayBack ( custom / asr_escucha )
same = > n , Hangup ()

[ PC_a_RTC ]
; llama desde PC a un telf exterior
exten = > _00 . ,1 , Dial ( DAHDI / g1 / $ { EXTEN :2} ,10)
exten = > _00 . ,n , Hangup ()

[ from - pstn ]

; ---- ---- ---- --- ---- ---- ---- --- ---- ---- ---- ---- --- ---- ---- ---- --- ----
; CENTRALITA DAHDI ( con ASR en ingles )
; ---- ---- ---- --- ---- ---- ---- --- ---- ---- ---- ---- --- ---- ---- ---- --- ----

exten = > s ,1 , Answer ()


same = > n , GotoIfTime (8:00 -20:00 , mon - fri ,* ,*? centralita_ASR ,s ,1)

122
A.2. A RCHIVOS DE CONFIGURACIÓN A STERISK

same = > n , PlayBack ( custom / asr_oficina_cerrada )


same = > n , VoiceMail (501) ; recepcion
same = > n , Hangup ()

[ centralita_ASR ]
exten = > s ,1 , Answer ()
same = > 2 , Background ( custom / asr_bienvenida )
same = > 3 , Set ( k =1)
same = > 4 , While ( $ [ $ { k } <3])
same = > n , Background ( custom / asr_extension_voz )
same = > n , Background ( custom / asr_menu )
same = > n , Record ( custom / recon / voz . wav , ,5)
same = > n , System (/ var / lib / asterisk / sounds / custom / recon / asr2 . sh )
same = >
n , Set ( num = $ { FILE (/ var / lib / asterisk / sounds / custom / recon / num . txt ,0 ,1) })
same = > n , NoOp ( num = $ { num })
same = > n , GotoIf ( $ [ " $ { num } " = " " ]? null )
same = > n , GotoIf ( $ [ $ { num } <0 | $ { num } >6]?: ok )
same = > n , Set ( num = i )
same = > n ( ok ) , Goto ( $ { num } ,1)
same = > n ( null ) , Set ( k = $ [ $ { k }+1])
same = > n , EndWhile
same = > n , Background ( custom / asr_extension & beep )
same = > n , WaitExten (15 , m ( radio ) )
same = > n ( max ) , PlayBack ( custom / asr_max_intentos )
same = > n , Goto (0 ,1)

; extension Recepcion
exten = > 0 ,1 , PlayBack ( custom / asr_recepcion )
same = > n , Dial ( SIP /501 ,15 , m ( radio ) t )
same = > n , Goto ( # ,1)

; extension Trabajadora Social


exten = > 1 ,1 , PlayBack ( custom / asr_trabajador_social )
same = > n , Dial ( SIP /502 ,10 , m ( radio ) )
same = > n , NoOp ( $ { DIALSTATUS })
same = > n , GotoIf ( $ [ $ { DIALSTATUS }= BUSY ]? busy )
same = > n , Voicemail (502 , u )
same = > n , Goto ( # ,1)
same = > n ( busy ) , PlayBack ( tt - weasels )
same = > n , Goto ( # ,1)

; extension Enfermeria
exten = > 2 ,1 , PlayBack ( custom / asr_enfermeria )
same = > n , Dial ( SIP /500 ,10 , m ( radio ) )
same = > n , GotoIf ( $ [ $ { DIALSTATUS }= BUSY ]? busy )
same = > n , PlayBack ( custom / asr_no_disponible )
same = > n , Goto ( # ,1)

123
CAPÍTULO A. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON A STERISK

same => n ( busy ) , PlayBack ( queue - callswaiting )


same => n , Queue ( cola_enfermeria , , , ,60)
same => n , PlayBack ( custom / asr_max_t_cola )
same => n , Goto ( # ,1)

; extension Directora
exten = > 3 ,1 , PlayBack ( custom / asr_directora )
same = > 2 , Dial ( SIP /506 ,10 , m ( radio ) )
same = > 3 , GotoIf ( $ [ $ { DIALSTATUS }= NOANSWER ]?:5)
same = > 4 , FollowMe ( directora , san )
same = > 5 , Voicemail (506)
same = > 6 , Goto ( # ,1)

; extension Psicologa
; de momento 509 esta redirigido a 501
exten = > 4 ,1 , PlayBack ( custom / asr_psicologa )
same = > 2 , Set ( num = $ { DB ( CFIM /509) })
same = > 3 , GotoIf ( $ [ " $ { num } " = " " ]?:6)
same = > 4 , Set ( num =509)
same = > 5 , Goto (7)
same = > 6 , PlayBack ( custom / asr_desvio )
same = > 7 , Dial ( SIP / $ { num } ,10 , m ( radio ) )
same = > n , PlayBack ( custom / asr_no_disponible )
same = > n , Goto ( # ,1)

; llama desde un telefono exterior a otro pasando por Asterisk


exten = > 5 ,1 , PlayBack ( custom / asr_exterior )
same = > n , NoOp (1 , $ { CHANNEL } , $ { CALLERID ( num ) } - $ { CALLERID ( name ) })
same = > n , Read ( telf , dir - pls - enter ,5)
same = > n , Dial ( DAHDI / g1 / $ { telf } ,15 , m ( radio ) )
same = > n , Hangup ()

; extension menu privado


exten = > 6 ,1 , Goto ( menu - privado ,s ,1)

; extension para colgar


exten = > # ,1 , PlayBack ( custom / asr_despedida )
same = > 2 , Hangup ()

; extension en caso de error al introducir la extension


exten = > i ,1 , PlayBack ( custom / asr_opcion_incorrecta )
same = > 2 , GotoIf ( $ [ $ { k }=3]? s , max )
same = > 3 , Goto (s ,4)

[ menu - privado ]

exten = > s ,1 , PlayBack ( custom / asr_bienvenida_privado )


same = > 2 , Authenticate (12369 , j )
same = > 3 , Background ( custom / asr_menu_privado )

124
A.2. A RCHIVOS DE CONFIGURACIÓN A STERISK

same = > 4 , WaitExten (15 , m ( radio ) )


same = > 5 , Goto (3)

; extension para Salas de Conferencias


exten = > 1 ,1 , PlayBack ( custom / asr_conferencia )
same = > n , MeetMe (101 , pM )
same = > n , Goto ( centralita_ASR , # ,1)

; extension para efectuar espionajes


exten = > 2 ,1 , PlayBack ( custom / asr_escucha )
same = > n , Set ( SPY_EXIT_CONTEXT = centralita_ASR )
same = > n , Chanspy ( , X )
same = > n , Goto ( centralita_ASR , # ,1)

; extension en caso de error al introducir la extension


exten = > i ,1 , PlayBack ( custom / asr_opcion_incorrecta )
same = > 2 , Goto (s ,3)

A.2.4 M ÚSICA EN ESPERA

Se añaden las siguientes líneas al final del archivo /etc/asterisk/musiconhold.conf:


[ default ]
mode = files
directory =/ var / lib / asterisk / mohlau
random = yes

[ radio ]
mode = custom
application =/ var / lib / asterisk / mohlau2 / music . sh

Se crea el archivo /var/lib/asterisk/mohlau2/music.sh que reproduce una


emisora de radio por Internet (shoutcast):
# !/ bin / bash

wget -q -T 120 -O - http ://184.95.62.170:8002 | / usr / bin / madplay -Q


-- mono -R 8000 -a -20 -o raw : - -

A.2.5 B UZÓN DE VOZ

Se añaden las siguientes líneas al final del archivo /etc/asterisk/voicemail.conf:


; Maximum length of a voicemail message in seconds
maxsecs =30

; You can override the default program to send e - mail if you wish , too
mailcmd =/ usr / sbin / sendmail -t

125
CAPÍTULO A. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON A STERISK

[ default ]
; buzones de voz para los residentes
200 = > 123 , residente1 , chiara2026@gmail . com
201 = > 456 , residente2 , chiara2016@gmail . com
202 = > 789 , residente3 , chiara2026@gmail . com

; buzones de voz para todos los trabajadores


501 = > 123 , Recepcion , chiara2026@gmail . com
502 = > 123 , Trabajadora Social , chiara2026@gmail . com
503 = > 123 , Gerocultora 1 , chiara2026@gmail . com
504 = > 123 , Gerocultora 2 , chiara2026@gmail . com
505 = > 123 , Gerocultora 3 , chiara2026@gmail . com
506 = > 123 , Despacho Directora , chiara2026@gmail . com
507 = > 123 , Movil Directora , chiara2026@gmail . com
508 = > 123 , Casa Directora , chiara2026@gmail . com
509 = > 123 , Psicologa , chiara2026@gmail . com
500 = > 123 , Jefa Enfermeras , chiara2026@gmail . com

A.2.5.1 G ESTOR DE CORREO

Se configura el archivo /etc/ssmtp/ssmtp.conf añadiendo las siguientes líneas:


#
# Config file for sSMTP sendmail
#
# The person who gets all mail for userids < 1000
root = securebiometricvoting@gmail . com

# The place where the mail goes . The actual machine name is required
no
# MX records are consulted . Commonly mailhosts are named
mail . domain . com
mailhub = smtp . gmail . com :587

# The full hostname


hostname = securebiometricvoting@gmail . com

# Are users allowed to set their own From : address ?


FromLineOverride = YES

AuthMethod = LOGIN
UseTLS = YES
UseSTARTTLS = YES
AuthUser = securebiometricvoting@gmail . com
AuthPass = isgsbv2011

Se configura el archivo /etc/ssmtp/revaliases añadiendo las siguientes líneas:


# sSMTP aliases
#

126
A.2. A RCHIVOS DE CONFIGURACIÓN A STERISK

# Format : local_account : outgoing_address : mailhub


#
root : securebiometricvoting@gmail . com : smtp . gmail . com :587

A.2.6 F OLLOW M E

Se añaden las siguientes líneas al final del archivo /etc/asterisk/followme.conf:


[ directora ]
musicclass = > radio
context = > usuarios
number = > 507 ,20 ; movil directora
number = > 508 ,20 ; casa directora

A.2.7 S ALA DE C ONFERENCIAS

Se añaden las siguientes líneas al final del archivo /etc/asterisk/meetme.conf:


[ rooms ]

; sala de conferencias para usuarios internos ( trabajadores )


conf = > 600 ,5678

; sala de conferencia centralita Dahdi


conf = > 101 ,14789

A.2.8 C OLAS

Se añaden las siguientes líneas al final del archivo /etc/asterisk/queues.conf:

[ cola_enfermeria ]
strategy = ringall
timeout = 10
retry = 5
periodic - announce = queue - thankyou
periodic - announce - frequency = 8
musicclass = radio

member = > SIP /503 ,1


member = > SIP /504 ,2
member = > SIP /505 ,3

A.2.9 T RANSFERENCIA Y PARKING DE LLAMADAS

Se descomentan las siguientes líneas en el archivo /etc/asterisk/features.conf:

127
CAPÍTULO A. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON A STERISK

[ general ]
parkext = > 700 ; What extension to dial to park
parkpos = > 701 -720 ; What extensions to park calls on .
( defafult parking lot )
; These needs to be numeric , as
Asterisk starts from the start
position
; and increments with one for the next
parked call .
context = > parkedcalls ; Which context parked calls are in
( default parking lot )

128
Instalaciones y configuraciones relacionadas con
B
las aplicaciones Android

B.1 I NSTALACIÓN ENTORNO DE DESARROLLO PARA


A NDROID
Prerrequisitos: Java JDK

El Android SDK utiliza el kit de desarrollo de Java (Java JDK), por lo tanto, es
lo primero que hay que instalar en el servidor. El paquete JDK1 es necesario para
desarrollar aplicaciones y applets en Java (lenguaje que utiliza Android). También
lleva incluido el JRE2 , que sirve para lanzar aplicaciones y applets en Java. Se
descarga el paquete de la página web oficial: http://www.oracle.com/technetwork/
java/javase/downloads/jdk-6u26-download-400750.html, se ubica en el directorio
/usr/src y se instala escribiendo lo siguiente en un terminal:

> cd / usr / src


> chmod + x jdk -6 u26 - linux - x64 . bin
> ./ jdk -6 u26 - linux - x64 . bin

Eclipse

Se descarga la última versión de Eclipse en el servidor desde la página web oficial:


http://www.eclipse.org/downloads/. La última versión disponible al iniciar este
proyecto, y por tanto la instalada, es la Eclipse Classic 3.6.2 (Helios). Lo colocamos en
el directorio /home/ldd/Desarrollo.
1
Java Development Kit
2
Java Runtime Environment

129
CAPÍTULO B. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON LAS
APLICACIONES A NDROID

Eclipse es un ejecutable, no hay que instalarlo. Se modifica el archivo eclipse.ini


para especificar la ruta del JDK instalado antes escribiendo lo siguiente en un terminal:

> cd / home / ldd / Desarrollo / eclipse


> nano eclipse . ini

Se incluyen las siguientes líneas antes de la línea -vmargs:

- vm
/ usr / src / jdk1 .6.0 _26 / bin / java

Android SDK

Se descarga el SDK de Android de la página web oficial: http://developer.


android.com/sdk/index.html. En este caso, se elige la versión 14 para Linux
y tras aceptar la licencia, se guarda y descomprime el fichero en el directorio
home/ldd/Desarrollo.

Antes de instalar nada, hay que declarar en el archivo .bashrc los paths de: android,
java y eclipse, para que el sistema los encuentre. Se incluyen las siguientes líneas al final
del archivo:

> nano ~/. bashrc

export PATH = $ { PATH }:/ home / ldd / Desarrollo / android - sdk - linux_x86 / tools
export PATH = $ { PATH }:/ usr / src / jdk1 .6.0 _26 / bin
export PATH = $ { PATH }:/ home / ldd / Desarrollo / eclipse

A continuación se cierran todos los terminales abiertos, para que haga efecto el path
que se acaba de definir, se abre uno nuevo y se escribe la instrucción:

android

Con esta instrucción se accede al manager de Android, desde el que se puede


instalar y actualizar el SDK, así como crear dispositivos virtuales para realizar las
pruebas de las aplicaciones. En la figura B.1 se puede observar el aspecto del manager
de Android al abrirlo.

130
B.1. I NSTALACIÓN ENTORNO DE DESARROLLO PARA A NDROID

FIGURA B.1: Pantalla inicial del Android Manager.

Para instalar el SDK, se accede a la sección Available Packages y se pulsa el botón


Refresh para que aparezca la lista de todos los paquetes que se pueden instalar. La
pantalla del Manager tendrá ahora el aspecto de la figura B.2. Se seleccionan todos los
paquetes y se pulsa Install Selected.

FIGURA B.2: Pantalla del Android Manager con todos los paquetes disponibles para
instalar.

Al hacer esto, se abre una nueva ventana, como se puede ver en la figura B.3,
para aceptar las licencias de los paquetes que se van a instalar. Se seleccionan todas

131
CAPÍTULO B. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON LAS
APLICACIONES A NDROID

las licencias y se pulsa el botón Install Acepted. Al acabar la instalación, se cierra el


manager y se continua con la instalación del plugin ADT para Eclipse.

FIGURA B.3: Pantalla del Android Manager para instalar licencias.

ADT

El plugin de Android ADT se instala desde el mismo Eclipse siguiendo los pasos
especificados a continuación. Primero se abre Eclipse, y desde la pestaña Help
del menú, se escoge la opción Install New Software y se pulsa el botón Add. En
la ventana que aparece, hay que especificar el nombre del software que se quiere
instalar (Android Plugin) y la dirección de descarga, como se puede ver en la figura B.4.

FIGURA B.4: Ventana para instalar el plugin ADT en Eclipse.

Al encontrar la información en la dirección indicada, aparece en la pantalla el


paquete Developer Tools con los dos plugins que incluye: Android DDMS y Android

132
B.1. I NSTALACIÓN ENTORNO DE DESARROLLO PARA A NDROID

Development, como puede verse en la figura B.5. Se selecciona todo y se pulsa el botón
Next para que se comprueben las dependencias necesarias. En la pantalla siguiente
(figura B.6) se aceptan los términos de la licencia y se pulsa Finish.
.

FIGURA B.5: Pantalla con los paquetes necesarios para instalar el plugin ADT.

133
CAPÍTULO B. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON LAS
APLICACIONES A NDROID

FIGURA B.6: Pantalla para aceptar las licencias de los paquetes del plugin ADT.

Hecho esto, se empieza el proceso de descarga e instalación de los paquetes


indicados antes y de todas las dependencias necesarias para que el ADT funcione
correctamente. Al finalizar este proceso, se debe reiniciar Eclipse.

El último paso consiste en indicar a Eclipse la ubicación del Android SDK. Para
ello seleccionamos la siguiente opción del menú W indow > P ref erences > Android y
donde pone SDK Location pulsamos el botón Browse y especificamos la carpeta donde
está instalado el SDK de Android, que en este caso es:

/ home / ldd / Desarrollo / android - sdk - linux_86

Se pulsa el botón Apply para que se cargue el Android SDK Content Loader. Una
vez finalizado este proceso, aparece la pantalla de la figura B.7 en la que se ve un
listado con todo lo que se ha instalado. Con esto se consigue importar el Android SDK
a Eclipse para disponer de las ayudas necesarias al escribir el código.

134
B.2. B ASE DE DATOS REMOTA

FIGURA B.7: Pantalla de Eclipse con las opciones del Android SDK instaladas.

B.2 B ASE DE DATOS REMOTA

B.2.1 I NSTALACIÓN Y CONFIGURACIÓN

Para instalar el paquete LAMP (Linux, Apache, MySQL, PHP) en el servidor, se escribe
la siguiente línea en un terminal:
> tasksel install lamp - server

Para comprobar si se ha realizado correctamente la instalación, se abre un naveg-


ador, se escribe la dirección del servidor en la barra de direcciones (http://localhost)
y se debe obtener el siguiente resultado por pantalla:
It works !
This is the default web page for this server .
The web server software is running but no content has been added , yet .

A continuación se instala un cliente gráfico para gestionar la base de datos del


servidor de forma más sencilla. Se instala el paquete mysql-navigator desde el gestor
de paquetes Synaptics.

Con todos los paquetes necesarios instalados, ya se puede crear la base de datos.
Para ello, se abre el cliente MySQL Navigator que se acaba de instalar. El primer paso

135
CAPÍTULO B. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON LAS
APLICACIONES A NDROID

es indicar al cliente gráfico la ubicación de la base de datos (localhost en este caso),


y el usuario y contraseña para acceder a la misma. Esto se hace con el menú de la
ventana Server que aparece al abrir el cliente, como se puede ver en la figura B.8.

FIGURA B.8: Definición de la ubicación de la base de datos con usuario y contraseña.

Al hacer esto, aparece la pantalla de la figura B.9. En el apartado Database aparecen


las bases de datos que son para la gestión interna de MySQL (information_schema,
mysql). Para crear la base de datos que se va a utilizar en las aplicaciones, se clica con
el botón derecho encima de Database y aparece la opción Create Database. Se escoge
un nombre para la base de datos (ALCATRAZ en este caso) y ya aparece la nueva base
de datos en el listado anterior.

136
B.2. B ASE DE DATOS REMOTA

FIGURA B.9: Pantalla inicial del cliente gráfico MySQL Navigator.

Por último, hay que crear las tablas que tendrá la base de datos. Como ya se ha
comentado anteriormente, la base de datos del proyecto tiene dos tablas: MyAlerts y
MyCoordinates. Para crear una tabla, se clica con el botón derecho encima del nombre
de la base de datos (ALCATRAZ) y se escoge la opción Execute Query. Al crear las
tablas, hay que definir su nombre, así como el nombre y tipo de todos sus atributos.
En la figura B.10 se ve la query utilizada para crear la tabla de alertas MyAlerts. De
la misma manera, en la figura B.11 se ve la query utilizada para crear la tabla de
coordenadas MyCoordinates. Al ejecutar estas dos querys, se crean las dos tablas y se
añaden a la base de datos ALCATRAZ tal y como se ve en la figura B.12. Con esto, ya
se tiene la base de datos preparada para su utilización desde las aplicaciones Android.

137
CAPÍTULO B. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON LAS
APLICACIONES A NDROID

FIGURA B.10: Pantalla de creación de la tabla de alertas MyAlerts.

138
B.2. B ASE DE DATOS REMOTA

FIGURA B.11: Pantalla de creación de la tabla de coordenadas MyCoordinates.

139
CAPÍTULO B. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON LAS
APLICACIONES A NDROID

FIGURA B.12: Base de datos Alcatraz con sus dos tablas: MyAlerts y MyCoordinates.

El último paso necesario es la creación de los scripts PHP que se utilizan para
gestionar la base de datos.

B.2.2 S CRIPTS PHP

Los scripts PHP que se utilizan para gestionar la base de datos ALCATRAZ deben ubi-
carse en el directorio de Apache, en este caso, /var/www/. Se añaden tantos scripts
como operaciones se quieran realizar, utilizando los siguientes comandos en un termi-
nal:

140
B.2. B ASE DE DATOS REMOTA

> cd / var / www /


> touch nombre_script . php

A continuación se presenta el código de todos los scripts PHP que se han utilizado
en este proyecto, diferenciando los utilizados por cada una de las aplicaciones. Para
realizar pruebas, estos scripts se pueden ejecutar directamente desde un navegador
escribiendo la instrucción con la siguiente nomenclatura en la barra de direcciones:
http :// localhost / nombre_script . php ? arg1 = value1 & arg2 = value2 & arg3 = value3 ...

B.2.2.1 S OFTPHONE RESIDENTES

• insert_alert_user.php

<? php

mysql_connect ( " localhost " ," root " ," t1lq1si " ) ;

mysql_select_db ( " ALCATRAZ " ) ;

try {
$result = mysql_query ( " INSERT INTO MyAlerts ( user , name )
VALUES ( ' " . $_REQUEST [ ' user ' ]. " ',
'" . $_REQUEST [ ' name ' ]. " ') " ) ;

print ( json_encode ( $result ) ) ;


mysql_close () ;
}
catch ( Exception $e ) {
print ( json_encode ( $e ) ) ;
mysql_close () ;
}
?>

• get_alert_user.php

<? php

mysql_connect ( " localhost " ," root " ," t1lq1si " ) ;

mysql_select_db ( " ALCATRAZ " ) ;

try {
$result = mysql_query ( " SELECT id FROM MyAlerts WHERE
name = ' " . $_REQUEST [ ' name ' ]. " ' AND

141
CAPÍTULO B. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON LAS
APLICACIONES A NDROID

user = ' " . $_REQUEST [ ' user ' ]. " '" ) ;

while ( $tmp = mysql_fetch_assoc ( $result ) )


$output []= $tmp ;

print ( json_encode ( $output ) ) ;


mysql_close () ;
}
catch ( Exception $e ) {
print ( json_encode ( $e ) ) ;
mysql_close () ;
}
?>

• update_alert_user.php

<? php

mysql_connect ( " localhost " ," root " ," t1lq1si " ) ;

mysql_select_db ( " ALCATRAZ " ) ;

try {
$result = mysql_query ( " UPDATE MyAlerts SET
user = ' " . $_REQUEST [ ' user ' ]. " ',
name = ' " . $_REQUEST [ ' name ' ]. " ' WHERE
id = " . $_REQUEST [ ' id ' ]. " " ) ;

print ( json_encode ( $result ) ) ;


mysql_close () ;
}
catch ( Exception $e ) {
print ( json_encode ( $e ) ) ;
mysql_close () ;
}
?>

• delete_alert_user.php

<? php

mysql_connect ( " localhost " ," root " ," t1lq1si " ) ;

mysql_select_db ( " ALCATRAZ " ) ;

try {

142
B.2. B ASE DE DATOS REMOTA

$result = mysql_query ( " DELETE FROM MyAlerts WHERE


user = ' " . $_REQUEST [ ' user ' ]. " '" ) ;

print ( json_encode ( $result ) ) ;


mysql_close () ;
}
catch ( Exception $e ) {
print ( json_encode ( $e ) ) ;
mysql_close () ;
}
?>

• update_alert_flag.php

<? php

mysql_connect ( " localhost " ," root " ," t1lq1si " ) ;

mysql_select_db ( " ALCATRAZ " ) ;

try {
$result = mysql_query ( " UPDATE MyAlerts SET
alert_flag = " . $_REQUEST [ ' flag ' ]. " WHERE
user = ' " . $_REQUEST [ ' user ' ]. " '" ) ;

print ( json_encode ( $result ) ) ;


mysql_close () ;
}
catch ( Exception $e ) {
print ( json_encode ( $e ) ) ;
mysql_close () ;
}
?>

• update_battery_flag.php

<? php

mysql_connect ( " localhost " ," root " ," t1lq1si " ) ;

mysql_select_db ( " ALCATRAZ " ) ;

try {
$result = mysql_query ( " UPDATE MyAlerts SET
battery_flag = " . $_REQUEST [ ' flag ' ]. " WHERE
user = ' " . $_REQUEST [ ' user ' ]. " '" ) ;

143
CAPÍTULO B. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON LAS
APLICACIONES A NDROID

print ( json_encode ( $result ) ) ;


mysql_close () ;
}
catch ( Exception $e ) {
print ( json_encode ( $e ) ) ;
mysql_close () ;
}
?>

• insert_coordinates.php

<? php

mysql_connect ( " localhost " ," root " ," t1lq1si " ) ;

mysql_select_db ( " ALCATRAZ " ) ;

try {
$result = mysql_query ( " INSERT INTO MyCoordinates ( user ,
latitude , longitude ) VALUES
( ' " . $_REQUEST [ ' user ' ]. " ', " . $_REQUEST [ ' latitude ' ]. " ,
" . $_REQUEST [ ' longitude ' ]. " ) " ) ;

print ( json_encode ( $result ) ) ;


mysql_close () ;
}
catch ( Exception $e ) {
print ( json_encode ( $e ) ) ;
mysql_close () ;
}
?>

B.2.2.2 S OFTPHONE RECEPCIÓN

• get_alert_coordinates.php

<? php

mysql_connect ( " localhost " ," root " ," t1lq1si " ) ;

mysql_select_db ( " ALCATRAZ " ) ;

try {
$result = mysql_query ( " SELECT
MyCoordinates . user , MyAlerts . name , MyCoordinates . latitude ,

144
B.2. B ASE DE DATOS REMOTA

MyCoordinates . longitude FROM MyAlerts , MyCoordinates


WHERE MyAlerts . user = MyCoordinates . user AND
MyAlerts . alert_flag =1 AND
MyCoordinates . id =( SELECT MAX ( id ) FROM
MyCoordinates WHERE user = MyAlerts . user ) " ) ;

while ( $tmp = mysql_fetch_assoc ( $result ) )


$output []= $tmp ;

print ( json_encode ( $output ) ) ;


mysql_close () ;
}
catch ( Exception $e ) {
print ( json_encode ( $e ) ) ;
mysql_close () ;
}
?>

• get_user_coordinates.php

<? php

mysql_connect ( " localhost " ," root " ," t1lq1si " ) ;

mysql_select_db ( " ALCATRAZ " ) ;

try {
$result = mysql_query ( " SELECT
MyAlerts . user , MyAlerts . name , MyCoordinates . latitude ,
MyCoordinates . longitude FROM MyAlerts , MyCoordinates
WHERE MyCoordinates . user = ' " . $_REQUEST [ ' user ' ]. " '
AND MyCoordinates . id =( SELECT MAX ( id ) FROM
MyCoordinates WHERE user = MyAlerts . user ) " ) ;

while ( $tmp = mysql_fetch_assoc ( $result ) )


$output []= $tmp ;

print ( json_encode ( $output ) ) ;


mysql_close () ;
}
catch ( Exception $e ) {
print ( json_encode ( $e ) ) ;
mysql_close () ;
}
?>

• check_battery_alert.php

145
CAPÍTULO B. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON LAS
APLICACIONES A NDROID

<? php

mysql_connect ( " localhost " ," root " ," t1lq1si " ) ;

mysql_select_db ( " ALCATRAZ " ) ;

try {
$result = mysql_query ( " SELECT COUNT (*) AS num FROM
MyAlerts WHERE battery_flag =1 " ) ;

$tmp = mysql_fetch_assoc ( $result ) ;


print ( json_encode ( $tmp [ ' num ' ] >0) ) ;
mysql_close () ;
}
catch ( Exception $e ) {
print ( json_encode ( $e ) ) ;
mysql_close () ;
}
?>

• get_battery_alerts.php

<? php

mysql_connect ( " localhost " ," root " ," t1lq1si " ) ;

mysql_select_db ( " ALCATRAZ " ) ;

try {
$result = mysql_query ( " SELECT user , name FROM MyAlerts
WHERE battery_flag =1 ORDER BY name " ) ;

while ( $tmp = mysql_fetch_assoc ( $result ) )


$output []= $tmp ;

print ( json_encode ( $output ) ) ;

mysql_close () ;
}
catch ( Exception $e ) {
print ( json_encode ( $e ) ) ;
mysql_close () ;
}
?>

146
B.3. E XTENSIONES DE EMERGENCIA A STERISK

B.3 E XTENSIONES DE EMERGENCIA A STERISK


Las extensiones de emergencia que se utilizan en las aplicaciones se encuen-
tran en el contexto [android_V A] del dialplan de Asterisk, en el archivo
/etc/asterisk/extensions.conf:
[ android_VA ]

exten = > 033 ,1 , Answer ()


same = > n , PlayBack ( beep )
; Origina una llamada entre SIP /501 ( r e c e p c i n ) y CALLERID ( num )
llama a SIP /501 y luego ejecuta la instruccion de la extension
CALLERID ( num ) , prioridad 2
same = > n , Originate ( SIP /501 , exten , usuarios , $ { CALLERID ( num ) } ,2)
same = > n , Hangup ()

exten = > 034 ,1 , Answer ()


same = > n , Read ( num , ,3)
same = > n , Set ( CALLERID ( num ) =034)
same = > n , Dial ( SIP / $ { num } ,10)
same = > n , Hangup ()

exten = > 035 ,1 , Answer ()


same = > n , Read ( num , ,3)
same = > n , Set ( CALLERID ( num ) =035)
same = > n , Dial ( SIP / $ { num } ,10)
same = > n , Hangup ()

147
CAPÍTULO B. I NSTALACIONES Y CONFIGURACIONES RELACIONADAS CON LAS
APLICACIONES A NDROID

148

También podría gustarte