ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA

Anuncio
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
INGENIERÍA TÉCNICA EN INFORMÁTICA DE SISTEMAS
CREADOR DE UN MAPA DE COBERTURA
Realizado por
Álvaro Chapresto Montesinos
Tutor
Dr. José Ramón Portillo Fernández
Departamento
Matemática Aplicada I
Sevilla, Junio de 2009
Creador de un Mapa de Cobertura
INDICE
1.-Definición de objetivos ................................................................................ 3
2.-Análisis de antecedentes y aportación realizada ....................................... 5
3.-Aportación Web ........................................................................................... 7
3.1.-Análisis de requisitos ...................................................................... 7
3.2.-Diseño ............................................................................................. 8
3.3.-Acceso web mediante PC ................................................................ 9
3.4.-Acceso web mediante Dispositivos Móviles ................................. 13
3.5.-API GoogleMaps............................................................................18
3.6.-Almacenamiento en Servidor Web ............................................... 25
4.-Implementación de la Aplicación en Symbian OS .................................. 30
4.1.-Análisis de requisitos .................................................................... 30
4.2.-Decisiones de diseño ..................................................................... 32
4.3.-Funcionamiento general de las Redes GSM, GPRS y WIFI. ........ 33
4.4.-API Symbian OS ........................................................................... 37
5.-Manual de la Aplicación a nivel de usuario ............................................. 78
6.-Pruebas ........................................................................................................ 84
7.-Herramientas .............................................................................................. 90
7.1.-Microsoft Expression Web ............................................................ 90
7.2.-MySQL y phpMyAdmin ............................................................... 91
7.3.-Herramientas necesarias para la programación en Symbian OS. .. 91
8.-Aplicaciones Futuras .................................................................................. 93
9.-Análisis Temporal ...................................................................................... 96
10.-Conclusiones ............................................................................................. 98
11.-Bibliografía ............................................................................................. 100
2
Creador de un Mapa de Cobertura
Capítulo 1:
Definición de objetivos
El objetivo fundamental que tiene este proyecto fin de carrera es medir
los niveles de cobertura de las redes GSM, GPRS y WIFI para poder
visualizarlos en un mapa. Este proceso incluye dos fases: una primara fase
dedicada a la obtención de dichos niveles de cobertura gracias a una aplicación
Symbian OS y una segunda fase dedicada al almacenamiento de los datos en un
servidor Web para poder generar un mapa sobre ellos a través de GoogleMap.
No sólo se almacenarían en el servidor los niveles de cobertura, también
era necesario almacenar las coordenadas, es decir, la longitud y la latitud de la
posición en la cual obtuviéramos estos niveles. La necesidad de almacenar
también la posición de donde realizáramos esta medida está relacionada con la
segunda parte del proyecto. Esta segunda parte del proyecto trataba de generar
un mapa haciendo uso de la API de GoogleMaps en el cual pudiéramos
localizar estas redes y conocer los niveles de cobertura que nos ofrecen de una
manera más visual. Para ello también fue necesario crear un sitio Web en el
cual poder insertar el mapa con el fin de que todo aquel que quisiera pudiera
conocer la cobertura que nos ofrecen las redes GSM, GPRS y WIFI en un lugar
determinado.
3
Creador de un Mapa de Cobertura
Mi intención en un primer instante fue implementar la aplicación en
J2ME (plataforma de Java para desarrollar aplicaciones en dispositivos
móviles) debido a la gran cantidad de documentación, herramientas, ayuda y
ejemplos que se pueden encontrar acerca de este lenguaje. Sin embargo, desde
la capa de Java no es posible acceder a cada una de las partes del dispositivo
móvil que nos permiten acceder a los datos que necesitamos.
Para poder obtener todos los datos necesarios era imprescindible tener
acceso a las rutinas del sistema operativo de nuestro dispositivo móvil, por lo
que la única alternativa era la utilización de Symbian C++ a la hora de
implementar la aplicación. Symbian OS es el sistema operativo que utilizan la
mayoría de dispositivos Nokia, y en concreto el modelo N95 que he utilizado en
el proyecto como dispositivo móvil.
A la hora de enviar los datos necesarios al servidor, mi idea en un
principio fue la utilización de Java 2EE, haciendo uso de Servlets y JDBC para
realizar la conexión a la base de datos e inserción de los mismos. Debido a la
tremenda complejidad que supone encontrar alojamiento Web gratuito que
soporte Java, decidí llevar a cabo esta parte del proyecto utilizando el lenguaje
PHP, soportado por la inmensa mayoría de servidores.
Finalmente comentar que en este proyecto la documentación relacionada
con Symbian OS no ha sido un objetivo primordial, puesto que gracias a un
proyecto de cursos anteriores que me ha servido de guía he podido resolver casi
todas mis dudas en cuanto al comienzo de la programación en Symbian OS.
4
Creador de un Mapa de Cobertura
Capítulo 2:
Análisis de antecedentes y aportación
realizada
En este proyecto siempre he querido destacar que podemos diferenciar
dos grandes partes: la primera de ellas relacionada con toda la aportación Web,
es decir, servidor, base de datos, páginas Web, PHP etc… y la segunda y más
importante relacionada con la programación en Symbian OS.
Al ser la aplicación en Symbian OS el objetivo fundamental del
proyecto, es sin duda la parte a la cual he dedicado más tiempo. Para comenzar
a introducirme en la programación en Symbian OS utilicé como referencia un
proyecto fin de carrera que fue expuesto en junio de 2007. Este proyecto incluía
en la documentación una guía que indicaba a los futuros programadores como
realizar su primera aplicación en Symbian OS utilizando como entorno de
desarrollo integrado (IDE) Microsoft Visual .NET 2003 con un plug-in
denominado Carbide.vs, el cual fue retirado por Nokia, necesario para poder
realizar proyectos en Symbian OS.
5
Creador de un Mapa de Cobertura
Debido a que han pasado dos años desde junio de 2007, todo el mundo
relacionado con los dispositivos móviles, y más concretamente con Nokia y
Symbian OS, ha experimentado una gran evolución. Es por este motivo por el
que a la hora de elegir el entorno de desarrollo a través del cual iba a
implementar mi aplicación en Symbian OS decidí decantarme por Carbide .c++
ya que es un software totalmente gratuito y actualizado que utilizan hoy en día
casi la totalidad de los programadores en Symbian OS. Por tanto, creo que
puede servir de ayuda a futuros programadores el hecho de que la aplicación en
Symbian OS de este proyecto esté realizada con este entorno de desarrollo, ya
que prácticamente toda información disponible sobre Symbian OS está
relacionada con Carbide.c++.
Al ir constantemente desarrollando Nokia nuevas funcionalidades para
los dispositivos móviles, las versiones de Symbian OS están en continua
actualización y por tanto la API y las SDK incluyen cada vez más información.
La versión 9.2 de Symbian OS es la que yo he utilizado junto con la SDK s60
3erd edition FP1 para poder llevar a cabo este proyecto. Esta versión es en estos
momentos una de las más actualizadas junto a la serie s60 5th edition. Una de
las innovaciones que añade esta API de Symbian OS es el acceso a redes WIFI
y a dispositivos GPS. Esta API también incluye nuevas clases para poder
acceder con más detalle aún si cabe a los niveles de cobertura de las redes GSM
y GPRS. Hace algún tiempo, para poder acceder al nivel de cobertura GSM
había que utilizar una librería y una serie de métodos de la SDK apara
desarrolladores de Nokia 9200 Comunicator, la cual fue retirada. En la
aplicación Symbian OS de este proyecto se ofrecen las clases y los métodos
necesarios para acceder a los niveles de cobertura GSM, GPRS y WIFI así
como a las coordenadas GPS de los dispositivos móviles más actuales de la
serie s60 de Nokia, es decir, la serie más extendida.
Englobando un poco las dos grandes partes en las cuales puede dividirse
este proyecto, creo que puede ser interesante disponer de una aplicación que
relacione dos grandes conceptos como son Symbian OS y GoogleMap,
haciendo posible obtener los niveles de cobertura GSM, GPRS y sobre todo
WIFI que es una tecnología más actual, de un determinado lugar para poder
almacenar dichos valores en un servidor Web con el fin de visualizar los datos a
través de un mapa. Es una manera de acceder a dichos niveles de cobertura
completa y sencilla para cualquier tipo de usuario.
6
Creador de un Mapa de Cobertura
Capítulo 3:
Aportación Web
En este apartado trataré de detallar toda la parte del proyecto que está
relacionada con la Web, comenzando por el diseño de la páginas Web donde
queremos visualizar los niveles de cobertura obtenidos tanto en un PC como en
un dispositivo móvil, enumerando y comentando cada una de las clases y
métodos de la API de GoogleMaps que hacen posible generar el mapa, los
marcadores y las ventanas de información necesarias y finalizando por la base
de datos instalada en el servidor cuya función es la de almacenar los valores de
las coordenadas y niveles de cobertura enviados desde el dispositivo móvil.
3.1.-Análisis de Requisitos
Toda la aportación Web existente en el proyecto también está pensada
para que sirva de ayuda al usuario, mostrando los niveles de cobertura GSM,
GPRS y WIFI obtenidos de una manera más visual situándolos en un mapa. A
la hora de realizar cualquier tipo de aplicación Web es fundamental realizar un
7
Creador de un Mapa de Cobertura
estudio que nos permita obtener toda la información necesaria. El mundo
relacionado con las aplicaciones Web es bastante extenso, existiendo mucha
información acerca de todas las funcionalidades que pueden añadirse a una
aplicación Web, pero la parte principal de este proyecto es la relacionada con la
aplicación Symbian OS. Por este motivo he creído oportuno realizar una
aplicación Web simple, haciendo uso únicamente de hojas de estilo y capas de
posicionamiento. Los requisitos que debe cumplir la aplicación Web de este
proyecto son los siguientes:

Facilidad de Uso
La aplicación Web debe ser lo más sencilla y clara posible ya su única
función es la de mostrar en un mapa una serie de valores, para que pueda servir
de ayuda a cualquier tipo de persona.

Transparencia al Usuario
Lo único que debe mostrar la aplicación al usuario es la información
acerca de los niveles de cobertura obtenidos y el mapa mostrando la ubicación
de estos. Todo lo relacionado a como se almacenan los niveles y las
coordenadas en la base de datos debe quedar oculto para el usuario.
3.2.-Diseño
El diseño empleado para realizar ambas páginas Web es muy sencillo y
claro ya que esta basado únicamente en el uso de hojas de estilo y capas de
posicionamiento. La única función que tienen ambas Web es la de mostrar
información en un mapa acerca de cada uno de los niveles de cobertura
obtenidos mediante la aplicación Symbian OS instalada en el dispositivo móvil
por lo que no es necesario añadir ningún otro tipo de funcionalidad a cada una
de las Web.
El código para cada una de las páginas Web es casi idéntico con la
excepción de que la página Web la cual es accedida desde un PC está centrada
y posee un determinado margen tanto a izquierda como a derecha y la página
Web la cual es accedida desde un dispositivo móvil no posee ningún tipo de
margen ocupando todo el ancho de página disponible.
8
Creador de un Mapa de Cobertura
La idea de realizar una Web para poder acceder desde un PC y una Web
dedicada al acceso desde un dispositivo móvil esta relacionada con la
posibilidad que están añadiendo hoy día los dispositivos móviles de conectarse
a Internet a través de un dispositivo WIFI sin coste alguno y con el tamaño de la
pantalla de cada tipo de dispositivo. Esta idea la detallaré más adelante en su
respectivo apartado.
3.3.-Acceso Web mediante PC
El código de la página Web donde queremos visualizar a través de un
PC los niveles de cobertura obtenidos es el siguiente:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Mapa de Cobertura</title>
<script
src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAYXgE2
vAAc2qhHiKrZMlnUxSY91aDXaiJPM7k4bLxEmyoVJ0ZIRRJ56TazbJMGN-CkuDkFwVd5A8uA&hl=es "
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("googleMap"));
map.setCenter(new GLatLng(37.388163, -5.996475), 15);
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
<?php
$link=mysql_connect("mysql8.000webhost.com","a1285122_alvaro","merequet
engue1") or die ("Error conexión");
mysql_select_db("a1285122_proyect", $link) or die ("Error selección
BD");
$sql = "SELECT * FROM datos;";
$result = mysql_query($sql) or die ("La consulta <b>$sql</b> tiene
algún error");
while ($row = mysql_fetch_array($result)){
$aux3 = $row['coberturagsm'];
9
Creador de un Mapa de Cobertura
if(strpos($row['coberturagsm'], ",")!=false){
$ind3 = strpos($row['coberturagsm'], ",");
$aux3 = $row['coberturagsm'];
$aux3[$ind3] = ".";
}
$aux4 = $row['coberturagprs'];
if(strpos($row['coberturagprs'], ",")!=false){
$ind4 = strpos($row['coberturagprs'], ",");
$aux4 = $row['coberturagprs'];
$aux4[$ind4] = ".";
}
$aux5 = $row['coberturawlan'];
if(strpos($row['coberturawlan'], ",")!=false){
$ind5 = strpos($row['coberturawlan'], ",");
$aux5 = $row['coberturawlan'];
$aux5[$ind5] = ".";
}
$ind1 = strpos($row['latitud'], ",");
$ind2 = strpos($row['longitud'], ",");
$aux1 = $row['latitud'];
$aux2 = $row['longitud'];
$aux1[$ind1] = ".";
$aux2[$ind2] = ".";
echo "var latlng = new GLatLng(";echo $aux1;echo ",";echo $aux2;
echo");";
echo "var opciones = { title: \"Niveles de Cobertura\", draggable:
false, bouncy: false};";
echo "var opcionesven = { noCloseOnClick: false};";
echo "var marcador";echo $row['id'];echo " = new GMarker(latlng,
opciones);";
echo "GEvent.addListener(marcador";echo $row['id'];echo ", \"click\",
function() {";
echo "marcador";echo $row['id'];echo ".openInfoWindow(\"Cobertura GSM:
";echo $row['coberturagsm'];echo " %<br/> Cobertura GPRS: "; echo
$row['coberturagprs'];echo " %<br/>Cobertura WIFI: ";echo
$row['coberturawlan'];echo " %\", opcionesven); });";
echo "map.addOverlay(marcador";echo $row['id'];echo ");";
}
mysql_close($link);
?>
}
}
//]]>
</script>
<style type="text/css">
#envolvente {
width: 650px;
10
Creador de un Mapa de Cobertura
padding: 0px;
margin-top: 10px;
margin-right: auto;
margin-left: auto;
}
#encabezado {
color: #FFFFFF;
background-color: #00A4CC;
}
#bienvenida {
border-width: medium;
border-color: #00A4CC;
background-color: #D9E6FF;
padding: 0px;
width: 171px;
float: left;
border-right-style: solid;
}
#mapadecobertura {
border-width: medium;
border-color: #00A4CC;
padding: 0px;
width: 171px;
float: right;
background-color: #99CCFF;
border-left-style: solid;
}
#piedepagina {
color: #FFFFFF;
background-color: #FF9D5B;
}
p, h1 {
margin: 0px 10px 10px 10px;
}
h1 {
font-size: 1.5em;
padding-top: 10px;
}
h2 {
font-size: 1.2em;
padding-top: 10px;
padding-left: 10px;
}
.style1 {
font-family: "Comic Sans MS";
font-size: 2em;
}
.style2 {
color: #0000CE;
font-family: Candara;
}
.style4 {
11
Creador de un Mapa de Cobertura
color: #0000FF;
font-family: Candara;
}
.style5 {
margin-right: 0px;
}
</style>
<link rel="shortcut icon"
href="http://alumno.us.es/a/alvchamon/favicon1.ico" type="image/x-icon"
/>
</head>
<body onload="load()" onunload="GUnload()">
<div id="envolvente">
<div id="encabezado">
<h1 class="style1">Mapa de Cobertura</h1>
</div>
<div id="bienvenida">
<h2 class="style4">Bienvenido a mi Pagina Web</h2>
<p><strong>Este es el Sitio Web de mi Proyecto Fin de Carrera. En este
espacio quiero daros a todos la Bienvenida y agradecer de antemano que
lo visiteis.</strong></p></div>
<div id="mapadecobertura">
<h2 class="style2">Aplicacion</h2>
<p><strong>La principal funcion que tiene la Web es ofrecer la
posibilidad a todos los que la visiten de conocer los niveles de
cobertura WIFI, GSM y GPRS de las distintas zonas que se pueden
observar en el mapa gracias a la API de GoogleMap y a la aplicacion
Symbian que hace posible obtener dichos niveles. </strong></p></div>
<div id="googleMap" style="width:300px; height:366px; float:left"
class="style5"></div>
<br clear="all"/>
<div id="piedepagina">Proyecto Fin de carrera. Alvaro Chapresto
Montesinos</div>
</div>
</body>
</html>
En el código se puede observar lo que he comentado anteriormente
acerca del uso de hojas de estilo y capas de posicionamiento para realizar la
página Web.
Para poder acceder a esta Web tenemos que introducir en el explorador
la siguiente dirección: http://alvaro.netne.net. Una vez introducida dicha
dirección accedemos a la Web que tendría la siguiente forma:
12
Creador de un Mapa de Cobertura
3.4.-Acceso Web mediante Dispositivos Móviles
Como ya he comentado anteriormente, era necesaria la realización de
una página Web para poder visualizar los niveles de cobertura obtenidos la cual
fuera accedida desde un dispositivo móvil.
El código de dicha página Web es el siguiente:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Mapa de Cobertura Móviles</title>
<script
src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAYXgE2
13
Creador de un Mapa de Cobertura
vAAc2qhHiKrZMlnUxSY91aDXaiJPM7k4bLxEmyoVJ0ZIRRJ56TazbJMGN-CkuDkFwVd5A8uA&hl=es "
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("googleMap"));
map.setCenter(new GLatLng(37.388163, -5.996475), 15);
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
<?php
$link=mysql_connect("mysql8.000webhost.com","a1285122_alvaro","merequet
engue1") or die ("Error conexión");
mysql_select_db("a1285122_proyect", $link) or die ("Error selección
BD");
$sql = "SELECT * FROM datos;";
$result = mysql_query($sql) or die ("La consulta <b>$sql</b> tiene
algún error");
while ($row = mysql_fetch_array($result)){
$aux3 = $row['coberturagsm'];
if(strpos($row['coberturagsm'], ",")!=false){
$ind3 = strpos($row['coberturagsm'], ",");
$aux3 = $row['coberturagsm'];
$aux3[$ind3] = ".";
}
$aux4 = $row['coberturagprs'];
if(strpos($row['coberturagprs'], ",")!=false){
$ind4 = strpos($row['coberturagprs'], ",");
$aux4 = $row['coberturagprs'];
$aux4[$ind4] = ".";
}
$aux5 = $row['coberturawlan'];
if(strpos($row['coberturawlan'], ",")!=false){
$ind5 = strpos($row['coberturawlan'], ",");
$aux5 = $row['coberturawlan'];
$aux5[$ind5] = ".";
}
$ind1 = strpos($row['latitud'], ",");
$ind2 = strpos($row['longitud'], ",");
$aux1 = $row['latitud'];
$aux2 = $row['longitud'];
$aux1[$ind1] = ".";
$aux2[$ind2] = ".";
14
Creador de un Mapa de Cobertura
echo "var latlng = new GLatLng(";echo $aux1;echo ",";echo $aux2;
echo");";
echo "var opciones = { title: \"Niveles de Cobertura\", draggable:
false, bouncy: false};";
echo "var opcionesven = { noCloseOnClick: false};";
echo "var marcador";echo $row['id'];echo " = new GMarker(latlng,
opciones);";
echo "GEvent.addListener(marcador";echo $row['id'];echo ", \"click\",
function() {";
echo "marcador";echo $row['id'];echo ".openInfoWindow(\"Cobertura GSM:
";echo $row['coberturagsm'];echo " %<br/> Cobertura GPRS: "; echo
$row['coberturagprs'];echo " %<br/>Cobertura WIFI: ";echo
$row['coberturawlan'];echo " %\", opcionesven); });";
echo "map.addOverlay(marcador";echo $row['id'];echo ");";
}
mysql_close($link);
?>
}
}
</script>
<style type="text/css">
#envolvente {
width: 100%;
padding: 0px;
margin-top: 0px;
float: left;
}
#encabezado {
color: #FFFFFF;
background-color: #00A4CC;
width: 100%;
}
#bienvenida {
border-width: medium;
border-color: #00A4CC;
background-color: #D9E6FF;
padding: 0px;
width: 50%;
float: left;
border-right-style: solid;
border-left-style: none;
}
#mapadecobertura {
border-width: medium;
border-color: #00A4CC;
padding: 0px;
width: 49%;
float: left;
15
Creador de un Mapa de Cobertura
background-color: #99CCFF;
border-left-style: solid;
border-right-style: none;
}
#piedepagina {
color: #FFFFFF;
background-color: #FF9D5B;
width: 100%;
}
p, h1 {
margin: 0px 10px 10px 10px;
}
h1 {
font-size: 1.5em;
padding-top: 10px;
}
h2 {
font-size: 1.2em;
padding-top: 10px;
padding-left: 10px;
}
.style1 {
font-family: "Comic Sans MS";
font-size: 2em;
}
.style2 {
color: #0000CE;
font-family: Candara;
}
.style4 {
color: #0000FF;
font-family: Candara;
}
.style5 {
margin-right: 0px;
}
</style>
<link rel="shortcut icon" href="../favicon1.ico" type="image/xicon" />
</head>
<body onload="load()" onunload="GUnload()">
<div id="envolvente">
<div id="encabezado">
<h1 class="style1">Mapa de Cobertura</h1>
</div>
<div id="mapadecobertura">
<h2 class="style2">Aplicacion</h2>
<p><strong>La principal funcion que tiene la Web es ofrecer la
posibilidada todos los que la visiten de conocer los niveles de
cobertura WIFI, GSM y GPRS de las distintas zonas que se pueden
observar en el mapa gracias a la API de GoogleMap y a la aplicacion
Symbian que hace posible obtener dichos niveles. </strong></p></div>
<div id="bienvenida">
16
Creador de un Mapa de Cobertura
<h2 class="style4">Bienvenido a mi Pagina Web</h2>
<p><strong>Este es el Sitio Web de mi Proyecto Fin de Carrera. En este
espacio quiero daros a todos la Bienvenida y agradecer de antemano que
lo visiteis.</strong></p></div>
<div id="googleMap" style="width:100%; height:348px; float:left"
class="style5" ></div>
</div>
</body>
</html>
En el código se puede observar como se hace uso de hojas de estilo y
capas de posicionamiento para realizar la Web pero con la salvedad de que esta
página Web utiliza todo el ancho de la pantalla. Esta idea esta aplicada debido a
que el tamaño de pantalla de un dispositivo móvil es mucho menor que el de
cualquier pantalla de un PC.
Al estar utilizando la página Web el 100% del ancho de la pantalla, se
adapta perfectamente al tamaño de pantalla de cada dispositivo móvil de forma
que en caso de que dispongamos de un ancho de pantalla muy pequeño, los
bloques de información de la Web se irían apilando para evitar que se produzca
scroll horizontal, que en un dispositivo móvil es más molesto que en un PC.
También surgía la necesidad de realizar esta Web para que todo el que
tenga la posibilidad de acceder a Internet desde su dispositivo móvil pueda
consultar los niveles de cobertura obtenidos en un determinado punto.
Para acceder a dicha página Web desde un dispositivo móvil tenemos
que
colocar
en
el
navegar
la
siguiente
dirección:
http://alvaro.netne.net/moviles.htm. Una vez introducida la dirección nos
aparecerá dicha página Web que posee la siguiente apariencia:
17
Creador de un Mapa de Cobertura
Como se puede observar en la imagen, la página Web aprovecha todo el
ancho de pantalla disponible que puede parecer exagerado a la hora de acceder
a dicha Web desde un PC, pero que sin embargo a la hora de acceder a través de
un dispositivo móvil se adapta perfectamente debido al reducido tamaño de su
pantalla.
3.5.-API GoogleMaps
Debido a que la idea fundamental del proyecto es la obtención de una
serie de niveles de cobertura y plasmarlos en un mapa para que puedan ser de
utilidad de una manera visual, es necesaria la utilización de la API de
GoogleMaps.
Para poder hacer uso de la API de GoogleMaps es necesario registrarte
así como indicar el directoria Web donde se van a almacenar la páginas que van
a mostrar mapas y demás contenidos relacionados con Google. Una vez hecho
esto, obtendremos la clave necesaria para, haciendo uso de JavaScript, utilizar
la API de GoogleMaps en nuestra Web.
18
Creador de un Mapa de Cobertura
La API de GoogleMaps esta compuesta por infinidad de clases,
métodos, atributos, constantes, estructuras de datos… etc. Es por este motivo
por lo que yo en este apartado sólo quiero hacer referencia a la parte de la API
de GoogleMaps que he utilizado a la hora de desarrollar este proyecto. Esta
parte sería la siguiente:
- Clase GMap2(container, opts?): Crea un mapa nuevo dentro
del contenedor HTML en cuestión, que generalmente suele ser un
elemento DIV. En el atributo container es donde tenemos que colocar el
id de nuestra etiqueta DIV contenedora. El atributo opts? Se puede
obviar puesto que hace referencia a las diferentes opciones que podemos
elegir como el tipo del mapa, tamaño etc. Esta clase contiene los
siguientes métodos:
1.- addControl(control, position?): Añade un objeto que
implemente la interfaz GControl al mapa. El atributo position? Se puede
obviar, en este caso se aplicará una posición predeterminada al control.
2.- setCenter(center, zoom?, type?): Define la vista del mapa de
acuerdo al centro especificado en el atributo center. El atributo zoom
hace referencia al zoom que tendrá el mapa al cargarse en la Web y el
atributo type haría referencia al tipo de mapa. Ambos atributos se
pueden obviar.
3.- addOverlay(overlay): Este método añade una superposición
al mapa y activa el evento addoverlay. Las superposiciones son
necesarias a la hora de añadir por ejemplo un marcador, como es nuestro
caso.
4.- openInfoWindowHtml(latlong, html, opts?): Abre una
ventana de información en el punto especificado del mapa a través del
atributo latlong que es un objeto de la clase GLatLng. El atributo html
hace referencia al texto HTML que vamos a mostrar. El atributo opts?
se puede obviar, aunque hace referencia a las diferentes opciones que
podemos agregar a dicha ventana. Esta opciones se establecen a través
de un objeto de la clase GInfoWindowsOptions.
- Clase GInfoWindowsOptions: las instancias de esta clase se
utilizan como ya he comentado anteriormente en el atributo opts? de las
19
Creador de un Mapa de Cobertura
clases GMap2 en el método openInfoWindowHtml. Las instancias de
esta clase se crean como un objeto literal de JavaScript. Esta clase
presenta las siguientes propiedades:
1.- MaxWidth: Representa la anchura máxima de la ventana de
información en píxeles.
2.- noCloseOnClick: Esta propiedad es de tipo boolean e indica si
la ventana debe cerrarse al hacer click en un lugar diferente a un
marcador. “True” indicaría que la ventana no se cerrase.
- Clase GMarker(latlong, icon?, inert?): esta clase establece un
marcador en el mapa. El marcador utilizado se establece en la posición
indicada a través del atributo latlong de la clase GLatLng. El atributo
icon? hace referencia al icono que queremos mostrar como marcador y
es un objeto de la clase icon que se puede obviar, en tal caso se utilizará
como marcador un icono por defecto. El atributo inert? es de tipo
boolean y hace referencia a la posibilidad de que se pueda hacer clic en
el marcador y activar un evento. Esta clase contiene los siguientes
métodos:
1.- openInfoWindowHtml(content, opts?): Abre una ventana de
información sobre el icono el marcador al hacer clic en el marcador. El
atributo content hace referencia al texto HTML que aparecerá en la
ventana de información mientras el atributo opts?, que se puede obviar,
está relacionado con la propiedad GInfoWindowOptions.maxWidth,
que es la única que en este caso se puede añadir.
2.- blindInfowindowHtml(content, opts?): Enlaza en texto
HTML indicado a través del atributo content. Este texto HTML se
mostará automáticamente en la venatana de información al hacer clic
sobre el marcador. El atributo opts? sigue haciendo referencia a las
opciones que se pueden añadir, pudiendo ser obviado.
3.- setLatLng(latlng): Este método define las coordenadas
geográficas del punto en el cual está anclado el marcador a través del
atributo latlng, que es de la clase GLatLng.
- Clase GMarkerOptions: Se usan instancias de esta clase en el
20
Creador de un Mapa de Cobertura
atributo opts? para el constructor de la clase GMarker. No existe
constructor para esta clase, por sus instancias se crean como un objeto
literal de JavaScript. Como indica el nombre del propio atributo, las
priedades se pueden obviar. Las propiedades que admite esta clase son
las siguientes:
1.- icon: Elige el icono para el marcador. Esta propiedad es un
objeto de la clase GIcon.
2.- tittle: Esta propiedad aparecerá como información de
herramienta en el marcador, es decir, aparecerá cuando situemos el
puntero del ratón sobre el marcador en cuestión.
3.- draggable: Esta propiedad habilita o deshabilita la
posibilidad de arrastrar el marcador. Es un valor de tipo boolean, en caso
de valer true posibilita que el marcador sea arrastrado.
4.- bouncy: Consiste en habilitar o deshabilitar que el marcador
rebote hacia arriba o hacia abajo cuando termine de ser arrastrado.
- Clase GIcon(copy?, image?): Se utiliza para crear el icono que
queremos que aparezca como marcador en el mapa. Ambos atributos
son opcionales y por tanto se pueden obviar. El atributo copy? Indica si
sus propiedades se copiaran y el atributo image? define el valor de la
propiedad image que se detalla a continuación. Esta clase contiene las
siguientes propiedades:
1.- image: Indica la URL de la imagen en primer plano del icono
que aparecerá como marcador.
2.- iconsize: Indica el tamaño en px de la imagen del icono.
- Clase GLatLng(lat, long, unbouned?): Esta clase genera un
punto de acuerdo a una latitud y una longitud de coordenadas
geográficas pasadas como argumento. El atributo unbouned? Es
opcional y es de tipo boolen. En caso de valer true las coordenadas se
usan tal como se pasan mientras que en caso contrario la laitud está
obligada a valer entre -90 grados y 90 grados mientras que la longitud
deberá valer entre -180 grados y 180 grados. Esta clase posee los
siguientes métodos:
21
Creador de un Mapa de Cobertura
1.- lat(): Devuelve la coordenada de latitud.
2.- lng(): Devuelve la coordenada de longitud.
3.- Equals(other): Devuelve true si el tamaño other pasado como
argumento tiene componentes iguales. Por lo que other debe ser un
objeto de la clase GLatLng.
- Interfaz GControl(printable?, selectable?): Esta interfaz
implementa todos los controles. Puedes implementarla para indicar un
control personalizado para el mapa. El atributo printable? Es opcional e
indica que el control deber estar visible en el mapa impreso. El atributo
selectable? también se puede obviar e indica que el control contendrá
texto seleccionable. Esta interfaz contiene los siguientes métodos:
1.- GSmallMapControl(): Este método crea un control con
botones para hacer desplazamiento en cuatro direcciones y acercar o
alejar el mapa.
2.- GLargeMapControl(): Es un método similar al anterior pero
incluye barra de desplazamiento.
3.- GSmallZoomControl(): Añade al mapa un control con
botones para acercar o alejar la imagen.
- Función GBrowserIsCompatible(): Esta función de vuelve un
valor de tipo boolean que indica si el navegador utilizado es compatible
con la biblioteca de la API de GoogleMaps.
- Función GUnload(): Esta función hace que la API de
googleMaps limpie estructuras de datos internas para liberar memoria.
Es el gestor de eventos “unload” de la página Web el encargado de
llamar a esta función.
- Namespace GEvent: Este espacio de nombres contiene
funciones que se utilizan para registrar gestores de eventos
personaliados. Posee el siguiente método:
1.- addListener(source, event, handler): registra un gestor de
22
Creador de un Mapa de Cobertura
eventos para un evento personalizado en el objeto origen. El atributo
source hace referencia al objeto de la clase GMarker, mientras que el
atributo event indica el evento a realizar y el atributo handler es una
función que realiza una tarea al producirse dicho evento sobre el
marcador.
La parte del código HTML que está relacionada con la API de
GoogleMaps es la siguiente:
<script
src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAYXgE2
vAAc2qhHiKrZMlnUxSY91aDXaiJPM7k4bLxEmyoVJ0ZIRRJ56TazbJMGN-CkuDkFwVd5A8uA&hl=es "type="text/javascript"></script>
En esta primera parte del código es donde se indica cual es nuestra API
Key para que aparezcan correctamente todos mapas en las páginas del servidor
indicado al registrarnos.
<script type="text/javascript">
//<![CDATA[
function load() {
Esta es la funcion que comprueba si el navegador es compatible con la
API de GoogleMaps, en ese caso se ejecuta cada una de las sentencias.
if (GBrowserIsCompatible()) {
var map=new GMap2(document.getElementById("googleMap"));
Almacenamos en la variable map un mapa que creamos mediante la
clase GMap2 estableciendo dicho mapa en la capa div cuyo id es “googleMap”.
map.setCenter(new GLatLng(37.388163, -5.996475), 15);
A través del método setCenter y el parámetro que indica las coordenadas
centramos nuestro mapa.
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
Utilizando el método addControl y los constructores de controles
GsmallMapControl() y GMapTypeControl() añadimos ambos controles al
mapa.
23
Creador de un Mapa de Cobertura
var latlng = new GLatLng(37.388163, -5.996475);
var opciones = { title: "Niveles de Cobertura", draggable: false,
bouncy: false};
Creamos ahora dos variables donde vamos a almacenar las coordenadas
de nuestro marcador a través de la clase GLatLng y las opciones de dicho
marcador. Estas opciones se declaran como un objeto literal de JavaScript.
var opcionesven = { noCloseOnClick: false};
Almacenamos en una variable las opciones que va a tener nuestra
ventana de información asociada al marcador. Estas opciones deben declararse
como un objeto literal de JavaScript.
var marcador = new GMarker(latlng, opciones);
Creamos una variable marcador donde almacenaremos el objeto de la
clase GMarker pasando como argumento sus coordenadas y sus propiedades.
GEvent.addListener(marcador, "click", function() {
marcador.openInfoWindow("Esto es una prueba,<br/> aqui es donde vamos a
colocar<br/> los niveles de cobertura", opcionesven); });
Ahora a través de GEvent y el método addListener asociamos un evento
al marcador, hacer click con el ratón, especificamos que al cumplirse el evento
se abra una ventana de información y asociamos a dicha ventana de
información las propiedades anteriormente declaradas.
map.addOverlay(marcador);
Añadimos el marcador al mapa.
}
}
//]]>
</script>
Finalmente colocamos la marca que cierra el código JavaScript.
24
Creador de un Mapa de Cobertura
3.6.-Almacenamiento en Servidor Web
Uno de los objetivos de este proyecto, como se ha comentado
anteriormente, es poder establecer una serie de marcadores en un mapa
haciendo uso de la API de GoogleMap de manera que al pulsar con el ratón en
cada uno de ellos se abra una ventana de información en el que se muestren los
niveles de cobertura GSM, GPRS y WIFI.
Para poder llevar a cabo esta parte del proyecto, surgía la necesidad de
disponer de alojamiento Web gratuito para poder subir las páginas Web. Otra
necesidad fundamental era que el servidor soportase PHP, ya que dentro del
código JavaScript de ambas páginas Web se ejecuta una función PHP que se
detalla más adelante.
El último y más importante de los requisitos que debía cumplir el
alojamiento Web era que me permitiese acceder a las herramientas MySQL y
phpMyAdmin para poder crear una base de datos en el servidor donde poder
almacenar cada uno de los niveles de cobertura GSM, GPRS y WIFI así como
la latitud y la longitud del punto en el que se realizase la media de dichos
niveles.
A través de http://www.0000webhost.com se puede solicitar alojamiento
Web de manera totalmente gratuita cumpliendo dicho alojamiento con todos los
requisitos que he comentado anteriormente. El directorio Web que me
concedieron fue http://alvaro.netne.net.
La base de datos es muy simple puesto que dispone de una única tabla,
denominada “datos”, con seis campos en los cuales almaceno un valor de tipo
entero que representa el id de cada fila siendo los cinco restantes de tipo varchar
para almacenar los niveles de cobertura y las coordenadas del punto. La
estructura de la tabla se puede observar en la siguiente figura:
25
Creador de un Mapa de Cobertura
Una vez creada la base de datos en la cual podemos insertar cada uno de
los valores necesarios, el siguiente paso sería averiguar como enviar los datos
sin que el usuario tuviera que rellenar algún tipo de formulario, es decir,
conectándose directamente a una url. Para ello fue necesario implementar una
función en PHP que realizara la conexión a la base de datos, seleccionara la
tabla e insertase cada uno de los valores indicados por la url en el campo
correspondiente, siempre que no se encuentren ya insertados. La función PHP
que realiza el tratamiento de los datos es la siguiente:
<?php
//1. Crear conexión a la Base de Datos
$conexion=
mysql_connect("mysql8.000webhost.com","a1285122_alvaro","merequetengue1
");
if (!$conexion) {
die("Fallo la conexión a la Base de Datos: " . mysql_error());
}
//2. Seleccionar la Base de Datos a utilizar
$seleccionar_bd = mysql_select_db("a1285122_proyect", $conexion);
if (!$seleccionar_bd) {
die("Fallo la selección de la Base de Datos: " . mysql_error());
}
26
Creador de un Mapa de Cobertura
//3. Tomar los campos provenientes del Formulario
$coberturagsm = $_GET['coberturagsm'];
$coberturagprs = $_GET['coberturagprs'];
$coberturawlan = $_GET['coberturawlan'];
$latitud = $_GET['latitud'];
$longitud = $_GET['longitud'];
if(strpos($longitud, "#oP9")!=false){
$cadena = str_replace( "#oP9", "", $longitud );
$longitud = $cadena;
}
//comprobar si ya estan los datos insertados
$sql = "SELECT * FROM datos;";
$result = mysql_query($sql) or die ("La consulta <b>$sql</b> tiene
algún error");
$enc = false;
while ($row = mysql_fetch_array($result) and
$enc == false){
if( $coberturagsm == $row['coberturagsm'] and $coberturagprs ==
$row['coberturagprs'] and $coberturawlan == $row['coberturawlan'] and
$latitud == $row['latitud'] and $longitud == $row['longitud'] )
$enc = true;
}
if($enc == false){
//4. Insertar campos en la Base de Datos, ya que no están ya
almacenados los valores
$insertar
=
mysql_query("INSERT
INTO
datos
(id,
coberturagsm,
coberturagprs, coberturawlan, latitud, longitud)
VALUES (NULL, '$coberturagsm', '$coberturagprs', '$coberturawlan',
'$latitud', '$longitud')", $conexion);
if (!$insertar) {
die("Fallo en la insercion de registro en la Base de Datos: " .
mysql_error());
}
}
else{
$actualizar = mysql_query("UPDATE datos SET
coberturagsm='$coberturagsm', coberturagprs='$coberturagprs',
coberturawlan='$coberturawlan' WHERE id='$id'", $conexion);
if (!$actualizar) {
die("Fallo en la actualización de registro en la Base de Datos: " .
mysql_error());
}
}
//5. Cerrar conexión a la Base de Datos
mysql_close($conexion);
?>
27
Creador de un Mapa de Cobertura
De esta forma, la url a la cual hay que conectarse para enviar los datos
tiene el siguiente aspecto:
http://alvaro.netne.net/ProcesaDatos.php?coberturagsm=valorgsm&coberturagp
rs=valorgprs&coberturawlan=valorwlan&latitud=valorlat&longitud=valorlon
Para finalizar, partiendo de la base de que todos los datos se encuentran
perfectamente almacenados en la base de datos, el único paso que queda por dar
es conectarse dicha base de datos e ir recorriendo cada una de las tuplas de la
tabla generando el código JavaScript correspondiente para crear cada uno de los
marcadores con los datos correspondientes. Para poder llevar a cabo todo se
necesita utilizar de nuevo una función en PHP que esté contenida dentro de las
etiquetas <script></script> de ambas páginas Web y que realice todo lo
comentado anteriormente. El código de dicha función PHP sería el siguiente:
<?php
$link=mysql_connect("mysql8.000webhost.com","a1285122_alvaro","merequet
engue1") or die ("Error conexión");
mysql_select_db("a1285122_proyect", $link) or die ("Error selección
BD");
$sql = "SELECT * FROM datos;";
$result = mysql_query($sql) or die ("La consulta <b>$sql</b> tiene
algún error");
while ($row = mysql_fetch_array($result)){
$aux3 = $row['coberturagsm'];
if(strpos($row['coberturagsm'], ",")!=false){
$ind3 = strpos($row['coberturagsm'], ",");
$aux3 = $row['coberturagsm'];
$aux3[$ind3] = ".";
}
$aux4 = $row['coberturagprs'];
if(strpos($row['coberturagprs'], ",")!=false){
$ind4 = strpos($row['coberturagprs'], ",");
$aux4 = $row['coberturagprs'];
$aux4[$ind4] = ".";
}
$aux5 = $row['coberturawlan'];
if(strpos($row['coberturawlan'], ",")!=false){
$ind5 = strpos($row['coberturawlan'], ",");
$aux5 = $row['coberturawlan'];
$aux5[$ind5] = ".";
28
Creador de un Mapa de Cobertura
}
$ind1 = strpos($row['latitud'], ",");
$ind2 = strpos($row['longitud'], ",");
$aux1 = $row['latitud'];
$aux2 = $row['longitud'];
$aux1[$ind1] = ".";
$aux2[$ind2] = ".";
echo "var latlng = new GLatLng(";echo $aux1;echo ",";echo $aux2;
echo");";
echo "var opciones = { title: \"Niveles de Cobertura\", draggable:
true, bouncy: false};";
echo "var opcionesven = { noCloseOnClick: false};";
echo "var marcador";echo $row['id'];echo " = new GMarker(latlng,
opciones);";
echo "GEvent.addListener(marcador";echo $row['id'];echo ", \"click\",
function() {";
echo "marcador";echo $row['id'];echo ".openInfoWindow(\"Cobertura GSM:
";echo $row['coberturagsm'];echo " %<br/> Cobertura GPRS: "; echo
$row['coberturagprs'];echo " %<br/>Cobertura WIFI: ";echo
$row['coberturawlan'];echo " %\", opcionesven); });";
echo "map.addOverlay(marcador";echo $row['id'];echo ");";
}
mysql_close($link);
?>
29
Creador de un Mapa de Cobertura
Capítulo 4:
Implementación de la Aplicación en
Symbian OS
4.1.- Análisis de requisitos
El objetivo principal que tiene la aplicación Symbian OS es ayudar a
cualquier persona que necesite conocer los niveles de cobertura GSM, GPRS y
WIFI en un determinado lugar. A la hora de realizar cualquier aplicación en
Symbian OS es necesario realizar un estudio previo que nos permita obtener
30
Creador de un Mapa de Cobertura
toda la información necesaria para poder comenzar a trabajar de forma
adecuada y optimizando el rendimiento. El objetivo del análisis es recoger toda
la información posible sobre el sistema a desarrollar y analizar los requisitos de
usuario que la aplicación deberá satisfacer. Estos requisitos son los siguientes:

Nociones básicas de Symbian
Para comenzar deberíamos adquirir una nociones básicas de las
plataformas de desarrollo para Symbian OS, en concreto de la serie s60, que
es la que me incumbe en esta aplicación.

Elección del entorno de desarrollo
Otro aspecto interesante a estudiar antes de comenzar a desarrollar una
aplicación en Symbian OS es la elección del entorno de desarrollo. Se debe
elegir el entorno que más nos favorezca, intentando que sea lo más actual
posible y que nos permita encontrar todo tipo de ayuda y documentación.

Elección del SDK
Otro punto muy interesante es la elección del SDK ya que cada
terminal lleva una versión del sistema operativo Symbian OS. Dependiendo
de la versión de Symbian OS que lleve nuestro dispositivo elegiremos un
SDK u otro.

Conocimientos de C++
Es muy importante poseer conocimientos de C++ ya que la
programación en Symbian OS no es estrictamente idéntica a C++, pero
utiliza una estructura muy similar.

Modularidad del Código
El código ha de estar lo más claro posible de forma que permita añadir
nuevas funciones y complementar la aplicación lo más fácil posible.

Coste Computacional
31
Creador de un Mapa de Cobertura
El coste computacional no ha de ser elevado puesto que los recursos
en los dispositivos móviles están muy limitados sobre todo en lo que a
memoria RAM se refiere, por lo que hay que hacer hincapié en la óptima
gestión de la memoria.

Portabilidad
La aplicación podrá ser utilizada en cualquier dispositivo móvil cuya
versión de Symbian OS sea compatible con la SDK s60 3erd FP1. Para
poder utilizar la aplicación en una versión distinta habrá que compilar de
nuevo la aplicación con la correspondiente SDK.

Fácil Mantenimiento
Hay que intentar estructurar el código en funciones de forma que sean
fáciles de utilizar para personas ajenas al proyecto, así como comentar el
código lo máximo posible.

Facilidad de Uso
Esta aplicación está pensada para que pueda ser utilizada por cualquier
tipo de persona, por lo que hay que procurar realizar un menú lo más
sencillo y claro posible a la vez que completo.

Transparencia al Usuario
Cada uno de los cálculos y los procesos realizados en la aplicación
deben producirse de manera oculta de forma que lo único que observe el
usuario sea el resultado final.

Requisito Hardware
Es importante disponer de un dispositivo móvil que te permita realizar
cualquier prueba de la aplicación, es decir, que tenga acceso a las redes
GSM, GPRS y WIFI así como a las coordenadas GPS.
4.2.- Decisiones de Diseño
32
Creador de un Mapa de Cobertura
En este apartado trataré de explicar la fase de diseño de la aplicación
Symbian OS, que es el objetivo fundamental del proyecto. Esta fase de diseño
no pretende entrar en detalles de implementación de software sino que pretende
proponer una idea de la funcionalidad que será capaz de encapsular.
La idea de implementar la aplicación en Symbian C/C++ parte de la
base de que es el único lenguaje de programación que nos permite acceder a
cada uno de los datos que la aplicación tiene como objetivo proporcionar.
Como dispositivo móvil para utilizar de prueba he elegido el modelo
N95 de Nokia por su facilidad en cuanto a la disponibilidad se refiere, ya que
era el dispositivo móvil que utilizaba antes de decidir embarcarme en este
proyecto, a su vez porque es un dispositivo capaz de acceder a redes GSM,
GPRS y WIFI, y porque te permite obtener la posición exacta a través de GPS,
es decir, latitud y longitud en un determinado instante. La elección de este
dispositivo móvil a condicionado la posterior elección de la SDK
correspondiente para realizar la aplicación.
El menú realizado para ejecutar la aplicación también he intendado que
fuera lo más sencillo posible dado que la aplicación Symbian OS de este
proyecto tiene como objetivo servir de ayuda a cualquier tipo de usuario. En el
menu se pueden observar, entre otras, dos funciones principales: la obtención
de los niveles de cobertura GSM, GPRS y WIFI así como la opción de enviar
dichos niveles y las coordenadas GPS latitud y longitud a la base de datos
instalada en el servidor para poder generar el correspondiente marcador con la
información necesaria en el punto exacto del mapa.
4.3.- Funcionamiento general de las Redes GSM,
GPRS y WIFI
La red GSM está estructurada de manera jerárquica. En una red GSM
hay al menos una región administrativa, Mobile Switching Center (MSC). Cada
región administrativa consiste al menos en una Área de Localización (LA).
Cada Área de Localización está formada por varios grupos de Células. Cada
grupo de células está asignado a un Estación Controladora Base ( Base Station
Controler, BSC). Esta estructura se muestra en el siguiente gráfico :
33
Creador de un Mapa de Cobertura
Jerarquía en la red GSM
El sistema GSM tiene limitado en el rango de frecuencias de 25 Mhz a
900Mhz. En este rango hay un máximo de 125 canales cada canal de un ancho
de 200 Khz. Un mismo canal se asigna a una sola célula , de esta manera se
forman los clusters de células que agrupan a las células que contiguas que no
comparten canal. Como el número de canales está limitado, la asignación de un
canal se hace a más de una célula. Para evitar interferencias entre células que
usen el mismo canal, las células que usen un mismo canal deben de estar lo mas
alejado posible dentro de la red GSM. La siguiente figura muestra como las
frecuencias pueden ser reutilizadas en tres casos diferentes, en cada caso el
operador GSM tiene asignado un determinado numero K de canales. Podemos
ver también la formación de Clusters.
Reutilización de frecuencias y formación de clusters
34
Creador de un Mapa de Cobertura
Cada teléfono móvil debe de comprobar periódicamente la intensidad de
la señal emitida por la estaciones base cercanas. El dispositivo móvil selecciona
la célula que dispone la mejor recepción. Una vez que el dispositivo esta
conectado a una Célula la comunicación móvil es posible. Cuando el
dispositivo esta en movimiento la intensidad de la señal recibida va variando
de manera que deberá de elegir otra Célula para garantizar el servicio. Este
proceso es el de reselección de célula es muy común dado a que cada célula
dispone de un área limitada. Cuando el dispositivo está en movimiento el
dispositivo elige la célula que le aporta mayor intensidad de señal para, de esta
manera, asegurar el servicio. Cuando el dispositivo móvil cambia de célula
recibe la señal de una célula con diferente CI.
La tecnología GPRS (General Packet Radio Services) permite a las
redes celulares una mayor velocidad y ancho de banda sobre el GSM,
mejorando las capacidades de acceso móvil a Internet. El principal problema de
esta tecnología resulta de su incompatibilidad con los aparatos GSM existentes,
inclusive con los que ya soportan el protocolo WAP para acceso a la Internet.
Asimismo, pocos son los modelos con tecnología GPRS.
La red GPRS es una extensión del Sistema Global para Comunicaciones
Móviles (Global System for Mobile Communications o GSM) para la
transmisión de datos no conmutada (o por paquetes). Existe un servicio similar
para los teléfonos móviles que del sistema IS-136. Permite velocidades de
transferencia de 56 a 114 kbps.
GPRS se puede utilizar para servicios tales como Wireless Application
Protocol (WAP) , servicio de mensajes cortos (SMS), servicio de mensajería
multimedia (MMS), Internet y para los servicios de comunicación, como el
correo electrónico y la World Wide Web (WWW). La transferencia de datos de
GPRS se cobra por volumen de información transmitida (en kilo o megabytes),
mientras que la comunicación de datos a través de conmutación de circuitos
tradicionales se factura por minuto de tiempo de conexión, independientemente
de si el usuario utiliza toda la capacidad del canal o está en un estado de
inactividad. GPRS da mejor rendimiento a la conmutación de paquetes de
servicios, en contraposición a la conmutación de circuitos, donde una cierta
calidad de servicio (QoS) está garantizada durante la conexión. Por este motivo,
se considera más adecuada la conexión conmutada para servicios como la voz
que requieren un ancho de banda constante durante la transmisión, mientras que
los servicios de paquetes como GPRS se orientan al tráfico de datos.
35
Creador de un Mapa de Cobertura
Cuando hablamos de WIFI nos referimos a una de las tecnologías de
comunicación inalámbrica mediante ondas más utilizada hoy en día. WIFI,
también llamada WLAN (wireless lan, red inalámbrica) o estándar IEEE
802.11. WIFI no es una abreviatura de Wireless Fidelity, simplemente es un
nombre comercial.
En la actualidad podemos encontrarnos con dos tipos de comunicación
WIFI: 802.11b, que emite a 11 Mb/seg, y 802.11g, más rapida, a 54 MB/seg.
De hecho, son su velocidad y alcance (unos 100-150 metros en hardware
asequible) lo convierten en una fórmula perfecta para el acceso a internet sin
cables.
Para tener una red inalámbrica en casa sólo necesitaremos un punto de
acceso, que se conectaría al módem, y un dispositivo WIFI que se conectaría en
nuestro aparato. Existen terminales WIFI que se conectan al PC por USB, pero
son las tarjetas PCI (que se insertan directamente en la placa base) las
recomendables, nos permite ahorrar espacio físico de trabajo y mayor rapidez.
Para portátiles podemos encontrar tarjetas PCMI externas, aunque muchos de
los aparatos ya se venden con tarjeta integrada.
Uno de los problemas más graves a los cuales se enfrenta actualmente la
tecnología Wi-Fi es la progresiva saturación del espectro radioeléctrico, debida
a la masificación de usuarios, esto afecta especialmente en la conexiones de
larga distancia (mayor de 100 metros), en realidad WIFI esta diseñado para
conectar ordenadores a la red a distancias reducidas, cualquier uso de mayor
alcance esta expuesto a un excesivo riesgo de interferencias.
Un muy elevado porcentaje de redes son instaladas sin tener en
consideración la seguridad convirtiendo así sus redes en redes abiertas (o muy
vulnerables a los crackers), sin proteger la información que por ellas circulan.
Existen varias alternativas para garantizar la seguridad de estas redes. Las más
comunes son: WEP, cifra los datos en su red de forma que sólo el destinatario
deseado pueda acceder a ellos. Los cifrados de 64 y 128 bits son dos niveles de
seguridad WEP. WEP codifica los datos mediante una “clave” de cifrado antes
de enviarlo al aire. WPA: presenta mejoras como generación dinámica de la
clave de acceso. Las claves se insertan como de dígitos alfanuméricos, sin
restricción de longitud.
36
Creador de un Mapa de Cobertura
4.4.- API Symbian OS
Para poder obtener los niveles de cobertura WIFI, GPRS y GSM así
como las coordenadas latitud y longitud que es el objetivo fundamental del
proyecto y poder enviarlas mediante protocolo HTTP a la base de datos alojada
en el servidor hay que hacer uso de la API del sistema operativo Symbian OS
v9.2.
La API del sistema operativo Symbian OS v9.2 es muy extensa y está
compuesta por infinidad de clases, métodos, atributos, constantes, estructuras
de datos… etc. Es por este motivo por lo que yo en este apartado sólo quiero
hacer referencia a la parte de la API de Symbian OS que he utilizado a la hora
de desarrollar el proyecto.
En primer lugar trataré de exponer la parte de la API de Symbian OS
correspondiente a la obtención del nivel de cobertura WIFI. Para poder acceder
a dicho nivel no es necesario implementar una clase auxiliar ya que realizo la
petición al sistema operativo de manera asíncrona sin hacer uso de un recurso
muy propio de Symbian OS como es Active Object. El código correspondiente
al método que hace posible obtener dicho nivel es el siguiente:
TPckgBuf<TConnMonNetworkNames> networks;
RConnectionMonitor monitor;
monitor.ConnectL();
CleanupClosePushL(monitor);
TRequestStatus status;
monitor.GetPckgAttribute(EBearerIdWLAN, 0, KNetworkNames ,
networks, status);
User::WaitForRequest(status ) ;
User::LeaveIfError(status.Int());
TBuf<20> ibuff;
TInt count = networks().iCount;
ibuff.Zero();
ibuff.AppendNum(count);
CEikonEnv::InfoWinL(_L("Total de redes LAN encontradas: "),
ibuff);
if(count==0){
iSignalWLAN = 0.0;//para enviar luego al servidor.
ibuff.Zero();
TRealFormat iFormat;
37
Creador de un Mapa de Cobertura
ibuff.AppendNum(iSignalWLAN, iFormat);
CEikonEnv::InfoWinL(_L("Cobertura WLAN media en %: "),ibuff);
ibuff.Zero();
CEikonEnv::InfoWinL(_L("Cobertura WLAN media en dB: 0 "),ibuff);
}
else{
TInt iNivelTotal = 0;
for(TInt i=0;i<count;i++)
{
TBuf8<32> ssid;
ssid.Copy( networks().iNetwork[i].iName );
ibuff.Zero();
ibuff.Copy(ssid);
CEikonEnv::InfoWinL(_L("Nombre de la Red:"),ibuff);
TUint8 iSignal = networks().iNetwork[i].iSignalStrength;
iNivelTotal = iNivelTotal + iSignal;
ibuff.Zero();
ibuff.AppendNum(iSignal);
CEikonEnv::InfoWinL(_L("Nivel de Cobertura WLAN en dB:"),ibuff);
}
iSignalWLAN = (iNivelTotal/count);
TReal dec = iSignalWLAN;
TInt decibelios = iSignalWLAN;
TReal por;
if(dec>0 &&
iSignalWLAN
}
// rango de
else if(dec
dec <= 50){
= 100;
80% a 100%
>= 51 && dec <= 60){
dec = dec - 51;
por = dec * 2.22;
iSignalWLAN = 100 - por;
}
//rango de 60% a 80%
else if(dec >= 61 && dec <= 70){
dec = dec - 61;
por = dec * 2.22;
iSignalWLAN = 80 - por;
}
//rango de 40% a 60%
else if(dec >= 71 && dec <= 80){
dec = dec - 71;
38
Creador de un Mapa de Cobertura
por = dec * 2.22;
iSignalWLAN = 60 - por;
}
//rango de 20% a 40%
else if(dec >= 81 && dec <= 90){
dec = dec - 81;
por = dec * 2.22;
iSignalWLAN = 40 - por;
}
//rango de 0% a 20%
else if(dec >= 91 && dec <= 100){
dec = dec - 91;
por = dec * 2.22;
iSignalWLAN = 20 - por;
}
if(iSignalWLAN>100)
iSignalWLAN = 100;
TRealFormat iFormat;
ibuff.Zero();
ibuff.AppendNum(iSignalWLAN, iFormat);
CEikonEnv::InfoWinL(_L("Cobertura WLAN media en %: "),ibuff);
ibuff.Zero();
ibuff.AppendNum(decibelios);
CEikonEnv::InfoWinL(_L("Cobertura WLAN media en dB: "), ibuff);
}
CleanupStack::PopAndDestroy();
-Clase RConnectionMonior: Esta clase nos permite acceder y
utilizar los servicios relacionados con redes que la plataforma s60
proporciona. La clase contiene los siguientes métodos:
1.- TInt ConnectL(): Este método es utilizado con el fin de
establecer una conexión con el Connection Monitor Server. El método
no recibe ningún tipo de argumento y devuelve un valor de tipo entero.
Si el método se ha ejecutado de manera correcta y se ha podido realizar
la conexión entonces devuelve KErrNone, en caso contrario devolvería
el código de error producido.
39
Creador de un Mapa de Cobertura
2.- GetPckgAttribute(TUint aConnectionId, TUint
aSubconnectionId, TUint attribute, TDes8 aValue, TrequesStatus
aStatus): Este método se utiliza para buscar estructuras de datos
representadas en un descriptor. El método no devuelve ningún
parámetro y recibe como argumentos el identificador de conexión, el
identificador de subconexión, el identificador del atributo que quiere ser
buscado, un descriptor para almacenar el valor de dicho atributo y por
último una variable para almacenar el código de error si se produjese o
KErrNone si no hubiera ningún problema al realizar la llamada. En
nuestro caso el método recibe como primer argumento EBearerWLAN
que es una constante que forma parte del tipo enumerado
TConnMonBearerType, como segundo argumento recibe 0 y como
tercer argumento recibe KNetworkNames que es una constante de tipo
entero.
3.- Close(): es el método necesario para cerrar la conexión
previamente establecida con el Connection Monitor Server.
- Clase TPckgBuf<TConnMonNetworkNames>: Esta clase es
necesaria para almacenar los datos necesarios en la llamada al método
GetPckgAttribute. Esta clase cuenta con dos atributos que son los
siguientes:
1.- TUint iCount: Es un atributo de tipo entero utilizado a modo
de contador ya que almacena en él el número de redes detectadas.
2.- iNetwork[KConnMonMaxNetworkCount]: Es un array con
una dimensión máxima igual al número de redes detectadas que contiene
elementos de la clase TConnMonNetwork. Esta clase contiene los
siguientes atributos: TBuf8<32> iName, TInt iType, y TUint32
iSignalStrength, que es el que nos interesa para almacenar el nivel de
cobertura de la red WLAN.
La siguiente parte de la API de Symbian OS que he utilizado para poder
realizar la aplicación es la relacionada con la obtención del nivel de cobertura
GSM. Para poder realizar esta medida, no he aplicado directamente sobre el
método AppUi::HandleCommandL las clases y métodos necesarios, sino que he
40
Creador de un Mapa de Cobertura
tenido que implementar una clase auxiliar, la clase CGSM, ya que para poder
obtener el nivel de cobertura GSM hay que utilizar una serie de métodos que
realizan una petición asíncrona al sistema operativo y por tanto he realizado
dicha petición a través de Active Objects, que es un concepto de porgramación
basada en hilos.
Una vez implementada la clase CGSM sólo tenemos que introducir las
modificaciones necesarias en nuestra clase AppUi y en el método
AppUi::HandleCommandL realizar la llamada al método de nuestra clase que
se encarga de obtener dicho nivel de cobertura. El código de la clase CGSM es
el siguiente:
#ifndef CGSM_H_
#define CGSM_H_
#include <e32std.h>
#include <e32base.h>
#include <Etel3rdParty.h>
class MNwSignalObserver
{
public:
virtual void SignalStatus(TInt32 aStrength, TInt8 aBars ) = 0;
};
class CGSM : public CActive
{
public:
static CGSM* NewL(MNwSignalObserver& aObserver);
static CGSM* NewLC(MNwSignalObserver& aObserver);
~CGSM();
private:
CGSM(MNwSignalObserver& aObserver);
void ConstructL(void);
private:
void RunL();
void DoCancel();
public:
void GetSignalInfo();
private:
MNwSignalObserver& iObserver;
CTelephony* iTelephony;
41
Creador de un Mapa de Cobertura
CTelephony::TSignalStrengthV1 iSigStrengthV1;
CTelephony::TSignalStrengthV1Pckg iSigStrengthV1Pckg;
TBool iGettingSignal;
};
#endif /* CGSM_H_ */
La implementación de cada uno de los métodos de la clase CGSM es la
siguiente:
CGSM* CGSM::NewL(MNwSignalObserver& aObserver)
{
CGSM* self = CGSM::NewLC(aObserver);
CleanupStack::Pop(self);
return self;
}
CGSM* CGSM::NewLC(MNwSignalObserver& aObserver)
{
CGSM* self = new (ELeave) CGSM(aObserver);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CGSM::~CGSM()
{
Cancel();
delete iTelephony;
}
void CGSM::ConstructL(void)
{
iTelephony = CTelephony::NewL();
}
CGSM::CGSM(MNwSignalObserver& aObserver) :
CActive(EPriorityStandard), iObserver(aObserver),
iSigStrengthV1Pckg(
iSigStrengthV1)
42
Creador de un Mapa de Cobertura
{
CActiveScheduler::Add(this);
}
void CGSM::GetSignalInfo()
{
if (iTelephony && !IsActive())
{
iGettingSignal = ETrue;
iTelephony->GetSignalStrength(iStatus, iSigStrengthV1Pckg);
SetActive();
}
}
void CGSM::RunL()
{
iObserver.SignalStatus(iSigStrengthV1.iSignalStrength,
iSigStrengthV1.iBar);
if (iStatus != KErrCancel)
{
iTelephony->NotifyChange(iStatus,
CTelephony::ESignalStrengthChange,
iSigStrengthV1Pckg);
SetActive();
}
iGettingSignal = EFalse;
}
void CGSM::DoCancel()
{
if (iGettingSignal)
iTelephony->CancelAsync(CTelephony::EGetSignalStrengthCancel);
else
iTelephony->CancelAsync(CTelephony::
ESignalStrengthChangeCancel);
}
Como ya comenté anteriormente, el método SignalStatus hay que
redefinirlo en nuestra clase AppUi:
43
Creador de un Mapa de Cobertura
void CprobandoWLANExampleAppUi::SignalStatus(TInt32 aStrength,
TInt8 aBars)
{
switch(aBars){
case
case
case
case
case
case
case
case
0:
1:
2:
3:
4:
5:
6:
7:
iSignalGSM
iSignalGSM
iSignalGSM
iSignalGSM
iSignalGSM
iSignalGSM
iSignalGSM
iSignalGSM
=
=
=
=
=
=
=
=
0;break;
14.2;break;
28.4;break;
42.6;break;
56.8;break;
71;break;
85.2;break;
99.4;break;
}
TBuf<50> ibuff;
TRealFormat iFormat;
ibuff.Zero();
ibuff.AppendNum(iSignalGSM, iFormat);
CEikonEnv::InfoWinL(_L("Cobertura GSM en % aproximadamente: "),
ibuff);
ibuff.Zero();
ibuff.AppendNum(aBars);
CEikonEnv::InfoWinL(_L("Barras de Cobertura GPRS mostradas en
pantalla: "), ibuff);
ibuff.Zero();
ibuff.AppendNum(aStrength);
CEikonEnv::InfoWinL(_L("Cobertura GSM en dB: "), ibuff);
}
-Clase CTelephony: Esta clase nos provee de una interfaz para
poder acceder al sistema del telefónico del dispositivo móvil. Los
métodos que he utilizado de esta clase son los siguientes:
1.- static CTelephony* NewL(): El método construye un nuevo
objeto de la clase CTelephony devolviendo la referencia a dicho objeto.
Utilizando este método no colocamos la referencia al nuevo objeto en la
pila CleanupStack.
2.SignalStrength(TRequestStatus
aStatus,
TDes8
aSignalStrength): Este es el método más interesante que utilizamos de
la clase CTelephony ya que nos devuelve la intensidad de señal del
dispositivo móvil, es decir, el nivel de cobertura a través de
44
Creador de un Mapa de Cobertura
aSignalStrength que utilizamos como parámetro. El primer parámetro
que toma este método es aStatus, que se utiliza para comprobar que la
llamada al método se realiza de forma correcta. En mi caso utilizo como
primer argumento la variable iStatus propia de CActive. Como segundo
argumento utilizo una variable del tipo TSignalStrengthV1Pckg que
necesita un objeto de la clase TSignalStrengthV1 para ser inicializada.
3.NotifyChange(TRequestStatus
aStatus,
const
TNotificationEvent aEvent, TDes8 aDes ): Gracias a este método se
registra nuestro interés en recibir notificaciones sobre el cambio de un
evento. Como primer parámetro vuelvo a utilizar la variable iStatus
propia de CActive y como segundo parámetro utilizo la constante
ESignalStrengthChange que es una constante del tipo enumerado
TNotificantionEvent propicia para registrar todos los cambios que se
produzcan en cuanto al nivel de cobertura GSM. Como tercer parámetro
vuelvo a utilizar una variable del tipo TSignalStrengthPckgV1 para
almacenar el nuevo valor del nivel de cobertura.
4.- TInt CancelAsync(TCancellationrequest aRequest): El
método se utiliza para cancelar cualquier petición asíncrona que está
siendo realizada. Este método se utiliza cuando redefinimos el método
DoCancel propio de CActive. Como parámetro toma una variable del
tipo enumerado TCancellationRequest. En mi caso utilizamos como
parámetro las constante ESignalStrengthCancel, que cancela una
petición pendiente para obtener el nivel de cobertura, y la constante
ESignalStrengthChangeCancel, que cancela una petición pendiente
sobre cambio en el valor del nivel de cobertura.
- Clase TSignalStrengthV1: A través de un objeto de esta clase
podemos almacenar el nivel de cobertura GSM en la llamada al método
GetSignalStrength de la clase CTelephony. Esta clase posee los
siguientes atributos:
1.- iBar: Es de tipo TInt8 y almacena el número de barras de
cobertura GSM que el dispositivo móvil debe mostrar.
2.- iSignalStrength: Es de tipo TInt32 y almacena el valor del
nivel de cobertura GSM expresado en dB.
45
Creador de un Mapa de Cobertura
A continuación trataré de explicar toda la parte de la API de Symbian
OS relacionada con la obtención de las coordenadas GPS, es decir, las clases y
métodos necesarios para poder obtener a través del GPS (interno o externo) del
dispositivo móvil la latitud y la longitud del punto exacto en el cual realizamos
la medida de los niveles de cobertura. Estas coordenadas son necesarias para
poder colocar luego en el mapa de la página Web la información
correspondiente.
Al igual que en el caso de la obtención del nivel de cobertura GSM, a la
hora de obtener las coordenadas GPS no aplico directamente el código
necesario en el método AppUi::HandleCommandL sino que tengo que
implementar una clase auxiliar, la clase CLBSInfo, ya que realizo una petición
al sistema operativo a través de Active Objects, utilizando hilos, y por tanto
tengo que implementar una serie de métodos heredados de la clase CActive.
Una vez implementada la clase CLBSInfo sólo hay que añadir a la clase
AppUi
las
modificaciones
necesarias
y
en
el
método
AppUi::HandleCommandL realizar la llamada al método que nos devuelve las
coordenadas. El código correspondiente a la clase CLBSInfo es el siguiente:
#include <lbs.h>
#include <LbsSatellite.h>
class MPositionObserver
{
public:
virtual void LBSPositionUpdatedL(TPositionInfoBase& aPosInfo) =
0;
virtual void LBSErrorL(const TDesC& aErrorString) = 0;
virtual void LBSMessageL(const TDesC& aMessage) = 0;
virtual void LBSMessageL(TInt aCode, const TDesC&
aMessage) = 0;
};
class CLBSInfo : public CActive
46
Creador de un Mapa de Cobertura
{
public:
static CLBSInfo* NewL(MPositionObserver& aPositionListener ) ;
virtual ~CLBSInfo();
protected:
void DoCancel();
void RunL();
TInt RunError(TInt aError);
private:
// New Functions
void ConstructL( );
CLBSInfo(MPositionObserver& aPositionListener );
void DoInitialiseL();
void PositionUpdatedL();
public:
void Pause();
void Continue();
TPositionInfoBase* CurrentPosition();
private:
TPositionModuleId UsedPsy;
RpositionServer iPosServer;
RPositioner iPositioner;
TPositionInfo iPositionInfo;
TPositionSatelliteInfo iSatelliteInfo;
MPositionObserver& iPositionListener;
47
Creador de un Mapa de Cobertura
TPositionInfoBase* iPosInfoBase;
TBool iGettingLastknownPosition;
};
La implementación correspondiente a cada uno de los métodos de la
clase es la siguiente:
#include <Lbs.h>
#include <eikenv.h>
#include "LBSInfo.h"
const TInt KSecond = 1000000;
const TInt KMaxAge = KSecond;
const TInt KErrBuffer = 100;
_LIT(KRequestor,"LocationExample");
_LIT(KLbsErrLocRequest,"Error Solicitud Localizacion: %d.");
_LIT(KLbsErrAccess,"No Acceso Localizacion. Error: %d.");
_LIT(KLbsErrPosServConn,"Error Servidor Localizacion: %d.");
_LIT(KLbsErrOpenPos,"Error servidor Localizacion: %d.");
_LIT(KLbsErrSetRequestor,"Error Solicitud Localizacion: %d.");
_LIT(KLbsErrSetUpOpt,"Error Actualizacion Localizacion: %d.");
_LIT(KLbsErrCanceled,"Localizacion Cancelada.");
_LIT(KLbsErrQuality,"Calidad Localizacion Error");
_LIT(KLbsErrPosUnknown, "Posicion Localizacion Desconocida");
CLBSInfo::CLBSInfo(MPositionObserver& aPositionListener)
: CActive(CActive::EPriorityStandard),
iPositionListener( aPositionListener ),
iPosInfoBase( &iPositionInfo ),
iGettingLastknownPosition( ETrue )
{
}
48
Creador de un Mapa de Cobertura
void CLBSInfo::ConstructL()
{
CActiveScheduler::Add( this );
DoInitialiseL();
}
CLBSInfo* CLBSInfo::NewL(MPositionObserver& aPositionListener)
{
CLBSInfo* self = new( ELeave ) CLBSInfo(aPositionListener);
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
return self;
}
CLBSInfo::~CLBSInfo()
{
Cancel();
iPositioner.Close();
iPosServer.Close();
}
void CLBSInfo::DoCancel()
{
if ( iGettingLastknownPosition )
{
iPositioner.CancelRequest(EPositionerGetLastKnownPosition);
}
else
{
iPositioner.CancelRequest(EPositionerNotifyPositionUpdate);
}
}
void CLBSInfo::RunL()
{
TBuf<KPositionMaxModuleName> buffer;
49
Creador de un Mapa de Cobertura
switch ( iStatus.Int() )
{
case KErrNone:
case KPositionPartialUpdate:
{
PositionUpdatedL();
break;
}
case KErrArgument:
{
iPosInfoBase = &iPositionInfo;
iPositioner.NotifyPositionUpdate( *iPosInfoBase, iStatus );
SetActive();
break;
}
case KPositionQualityLoss:
{
iPositionListener.LBSErrorL(KLbsErrQuality);
if ( iGettingLastknownPosition )
{
iPosInfoBase = &iSatelliteInfo;
}
iPositioner.NotifyPositionUpdate( *iPosInfoBase, iStatus );
SetActive();
break;
}
case KErrAccessDenied:
{
buffer.Format(KLbsErrAccess, iStatus.Int());
iPositionListener.LBSErrorL(buffer);
break;
}
50
Creador de un Mapa de Cobertura
case KErrTimedOut:
{
iPositionListener.LBSErrorL(KLbsErrPosUnknown);
if ( iGettingLastknownPosition )
{
iPosInfoBase = &iSatelliteInfo;
}
iPositioner.NotifyPositionUpdate( *iPosInfoBase, iStatus );
SetActive();
break;
}
case KErrCancel:
{
iPositionListener.LBSErrorL( KLbsErrCanceled );
break;
}
case KErrUnknown:
{
iPositionListener.LBSMessageL(KLbsErrPosUnknown);
if ( iGettingLastknownPosition )
{
iPosInfoBase = &iSatelliteInfo;
iGettingLastknownPosition = EFalse;
}
iPositioner.NotifyPositionUpdate( *iPosInfoBase, iStatus );
SetActive();
break;
}
default:
{
buffer.Format(KLbsErrLocRequest, iStatus.Int());
iPositionListener.LBSErrorL( buffer );
break;
}
51
Creador de un Mapa de Cobertura
}
if ( iGettingLastknownPosition )
{
iGettingLastknownPosition = EFalse;
}
}
void CLBSInfo::DoInitialiseL()
{
.
TInt error = iPosServer.Connect( );
TBuf<KErrBuffer> buffer;
if ( KErrNone != error )
{
buffer.Format(KLbsErrPosServConn, error);
iPositionListener.LBSErrorL( buffer );
return;
}
TUint numModules;
TPositionModuleId modId;
TPositionModuleInfo modInfo;
TPositionModuleStatus modStatus;
TBool foundModule = EFalse;
User::LeaveIfError(iPosServer.GetNumModules(numModules));
for (TUint I=0 ; I < numModules ; I++)
{
User::LeaveIfError(iPosServer.GetModuleInfoByIndex(I, modInfo));
if ( modInfo.IsAvailable() && (modInfo.TechnologyType() ==
TPositionModuleInfo::ETechnologyAssisted) )
{
TPositionModuleInfo::TCapabilities caps =
modInfo.Capabilities();
if ((caps & TPositionModuleInfo::ECapabilitySpeed) && (caps &
TPositionModuleInfo::ECapabilityHorizontal)
&& (caps & TPositionModuleInfo::ECapabilityVertical))
{
modId = modInfo.ModuleId();
foundModule = ETrue;
iPositionListener.LBSMessageL(_L("Assisted Technology chosen"));
break;.
}
}
52
Creador de un Mapa de Cobertura
}
if(!foundModule)
{
for (TUint I=0 ; I < numModules ; I++)
{
User::LeaveIfError(iPosServer.GetModuleInfoByIndex(I, modInfo));
if ( modInfo.IsAvailable() && (modInfo.TechnologyType() ==
TPositionModuleInfo::ETechnologyTerminal) )
{
modId = modInfo.ModuleId();
foundModule = ETrue;
iPositionListener.LBSMessageL(_L("Terminal Technology chosen"));
break;
}
}
}
if(!foundModule)
{
iPositionListener.LBSErrorL(KLbsErrPosUnknown);
return;
}
error = iPositioner.Open(iPosServer, modId);
iPositionListener.LBSMessageL(modId.iUid, _L("Hasta este modIDul"));
if ( KErrNone != error )
{
buffer.Format(KLbsErrOpenPos, error);
iPositionListener.LBSErrorL( buffer );
iPosServer.Close();
return;
}
error = iPositioner.SetRequestor( CRequestor::ERequestorService
,
CRequestor::EFormatApplication , KRequestor );
if ( KErrNone != error )
{
buffer.Format(KLbsErrSetRequestor, error);
iPositionListener.LBSErrorL( buffer );
iPositioner.Close();
53
Creador de un Mapa de Cobertura
iPosServer.Close();
return;
}
TPositionUpdateOptions options;
const TTimeIntervalMicroSeconds KUpdateInterval(2000000);
const TTimeIntervalMicroSeconds KTimeOut(30000000);
const TTimeIntervalMicroSeconds KMaxUpdateAge(1000000);
options.SetUpdateInterval(KUpdateInterval);
options.SetUpdateTimeOut(KTimeOut);
options.SetMaxUpdateAge(KMaxUpdateAge);
options.SetAcceptPartialUpdates(EFalse);
error =
iPositioner.SetUpdateOptions( options );
if ( KErrNone != error )
{
buffer.Format(KLbsErrSetUpOpt, error);
iPositionListener.LBSErrorL( buffer );
iPositioner.Close();
iPosServer.Close();
return;
}
iPositioner.GetLastKnownPosition(*iPosInfoBase,iStatus);
SetActive();
}
TInt CLBSInfo::RunError(TInt aError)
{
Cancel();
TBuf<32> err;
err.Format(KLbsErrLocRequest, aError);
iPositionListener.LBSMessageL(err);
if ( iGettingLastknownPosition )
{
iPosInfoBase = &iSatelliteInfo;
iGettingLastknownPosition = EFalse;
}
if(!IsActive())
{
54
Creador de un Mapa de Cobertura
iPositioner.NotifyPositionUpdate( *iPosInfoBase, iStatus );
SetActive();
}
return KErrNone;
}
void CLBSInfo::Pause()
{
if (IsActive())
{
Cancel();
}
}
void CLBSInfo::Continue()
{
if (!IsActive())
{
iPositioner.GetLastKnownPosition(*iPosInfoBase,iStatus);
SetActive();
}
}
TPositionInfoBase* CLBSInfo::CurrentPosition()
{
return iPosInfoBase;
}
void CLBSInfo::PositionUpdatedL()
{
iPositionListener.LBSPositionUpdatedL(*iPosInfoBase);
if ( iGettingLastknownPosition )
{
iPositionListener.LBSPositionUpdatedL(*iPosInfoBase);
iPosInfoBase = &iSatelliteInfo;
iPositioner.NotifyPositionUpdate( *iPosInfoBase, iStatus );
SetActive();
}
else
{
if ( 0 == iUsedPsy.iUid)
{
55
Creador de un Mapa de Cobertura
iUsedPsy = iPosInfoBase->ModuleId();
}
else if ( iPosInfoBase->ModuleId() != iUsedPsy )
{
iUsedPsy = iPosInfoBase->ModuleId();
TPositionModuleInfo moduleInfo;
iPosServer.GetModuleInfoById(iUsedPsy,moduleInfo);
TInt32 moduleInfoFamily =
moduleInfo.ClassesSupported(EPositionInfoFamily);
iPosInfoBase = &iSatelliteInfo;
if ( EPositionSatelliteInfoClass & moduleInfoFamily )
{
iPosInfoBase = &iSatelliteInfo;
}
else
{
iPosInfoBase = &iPositionInfo;
}
}
iPositionListener.LBSPositionUpdatedL(*iPosInfoBase);
iPositioner.NotifyPositionUpdate( *iPosInfoBase, iStatus );
SetActive();
}
}
Los métodos propios de la clase observadora que hay que implementar en la
clase AppUi son los siguientes:
void CprobandoWLANExampleAppUi::LBSPositionUpdatedL(
TPositionInfoBase& aPosInfo)
{
TReal rLatitude, rLongitude;
TRealFormat rFormat(20, 10);
TBuf<32> latitude, longitude;
56
Creador de un Mapa de Cobertura
TPositionInfo* posInfo = static_cast<TPositionInfo*>(&aPosInfo);
TPosition position;
posInfo->GetPosition(position);
rLatitude = position.Latitude();
rLongitude = position.Longitude();
latitude.Num(rLatitude, rFormat);
longitude.Num(rLongitude, rFormat);
iLastPosition = position;
iLatitud = rLatitude;
iLongitud = rLongitude;
CEikonEnv::InfoWinL(_L("Latitud: "), latitude);
CEikonEnv::InfoWinL(_L("Longitud: "), longitude);
}
void CprobandoWLANExampleAppUi::LBSErrorL(const TDesC&
aErrorString)
{
CEikonEnv::InfoWinL(_L(""), aErrorString);
}
void CprobandoWLANExampleAppUi::LBSMessageL(const TDesC&
aMessage)
{
if(iNetworkEngineObserver)
iNetworkEngineObserver->HandleErrorL(KErrNone, aMessage);
}
void CprobandoWLANExampleAppUi::LBSMessageL(TInt aCode, const
TDesC& aMessage)
{
if(iNetworkEngineObserver)
iNetworkEngineObserver->HandleErrorL(aCode, aMessage);
}
-Clase RPositionServer: Esta es la clase que nos permite
interactuar con el servidor de posicionamiento, se utiliza para realizar la
conexión con dicho servidor. Los métodos que utilizo son los siguientes:
1.- TInt Connect(): Crea una sesión con el Servidor de
Posicionamiento. Devuelve una variable de tipo entero que representa el
código de error de Symbian OS.
57
Creador de un Mapa de Cobertura
2.- TInt GetNumModules(TUint aNumModules): El método
devuelve el número de módulos de posicionamiento que están
disponibles. Recibe un parámetro de entrada, anumModules, en donde
almacenamos dicho número. Devuelve una variable de tipo que
representa el código de error de Symbian OS.
3.- TInt GetModuleInfoByIndex(TInt aModuleIndex,
TPositionModuleInfoBase aModuleInfo): Se utiliza para obtener sobre
el módulo especificado. Recibe dos parámetros de entrada, el primero
para indicar el índice (de 0 a n) del módulo acerca del cual queremos
obtener información y el segundo para almacenar dicha información.
Devuelve una variable de tipo entero que re presenta el código de error
de Symbian OS.
4.- TInt GetModuleInfoById(TPositionmoduleId aModuleId,
TPositionModuleInfoBase aModuleInfo): Este método es similar al
anterior con la única salvedad que recibe como primer parámetro el
identificador único (UID) del módulo sobre el que queremos obtener
información. El resto de parámetros funcionan igual que el anterior.
5.- void Close(): El método se utiliza para finalizar una sesión
con el Servidor de Posicionamiento.
-Clase RPositioner: Esta clase es usada para crear una subsesión
con el servidor de Posicionamiento con el propósito de obtener la
posición actual. Los métodos que ha sido necesario utilizar de esta clase
son los siguientes:
1.- TInt Open(RPositionserver aPosServer): Se utiliza para
establecer una subsesión con el Servidor de Posicionamiento. El método
recibe como parámetro de entrada un objeto de la clase RPositionServer
que representa al Servidor de Posicionamiento al cual hay que
conectarse previamente. Devuelve una variable de tipo TInt que
representa el código de error de Symbian OS.
2.- TInt SetRequestor(TRequestorType aType,
TRequestorFormat aFormat, TdesC aData): A través de este método
podemos establecer una serie de requisitos que la información acerca de
la localización debe cumplir. El método recibe como primer parámetro
una variable del tipo definido TRequestorType que en mi caso es
58
Creador de un Mapa de Cobertura
ERequestorService. En segundo lugar recibe como parámetro una
variable del tipo definido TRequestorFormat, yo he utilizado
EFormatApplication y por último recibe como parámetro un descriptor
con el nombre de la petición. El método devuelve una variable de tipo
TInt que representa el código de error de Symbian OS.
3.- TInt SetUpdateOptions( TPositionUpdateOptions aPosOpt):
El método es utilizado para modificar el comportamiento del notificador
de actualización de la posición, permitiendo establecer una serie de
opciones a la hora de ir actualizando la posición. Recibe como
parámetro de entrada un objeto de la clase TPositionUpdateOptions
que se detalla más adelante. Devuelve una variable de tipo TInt que
representa el código de error de Symbian OS.
4.- void GetLastKnowPosition( TPositionInfoBase pos,
TRequestStatus aStatus): Se utiliza para almacenar en el objeto parado
como primer parámetro la información de la última posición obtenida, si
está disponible. El primer parámetro es un objeto de la clase
TPositionInfoBase, clase que se detalla más adelante mientras que el
segundo parámetro es un objeto de la clase TRequestStatus que
almacena el resultado de la llamada asíncrona que necesita realizar el
método al ser llamado.
5.- void NotifyPositionUpdate(TPositionInfo pos,
TRequestStatus aStatus): Es un método asíncrono que se utiliza para ir
actualizando la información acerca de la posición. Recibe como primer
parámetro de entrada un objeto de la clase TPositionInfo, clase que se
detalla más adelante, y como segundo parámetro de entrada un objeto de
la clase TRequestStatus que contiene el resultado de la llamada
asíncrona que el método realiza cuando se utiliza.
6.- TInt CancelRequest(TInt aRequestId): El método cancela una
petición asíncrona para obtener la posición previamente realizada.
Recibe como parámetro de entrada una variable del tipo enumerado
TPositionIpcld, en mi caso utilizo las variables
EPositionerGetLastKnowPosition y EPositionerNotifyPositionUpdate.
En el objeto de la clase TRequestStaus se almacenará el valor
59
Creador de un Mapa de Cobertura
KErrCancel si la petición de cancelación de ha realizado correctamente o
el código de error de Symbian OS en caso contrario.
7.- void Close(): Para poder cerrar la subsesión creada con el
servidor de Posicionamiento.
- Clase TPosititonInfoBase: Esta clase contiene información
sobre el tipo de actualización y el ID del módulo que dio la información
de localización. El método que utilizo de esta clase es el siguiente:
1.- TPositionModuleId ModuleId(): El método devuelve el ID del
módulo utilizado para obtener la información de localización en una
variable del tipo definido TPositionModuleId.
- Clase TPositionModuleInfo: Es la clase estándar utilizada para
almacenar información acerca del módulo de posicionamiento utilizado.
Los métodos utilizados de esta clase son los siguientes:
1.- TBool IsAvailable(): Devuelve en una variable de tipo TBool
si el módulo está o no disponible.
2.- TTechnologyType TechnologyType(): El método devuelve en
una variable del tipo definido TTecnologyType el tipo de tecnología que
utiliza el módulo. La variable utilizada en mi caso es
ETechNologyTerminal.
3.- TCapabilities Capabilities(): Devuelve en una variable de tipo
enumerado TCapabilities las capacidades del módulo. En mi caso he
utilizado
las
siguientes
variables:
ECapabilitySpeed,
ECapabilityHorizontal y ECapabilityVertical.
4.-TUint32 CassesSupported( TpositionClass
Family classType): Devuelve las clases soportadas. Recibe como
parámetro una variable del tipo enumerado TPositionFamily, en mi caso
EPositionFamily.
- Clase TPositionUpdateOptions: Esta clase es la que se utiliza
para almacenar las diferentes opciones que podemos especificar a la
hora de recibir las actualizaciones sobre la información de
posicionamiento. Los métodos utilizados son los siguientes:
60
Creador de un Mapa de Cobertura
1.-void SetUpdateInterval( TTimeInterval
MicroSeconds aInter): Utilizado para establecer el intervalo de
actualización. Recibe como parámetro un objeto de la clase
TTImeIntervalMicroseconds que indica en microsegundos el tiempo del
intervalo.
2.-void SetUpdateTimeOut( TTimeinterval
Microseconds aTime): A través de este método se puede establecer el
timeout, es decir, el tiempo máximo en el que se intentará actualizar la
información acerca de la posición. Recibe como parámetro un objeto de
la clase TTimeIntervalMicroseconds que representa ese timeout en
microsegundos.
La siguiente parte de la API de Symbian OS que desarrollo a
continuación es la correspondiente al envío de todos los parámetros necesarios
para generar el punto de información en el mapa de la página Web, estos
parámetros son: niveles de cobertura GSM, GPRS, WIFI así como latitud y
longitud del punto en el que se realiza la obtención de dichos niveles.
Al igual que ocurre con la obtención del nivel de cobertura GSM y la
obtención de las coordenadas GPS, a la hora de enviar los datos necesarios a la
base del servidor no aplico directamente el código correspondiente en el
método AppUi::HandleCommandL sino que implemento una clase auxiliar, la
clase CHTTPClient, ya que la petición de envío de datos realizada al sistema
operativo se realiza a través de Active Objects, es decir utilizando hilos como
ya he comentado anteriormente, y redefinir una serie de métodos heredados de
la clase CActive.
Una vez implementada la clase CHTTPClient sólo hay que añadir a la
clase AppUi las modificaciones necesarias y en el método
AppUi::HandleCommandL realizar la llamada al método que realiza la
conexión HTTP y envía los datos al servidor. El código correspondiente a la
clase CHTTPClient es el siguiente:
61
Creador de un Mapa de Cobertura
class CHTTPClient :
public CBase,
public MHTTPTransactionCallback,
public MHTTPDataSupplier,
public MHTTPAuthenticationCallback
{
public:
static CHTTPClient* NewL(MClientObserver& iObserver);
static CHTTPClient* NewLC(MClientObserver& iObserver);
~ CHTTPClient ();
void IssueHTTPGetL(const TDesC8& aUri);
void CancelTransaction();
inline TBool IsRunning() { return iRunning; };
private:
void ConstructL();
CHTTPClient (MClientObserver& iObserver);
void SetHeaderL(RHTTPHeaders aHeaders, TInt aHdrField,
const TDesC8& aHdrValue);
private:
void MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent&
aEvent);
TInt MHFRunError( TInt aError,
RHTTPTransaction aTransaction,
const THTTPEvent& aEvent);
private:
void ReleaseData();
TBool GetNextDataPart(TPtrC8& aDataPart);
TInt Reset();
TInt OverallDataSize();
62
Creador de un Mapa de Cobertura
void SetupConnectionL();
private:
TBool GetCredentialsL( const TUriC8& aURI,
RString aRealm,
RStringF aAuthenticationType,
RString& aUsername,
RString& aPassword);
private:
RSocketServ iSocketServ;
RConnection iConnection;
RHTTPSession iSession;
RHTTPTransaction iTransaction;
MClientObserver& iObserver;
HBufC8*
iPostData;
TBool iRunning;
TBool iConnectionSetupDone;
};
La implementación correspondiente a cada uno de los métodos de la clase es la
siguiente:
CHTTPClient* CClientEngine::NewL(MClientObserver& aObserver)
{
CClientEngine* self = CClientEngine::NewLC(aObserver);
CleanupStack::Pop(self);
return self;
}
CHTTPClient* CClientEngine::NewLC(MClientObserver& aObserver)
{
CClientEngine* self = new (ELeave) CClientEngine(aObserver);
CleanupStack::PushL(self);
self->ConstructL();
return self;
63
Creador de un Mapa de Cobertura
}
CHTTPClient::CHTTPClient(MClientObserver& aObserver)
:
iObserver(aObserver),
iPostData(NULL),
iRunning(EFalse)
{
}
CHTTPClient::~CCHTTPClient()
{
iSession.Close();
// and finally close handles
iConnection.Close();
iSocketServ.Close();
delete iPostData;
}
void CHTTPClient::ConstructL()
{
TRAPD(err, iSession.OpenL());
if(err != KErrNone)
{
_LIT(KErrMsg,
"Cannot create session. Is internet access point configured?");
_LIT(KExitingApp, "Exiting app.");
CEikonEnv::Static()->InfoWinL(KErrMsg, KExitingApp);
User::Leave(err);
}
InstallAuthenticationL(iSession);
}
void CHTTPClient::SetHeaderL(RHTTPHeaders aHeaders,
TInt aHdrField,
const TDesC8& aHdrValue)
{
RStringF valStr = iSession.StringPool().OpenFStringL(aHdrValue);
CleanupClosePushL(valStr);
THTTPHdrVal val(valStr);
aHeaders.SetFieldL(iSession.StringPool().StringF(aHdrField,
64
Creador de un Mapa de Cobertura
RHTTPSession::GetTable()), val);
CleanupStack::PopAndDestroy();
}
void CHTTPClient::IssueHTTPGetL(const TDesC8& aUri)
{
SetupConnectionL();
TUriParser8 uri;
uri.Parse(aUri);
RStringF method = iSession.StringPool().StringF(HTTP::EGET,
RHTTPSession::GetTable());
iTransaction = iSession.OpenTransactionL(uri, *this, method);
RHTTPHeaders hdr = iTransaction.Request().GetHeaderCollection();
SetHeaderL(hdr, HTTP::EUserAgent, KUserAgent);
SetHeaderL(hdr, HTTP::EAccept, KAccept);
iTransaction.SubmitL();
iRunning = ETrue;
}
void CHTTPClient::IssueHTTPPostL(const TDesC8& aUri,
const TDesC8& aContentType,
const TDesC8& aBody)
{
SetupConnectionL();
TUriParser8 uri;
uri.Parse(aUri);
delete iPostData;
iPostData = aBody.AllocL();
RStringF method = iSession.StringPool().StringF(HTTP::EPOST,
RHTTPSession::GetTable());
iTransaction = iSession.OpenTransactionL(uri, *this, method);
RHTTPHeaders hdr = iTransaction.Request().GetHeaderCollection();
SetHeaderL(hdr, HTTP::EUserAgent, KUserAgent);
SetHeaderL(hdr, HTTP::EAccept, KAccept);
SetHeaderL(hdr, HTTP::EContentType, aContentType);
65
Creador de un Mapa de Cobertura
MHTTPDataSupplier* dataSupplier = this;
iTransaction.Request().SetBody(*dataSupplier);
iTransaction.SubmitL();
iRunning = ETrue;
}
void CHTTPClient::CancelTransaction()
{
if(!iRunning)
return;
iTransaction.Close();
iRunning = EFalse;
TBuf<20> ibuff;
ibuff.Copy(_L("Transaccion Cancelada"));
CEikonEnv::InfoWinL(_L(""), ibuff);
}
void CHTTPClient::MHFRunL(RHTTPTransaction aTransaction,
const THTTPEvent& aEvent)
{
switch (aEvent.iStatus)
{
case THTTPEvent::EGotResponseHeaders:
{
RHTTPResponse resp = aTransaction.Response();
TInt status = resp.StatusCode();
TBuf<KStatustextBufferSize> statusText;
statusText.Copy(resp.StatusText().DesC());
TBuf<KDefaultBufferSize> text;
}
break;
case THTTPEvent::EGotResponseBodyData:
{
MHTTPDataSupplier* body = aTransaction.Response().Body();
TPtrC8 dataChunk;
TBool isLast = body->GetNextDataPart(dataChunk);
iObserver.ClientBodyReceived(dataChunk);
66
Creador de un Mapa de Cobertura
TBuf<KInfotextBufferSize> text;
body->ReleaseData();
}
break;
case THTTPEvent::EResponseComplete:
{
}
break;
case THTTPEvent::ESucceeded:
{
aTransaction.Close();
iRunning = EFalse;
User:: Exit(KErrNone);
}
break;
case THTTPEvent::EFailed:
{
aTransaction.Close();
iRunning = EFalse;
}
break;
default:
{
TBuf<KInfotextBufferSize> text;
if (aEvent.iStatus < 0)
{
aTransaction.Close();
iRunning = EFalse;
}
else
{
}
iObserver.ClientEvent(text);
}
break;
}
}
TInt CHTTPClient::MHFRunError(TInt aError,
RHTTPTransaction /*aTransaction*/,
const THTTPEvent& /*aEvent*/)
{
67
Creador de un Mapa de Cobertura
TBuf<KInfotextBufferSize>
text;
text.AppendNum(aError);
CEikonEnv::InfoWinL(_L("MHFRunError: "), text);
iObserver.ClientEvent(text);
return KErrNone;
}
TBool CHTTPClient::GetNextDataPart(TPtrC8& aDataPart)
{
if(iPostData)
{
aDataPart.Set(iPostData->Des());
}
return ETrue;
}
void CHTTPClient::ReleaseData()
{
// It's safe to delete iPostData now.
delete iPostData;
iPostData = NULL;
}
TInt CHTTPClient::Reset()
{
return KErrNone;
}
TInt CHTTPClient::OverallDataSize()
{
if(iPostData)
return iPostData->Length();
else
return KErrNotFound ;
}
TBool CHTTPClient::GetCredentialsL(const TUriC8& aURI,
RString aRealm,
RStringF aAuthenticationType,
RString& aUsername,
RString& aPassword)
{
TBuf<KDefaultBufferSize> userName;
TBuf<KDefaultBufferSize> password;
CAknMultiLineDataQueryDialog* dlg =
CAknMultiLineDataQueryDialog::NewL(userName, password);
68
Creador de un Mapa de Cobertura
TBuf8<KDefaultBufferSize> temp;
temp.Copy(userName);
TRAPD(err, aUsername = aRealm.Pool().OpenStringL(temp));
if (!err)
{
temp.Copy(password);
TRAP(err, aPassword = aRealm.Pool().OpenStringL(temp));
if (!err) return ETrue;
}
return EFalse;
}
void CHTTPClient::SetupConnectionL()
{
if( iConnectionSetupDone )
return;
iConnectionSetupDone = ETrue;
User::LeaveIfError(iSocketServ.Connect());
User::LeaveIfError(iConnection.Open(iSocketServ));
CCommsDatabase* commDB = CCommsDatabase::NewL(EDatabaseTypeIAP);
CleanupStack::PushL(commDB);
// initialize a view
CCommsDbConnectionPrefTableView* commDBView =
commDB>OpenConnectionPrefTableInRankOrderLC(ECommDbConnectionDirection
Unknown);
User::LeaveIfError(commDBView->GotoFirstRecord());
CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref pref;
commDBView->ReadConnectionPreferenceL(pref);
TUint32 iapID = pref.iBearer.iIapId;
CleanupStack::PopAndDestroy(commDBView);
CleanupStack::PopAndDestroy(commDB);
TCommDbConnPref connectPref;
connectPref.SetDialogPreference(ECommDbDialogPrefPrompt);
connectPref.SetDirection(ECommDbConnectionDirectionOutgoing);
User::LeaveIfError(iConnection.Start(connectPref));
69
Creador de un Mapa de Cobertura
RStringPool strPool = iSession.StringPool();
RHTTPConnectionInfo connInfo = iSession.ConnectionInfo();
connInfo.SetPropertyL ( strPool.StringF(HTTP::EHttpSocketServ,
RHTTPSession::GetTable() ), THTTPHdrVal (iSocketServ.Handle())
);
connInfo.SetPropertyL (
strPool.StringF(HTTP::EHttpSocketConnection,
RHTTPSession::GetTable() ),
THTTPHdrVal (REINTERPRET_CAST(TInt, &(iConnection))) );
}
- Clase RSocketServ: Esta clase tiene como principal objetivo
proporcionar la conexión para crear una comunicación a través del canal
IPC mediate con el servidor Socket. Los métodos utilizados de esta
clase son los siguentes:
1.- TInt Connect(): Abre una sesión con el servidor Socket.
Devuelve una variable de tipo TInt que representa el código de error de
Symbian OS o KErrNone en caso de que no haya habido ningún
problema.
2.- void Close(): Se encarga de cerrar la sesión previamente
establecida con el servidor Socket.
- Clase RConnection: Esta clase representa la principal interfaz
para administrar una conexión o subconexión a la red. Proporciona al
cliente la apertura y cierre de sesión, comenzar o detener la conexión,
obtener información acerca del progreso durante la conexión leer
campos pertenecientes a la base de datos CommDB, y un largo etc. Los
métodos que ha sido necesario utilizar son los siguientes:
1.- TInt Open(RSocketServ aServ): El método consiste en abrir
una nueva instancia de la clase RConnection. Recibe como único
argumento un objeto de la clase RSocketServ que representa la sesión
con el servidor Socket previamente establecida. Devuelve una variable
70
Creador de un Mapa de Cobertura
del tipo TInt que representa el código de error de Symbian OS y
KErrNone si no ocurre ningún tipo de problema.
2.- TInt Start(TConnPref aPref): Comienza una conexión
sobrescribiendo las preferencias que se indican en el parámetro que
recibe de entrada en la base de datos CommDB. Las preferencias que
permite sobrescribir son las siguientes: IAP id, Network id, Dialog
preferente, Direction y Bearer Set. Devuelve una variable de tipo TInt
que representa el código de error de Symbian OS en caso de que ocurra
algún tipo de fallo o KErrNone si no hay problema.
3.- void Close(): Cierra la conexión.
-Clase RHTTPSession: Esta clase representa el manejador de
sesión, entendiendo por sesión un conjunto de transacciones http que
utilizan la misma configuración a la hora de realizar una conexión. De
esta clase se utilizan los siguientes métodos:
1.- void OpenL(): Para utilizar este método hay que cumplir la
precondición de que la sesión esté cerrada. El método abre una sesión
utilizando por defecto el protocolo HTTP/TCP.
2.- RStringPool StrigPool(): El método permite acceso para el
“string pool” propio de HTTP. Devuelve un objeto de la clase
RStringPool, que se detalla más adelante.
3.- RHTTPConnectionInfo ConnectionInfo(): Permite acceso a la
información de conexión de la sesión. Esta información de conexión
debe ser establecida antes de que la primera transacción sea realizada.
Devuelve un objeto de la clase RHTTPConnectionInfo, que se detalla
más adelante, que permite estabelecer dicha información de conexión.
4.RHTTPTransaction OpenTransactionL(TUriC8 aUri,
MHTTPTransactionCallBack aCallBack, RStrinF amethod): Este es el
método utilizado para crear una transacción. Recibe como argumento un
objeto de la clase TUriC8 que indica la url a la cual vamos a realizar la
petición, un objeto de la clase MHTTPTransactionCallback que
comprueba el estado de los eventos relacionados con las transacciones, y
71
Creador de un Mapa de Cobertura
por último un objeto de la clase RStringF que indica el método con el
que se quiere realizar dicha petición, por defecto GET.
- Clase RHTTPTransaction: representa una transacción http. Esta
clase encapsula a una petición http y a una respuesta http. Una
transacción es asociada con una sesión por lo que debe ser creada
utilizando el método CreateTransactionL. Los métodos utilizados
pripios de esta clase son los sigientes:
1.- RHTTPRequest Request(): Método a través del cual
obtenemos la petición en un objeto de la clase RHTTPRequest.
2.- void SubmitL(): A través de este método se solicita una
transacción. El método provoca que la transacción sea hecha.
3.- void Close(): El método se utiliza para cerrar la transacción y
liberar todos los recursos.
4.- RHTTPResponse Response(): Método a través del cual
obtenemos la respuesta en un objeto de la clase RHTTPResponse, que se
detalla más adelante.
- Clase MHTTPAuthemticationCallBack: Surge la necesidad de
implementar esta clase si es soportada la autentificación. Es utilizada
para sustituir nombre y contraseña cuando son necesarios para
autentificar. El método que se utiliza de esta clase es el siguiente:
1.- void InstallAuthenticationL(RHTTPSession aSession):
Gracias a la llamada a este método la sesión que recibe como parámetro
a través de un objeto de la clase RHTTPSession soporta autentificación.
- Clase RHTTPHeaders: esta clase representa la colección de
cabeceras asociadas con un mensaje. Estas cabeceras pueden ser
creadas, leídas y modificadas. El método utilizado de esta clase es el
siguiente:
1.- void SetFieldL(RString aFieldName, THTTPHdrVal
aFieldvalue): El método es utilizado para establecer el campo nombre en
la cabecera. Recibe como parámetros un objeto de la clase RString que
72
Creador de un Mapa de Cobertura
representa el nombre del campo y un objeto de la clase THTTPHdrVal
que indica el valor de dicho campo.
- Clase TUriParser8: Esta clase es utilizada ya que proporciona
funcionalidad a la hora de transformar un descriptor en una url. El
método que se utiliza de esta clase es el siguiente:
1.- TInt Parse(TDesC8 aUri): Pasa el objeto de la clase TDesC8 a
componente url. Devuelve una variable de tipo TInt que representa el
código de error de Symbian OS en caso de que se produzca un problema
o KErrNone si el método se ejecuta de manera correcta.
- Clase RHTTPResponse: Representa una respuesta http. El
método que se utiliza de esta clase es el siguiente:
1.- TInt StatusCode(): Devuelve en una variable de tipo TInt el
código de estado.
- Clase CCommDataBase: Esta clase permite acceder a la base
de datos de las comunicaciones. Los métodos propios de esta clase que
su utilizan son los siguientes:
1.- CCommDataBase* NewL(TCommDbDataBaseType type):
Este método se utiliza para crear una nueva instancia de un objeto de
esta clase. Al realizar la llamada a este método se acumula en la pila la
referencia que devuelve el método. Recibe como parámetro una variable
del tipo definido TCommDatabaseType, en mi caso utilizo
EDatabaseTypeIAP.
2.-CCommsDbConnectionPrefTableView*
OpenConnectionPrefTableInRankOrderLC(TCommDbConnectionDire
ction dir): Se utiliza para abrir una vista de la tabla que contiene las
preferencias de conexión. Devuelve la referencia a un objeto de la clase
CCommsDbConnectionPrefTable que se detalla más adelante, y recibe
como
parámetro
una
variable
del
tipo
enumerado
TCommDbConnectionDirection,
que
en
mi
caso
es
ECommDbConnectionDirectionUnknown.
73
Creador de un Mapa de Cobertura
- Clase CCommsDbConnectionprefTableView: Esta clase es
utilizada para implementar cualquier tipo de acción en la tabla de
preferencias de conexión. Permite al cliente establecer el orden en el que
las conexiones serán atendidas. Los métodos utilizados de esta clase son
los siguientes:
1.- TInt GoToFirstRecord(): Este método permite establecer la
primera preferencia de conexión existente en la vista como preferencia
de la conexión actual. Devuelve una variable de tipo TInt que contendrá
KErrNotFound en el caso de que la tabla no tenga almacenada ninguna
preferencia para la conexión o el código de error de la base de datos de
conexiones en el caso de que haya ocurrido algún problema.
2.-void ReadConnectionPreferenceL (TCommDbIap
ConnectionPref aPref): El método se utiliza para obtener en un objeto
de la TCommDbConnectionPref, que se detalla a continuación, el IAP
(punto de acceso a internet) de la preferencia de conexión actualmente
seleccionada en la tabla. Este método puede provocar una salida en el
código en caso de que no esté almacenada ninguna preferencia de
conexión actual en la vista devolviendo KErrNotFound o en caso de que
la tabla de preferencias de conexión esté vacía, devolviendo
KErrUnknown.
-Clase TCommDbIapConnectionPref: Esta clase encapsula la
dirección y las opciones que aparecen en el cuadro de dialogo para
seleccionar el IAP (punto de acceso a internet). De esta clase solo se
utiliza el atributo iBearer, que es de la clase TCommDbIapBearer, que a
su vez posee el atributo iIapId de tipo TUint32 que es el que interesa.
- Clase TCommDbConnPref: Esta clase permite establecer una
serie de preferencias a la hora de realizar una conexión. Los métodos
utilizados propios de esta clase son los siguientes:
1.- void SetDialogPreference(TCommDbDialogPref aDialogPr):
Este método se utiliza para establecer las preferencias de dialogo que se
utilizan en la conexión. Recibe como parámetro una variable del tipo
enumerado
TCommDbDialogPref
que
en
mi
caso
es
EcommDbDialogPrefPromt, para que podamos elegir a través del
74
Creador de un Mapa de Cobertura
cuadro de dialogo la forma en la que queremos establecer el punto de
acceso a internet.
2.- void SetDirection(TCommDbConnectionDirection aDir): Se
utiliza para establecer la dirección de la conexión. Recibe como
parámetro de entrada una variable del tipo enumerado
TcommDbConnectionDirection
que
en
mi
caso
es
ECommDbConnectionDirectionOutgoing.
- Clase RHTTPConnectionInfo: A través de esta clase podemos
establecer u obtener los valores utilizados de la conexión en relación
con el protocolo. El método utilizado de esta clase es el siguiente:
1.- void SetPropertyL(RstringF propertyName, THTTPHdrVal,
aValue): Gracias a este método podemos crear o modificar el valor de
una propiedad. Recibe como parámetros un objeto de la clase RstringF
que representa el nombre de la propiedad y un objeto de la clase
THTTPHdrVal que indica el valor de dicha propiedad.
- Clase RHTTPResponse: Esta clase representa una respuesta
http. Elmétodo utilizado de esta clase es el siguiente:
1.- MHTTPDataSupplier* Body(): El método devuelve una
referencia a un objeto de la clase MHTTPDataSupplier que representa el
cuerpo de la transacción.
Para finalizar con este apartado, la siguiente parte de la API de Symbian
OS que se desarrollará a continuación es la relacionada con la obtención del
nivel de cobertura GPRS. Para poder obtener este nivel, no he tenido que
implementar una clase auxiliar para realizar la petición al sistema operativo,
sino que aplico directamente el código necesario en la clase AppUi al igual que
sucede como se comentó anteriormente con la obtención del nivel de cobertura
WIFI. El código que hace posible acceder al nivel de cobertura GPRS es el
siguiente:
75
Creador de un Mapa de Cobertura
RConnectionMonitor monitor;
monitor.ConnectL();
CleanupClosePushL(monitor);
TRequestStatus status;
TInt iSignalStrength;
monitor.GetIntAttribute( EBearerIdGPRS, 0, KSignalStrength,
iSignalStrength, status );
User::WaitForRequest(status);
User::LeaveIfError(status.Int());
TInt decibelios = iSignalStrength;
if(decibelios<94){
iSignalGPRS = 100;
}
else{
decibelios = decibelios - 94;
TReal porcentaje = decibelios*4.14;
iSignalGPRS = 100-porcentaje;
}//cierre del else
if(iSignalGPRS>100)
iSignalGPRS = 100;
TRealFormat iformat;
TBuf<20> ibuff;
ibuff.Zero();
ibuff.AppendNum(iSignalGPRS, iformat);
CEikonEnv::InfoWinL(_L("Cobertura GPRS en %: "), ibuff);
ibuff.Zero();
ibuff.AppendNum(iSignalStrength);
CEikonEnv::InfoWinL(_L("Cobertura GPRS en dB: "), ibuff);
CleanupStack::PopAndDestroy();
-Clase RConnectionMonior: Es la única clase que se utiliza en
esta parte de la API de Symbian OS, permitiéndonos acceder y utilizar
los servicios relacionados con redes que la plataforma s60 proporciona.
La clase contiene los siguientes métodos:
76
Creador de un Mapa de Cobertura
1.- TInt ConnectL(): Este método nos permite conectar el cliente
que desea realizar la petición con el servidor Connection Monitor.
Devuelve una variable de tipo TInt que representa el código de error de
Symbian OS en caso de que se haya producido algún fallo en la llamada
o KErrNone si todo se realiza de manera satisfactoria.
2.- void GetIntAttribute(TUint aConnId, TUint aSubConnId,
TUint aAttribute, TInt aValue, TRequestStatus status): Se utiliza para
obtener el atributo de tipo TInt que indiquemos. Recibe como primer
parámetro una variable de tipo TUint que representa el Id de la
conexión, pero en mi caso utilizo la constante EBearerIdGPRS del tipo
enumerado TConnMonBearerId. Como segundo parámetro recibe una
variable de tipo TUint que indica el Id de la sebconexión pero en mi
caso es 0. Como tercer parámetro recibe una variable de tipo TUint que
representa el atributo el cual queremos obtener su valor, yo utilizo la
constante KSignalStrength para indicar que quiero obtener el valor de
intensidad de señal, es decir, el nivel de cobertura. Como cuarto
parámetro tenemos una variable de tipo TInt donde almacenamos el
valor del nivel de cobertura y por último recibe una variable de tipo
TRequestStatus que almacena KErrNone si todo se realiza
correctamente o el código de error de Symbian OS si se produce algún
fallo.
77
Creador de un Mapa de Cobertura
Capítulo 5:
Manual de la Aplicación a nivel de
usuario
En este capítulo de la memoria me gustaría explicar el funcionamiento
de la aplicación Symbian OS de este proyecto fin de carrera desde el punto del
usuario final. Como he comentado en anteriores ocasiones, siempre he
intentado que la aplicación fuera lo más sencillo posible de entender de forma y
manera que pudiera ser utilizada por cualquier tipo de usuario sin que éste
tuviera que poseer algún tipo de conocimiento adicional.
A continuación se muestran a modo de guía cada uno de los pasos que
debemos seguir para utilizar la aplicación de forma correcta:
Al abrir la aplicación y pulsando sobre el menú “options” nos
encontramos con las siguientes opciones:
78
Creador de un Mapa de Cobertura
En primer lugar seleccionamos “Cobertura WLAN” para obtener el
nivel de cobertura WIFI existente. El dispositivo móvil nos irá mostrando por
cada red encontrada el nombre de dicha red así como su nivel de cobertura en
dB, para finalmente mostrarnos el nivel medio de cobertura WLAN en % y en
dB. Una vez que ejecutemos esta opción se almacena en una variable interna
dicho valor. No incluyo aquí ninguna imagen de este paso puesto que he
realizado esta guía con el emulador que la SDK pone a nuestra disposición y no
soporta acceso a WIFI.
En segundo lugar seleccionamos la opción “Cobertura GPRS” con el fin
de obtener el nivel de cobertura GPRS que existe en el punto en el cual
realizamos la medida. El dispositivo móvil nos mostrará el nivel de cobertura
GPRS existente tanto en dB como en %, como se puede observar en las
siguientes imágenes:
79
Creador de un Mapa de Cobertura
Una vez realizado este paso almacenamos dicho valor de cobertura
GPRS en una variable interna.
El siguiente paso es seleccionar la opción “Cobertura GSM” a través de
la cual obtenemos el nivel de cobertura GSM y el número de barras de
cobertura que muestra el dispositivo móvil.
80
Creador de un Mapa de Cobertura
Al igual que sucediera con los niveles de cobertura WIFI y GPRS, al
obtener el nivel de cobertura GSM, dicho valor queda almacenado en una
variable interna. Después de seleccionar esta opción en el menú, en el momento
en que se produzca una variación en el nivel de cobertura GSM obtendremos
una notificación indicándonos los nuevos valores actualizados.
A continuación, una vez obtenidos los niveles de cobertura GSM, GPRS
y WIFI, el siguiente paso es obtener las coordenadas, es decir, latitud y longitud
del punto en el cual realizamos la medida de dichos niveles. Para ellos
seleccionamos la opción “Obtener Latitud y Longitud” obteniendo el siguiente
resultado:
81
Creador de un Mapa de Cobertura
Es importante destacar que a la hora de seleccionar la opción “Obtener
latitud y Longitud” esta aplicación devuelve en primer lugar la última posición
que quedó almacenada en el servidor, por lo que para obtener las coordenadas
de la posición actual habría que estar en movimiento y en el instante en que se
encontrara un satélite irían apareciendo en pantalla cada una de las
coordenadas, de forma que a medida que fuéramos avanzando estas
coordenadas se irían actualizando constantemente. Una vez hecho esto, los
últimos valores obtenidos son los que quedarían almacenados en variables
internas.
Una vez obtenidos todos los valores necesarios, el último paso de
nuestra aplicación sería enviar dichos valores a la base de datos del servidor.
Para llevar a cabo este paso tendríamos que seleccionar la opción “Enviar datos
al Servidor”. Al ejecutar esta opción se ejecuta un método que recibe como
parámetros las variables internas que almacenan cada uno de los valores
necesarios y establece una conexión http con una url, mostrando el
correspondiente mensaje de error en caso de que la transacción no se haya
realizado correctamente o cerrándose la aplicación en caso de que todo haya
ocurrido con normalidad.
82
Creador de un Mapa de Cobertura
Para finalizar, desde el propio dispositivo móvil a través de
http://alvaro.netne.net/moviles.htm podríamos comprobar de manera visual que
se ha insertado el correspondiente marcador con su información en el mapa.
83
Creador de un Mapa de Cobertura
Capítulo 6:
Pruebas
Con el objetivo de comprobar el correcto funcionamiento de la
aplicación, he decidido realizar una serie de pruebas obteniendo los niveles de
cobertura GSM, GPRS y WIFI, enviando dichos datos junto con las
coordenadas GPS del punto en el que realizo la medida a la base de datos del
servidor, comprobando en el mapa de la página Web que se genera el
correspondiente marcador y que la información mostrada es correcta.
La aplicación muestra los niveles de cobertura GSM, GPRS y WIFI así
como las coordenadas GPS de cualquier punto en el que deseemos ejecutarla,
pero a la hora de enviar los datos al servidor, para que las pruebas no supongan
ningún coste, siempre quise realizar las medidas en una serie de puntos en los
que dispusiera de una red WIFI a la cual pudiera acceder, ya que he realizado
todas las pruebas utilizando como dispositivo móvil el modelo N95 de Nokia.
84
Creador de un Mapa de Cobertura
La primera de las pruebas la realicé en mi casa, en la calle c/Jiménez
Aranda, donde las coordenadas son: latitud 37,3868211363 y longitud
5,9808381089, obteniendo los siguientes niveles de cobertura: 71.0% de la red
GSM, 66.88% de red GPRS y 69.0% de red WIFI. En la siguiente imagen se
puede observar como se genera el marcador en el lugar adecuado con la
correspondiente información:
La segunda de las pruebas decidí llevarla a cabo en el centro de
formación Diasoft, en donde actualmente estoy realizando un Máster. Este
centro se encuentra en la calle c/Samuel Morse, cuyas coordenadas son: latitud
37,375816 y longitud -6,0085702, obteniendo una cobertura GSM del 85.2%,
una cobertura GPRS del 83.44 y una cobertura WIFI del 100%. En la siguiente
imagen se puede observar el marcador y la información asociada a él:
85
Creador de un Mapa de Cobertura
La siguiente de las pruebas está realizada en la Facultad de Ciencias
Económicas y Empresariales, situada en la avenida Av. Ramón y Cajal cuyas
coordenadas son las siguientes: latitud 37,377740000 y longitud 5,9765466667. A la hora de medir los niveles de cobertura obtuve el siguiente
resultado: para la red GSM un 99.4%, para la red GPRS un 100% y para la red
WIFI un 28.9%. A continuación en la imagen se puede observar el marcador
mostrando los correspondientes datos:
86
Creador de un Mapa de Cobertura
En siguiente lugar, quise realizar una prueba en la escuela E.T.S.
Ingeniería Informática, en la misma puerta, en la avenida Av. Reina Mercedes
donde las coordenadas de dicho punto tienen el siguiente valor: latitud
37,3578916667 y longitud 7 -5,9865650000, y donde el dispositivo móvil
mostraba los siguientes valores: para la red GSM el 99.4%, para la red GPRS el
100%, y en el caso de la red WIFI el 51.12%. Aquí en la siguiente imagen
puede comprobarse como el marcador del mapa muestra los datos
correctamente:
Una vez me desplacé hasta reina Mercedes para realizar la prueba
anterior, creí oportuno realizar más pruebas en algunos puntos del campus,
aprovechando por supuesto la red WIFI que la universidad pone a disposición
de los alumnos para enviar los datos al servidor. La siguiente prueba realiza en
esta zona fue en la Facultad de Biología, en el edificio rojo. En dicho punto se
obtienen las siguientes coordenadas: latitud 37,3599850000 y longitud 5,9879366667. En dicho punto los niveles de cobertura detectados por la
aplicación fueron: 99.4% para la red GSM, 100% para la red GPRS y 60.0 para
la red WIFI. En la imagen puede apreciarse como se genera el marcador en el
lugar exacto del mapa mostrando los niveles de cobertura:
87
Creador de un Mapa de Cobertura
A continuación, la siguiente prueba fue realizada también en la Facultad
de Biología pero en este caso en el edificio verde. Dicho punto posee las
siguientes coordenadas: latitud 37,3597700000 y longitud -5,9870100000. Una
vez ejecutada la aplicación, pude obtener los siguientes niveles de cobertura:
85.2% de red GSM, 83.44% de red GPRS y 71.12% de red WIFI. A
continuación se muestra en la imagen el marcador en el mapa mostrando los
niveles obtenidos:
88
Creador de un Mapa de Cobertura
En último lugar, para finalizar con este apartado, la E.T.S. Arquitectura
fue el punto en el que decidí realizar la última de las pruebas. En dicho punto
pueden obtenerse las siguientes coordenadas: latitud 37,362518333 y longitud 5,9865600000. El dispositivo móvil mostraba los siguientes niveles al ejecutar
la aplicación: 99.4% para la red GSM, 100% para la red GPRS y 86.68% para
la red WIFI. En la correspondiente imagen se observa en el mapa el marcador
en el mapa mostrando la información relativa a dichos niveles:
89
Creador de un Mapa de Cobertura
Capítulo 7:
Herramientas
7.1.- Microsoft Expression Web
A la hora de plantearnos el desarrollo de una aplicación Web debemos
decantarnos por utilizar el software que más se adapte a nuestras necesidades.
En mi caso, la página Web que realizo forma parte del proyecto al igual que la
aplicación Symbian pero en ningún momento es el objetivo fundamental por lo
que decidí utilizar un software fácil y rápido de entender y a la vez completo en
el sentido de que me permitiera implementar todos los requisitos que debe
cumplir la Web.
En la actualidad existen infinitas herramientas para el diseño de páginas
Web utilizando todas y cada una de las tecnologías más actuales. Para la
realización de la página Web a través de la cual accedemos de una manera más
visual a los niveles de cobertura obtenidos he utilizado Microsoft Expression
Web. Esta herramienta se puede utilizar de forma sencilla e intuitiva, dispone
de un servidor local para comprobar el resultado y funcionamiento de la Web,
validando nuestro contenido contra el estándar que deseemos seguir o
90
Creador de un Mapa de Cobertura
navegador sobre el que vayamos a montar nuestra aplicación. A la vez se puede
obtener de forma gratuita a través de Suscripción MSDN-AA en la web de la
escuela como cualquier software de Microsoft. La versión que instalé fue la
v12.0.04518 con todas las opciones por defecto.
7.2.- MySQL y phpMyAdmin
Debido a la necesidad de disponer de una base de datos en la que poder
almacenar los niveles de cobertura GSM, GPRS y WIFI así como las
coordenadas del punto en el que se obtienen dichos niveles, es necesario que el
servidor del alojamiento web utilizado nos permita acceder y hacer uso de estas
dos herramientas, imprescindibles para poder conectarse a la base de datos,
insertar valores y recorrer dichos datos para ir generando los marcadores y la
información asociada a cada marcador de manera correcta.
7.3.- Herramientas necesarias para la programación
en Symbian OS
En este apartado intentaré explicar cuales han sido las herramientas
necesarias para conseguir programar mi aplicación en Symbian OS, así como su
orden de instalación.
1. En primer lugar es necesaria la instalacion de Perl, debido a su
utilización en la ejecución de algunos comandos, necesarios para la
creación de algunos archivos, construir proyectos (build project) etc.
Este software se puede obtener de forma totalmente gratuita a través de
http://www.activestate.com/ y es conveniente siempre descargarse la
versión más actual posible e instalarla con las opciones por defecto. La
versión que yo he utilizado es la v5.10.0.
2. En segundo lugar tenemos que instalar Java Runtime Environment para
el correcto funcionamiento de la SDK. Este software también lo
podemos descargar de forma gratuita a través de http://www.sun.com/
descargándonos como siempre la versión más actual posible. En mi caso
estoy utilizando la versión v1.6.0.13 es decir, version 6 update 13.
91
Creador de un Mapa de Cobertura
3. El siguiente paso es instalar el entorno de desarrollo (IDE) que vamos a
utilizar para implementar la aplicación Symbian. En mi caso, elegí
Carbide.c++ Express Edition como entorno de desarrollo debido a que
la única manera de implementar mi aplicación es utilizando Symbian
C/C++, es una versión totalmente gratuita, es el entorno más actual que
existe para desarrollar aplicaciones Symbian y a la vez el más usado por
la mayoría de desarrolladores de este tipo de aplicaciones. La versión
que he utilizado es la v2.0.2. Este IDE puede ser descargado a través de
http://www.forum.nokia.com/.
4. Una vez instalado el IDE, el siguiente paso será la instalación de la
correspondiente SDK que como ya he comentado anteriormente está
relacionada con la versión del sistema operativo Symbian que utiliza el
dispositivo móvil en el que ejecutaremos la aplicación. A través de
http://www.forum.nokia.com/devices/matrix_all_1.html
podemos
seleccionar el dispositivo móvil que utilizaremos y descargarnos de
forma gratuita la SDK que se nos aconseja. En mi caso, al utilizar como
dispositivo móvil el modelo N95 de Nokia que utiliza un sistema
operativo Symbian Os v9.2 he instalado la SDK s60 3erd FP1.
Una vez instaladas todas estas herramientas ya podemos comenzar a
desarrollar cualquier tipo de aplicacion Symbian para nuestro dispositivo móvil.
92
Creador de un Mapa de Cobertura
Capítulo 8:
Aplicaciones Futuras
La funcionalidad que pueden aportar las dos partes de este proyecto, es
decir, tanto la aplicación Symbian como la aplicación Web está ampliamente
relacionada con la necesidad del usuario de conocer los niveles de cobertura
GSM, GPRS y WIFI de un punto determinado.
Uno de los posibles usos de la aplicación y posiblemente el principal es
obtener los niveles exactos de cobertura GSM, GPRS y WIFI que nos ofrece el
operador de telefonía que estamos utilizando, para poder comprobar si
realmente disponemos de la cobertura que nos garantiza.
Otra posible utilidad que nos puede proporcionar la aplicación es la
relacionada con un cliente que quiera contratar uno de lo servicios de internet a
través de USB que actualmente ofertan los operadores de telefonía. Si el cliente
quiere utilizar este servicio únicamente en un punto determinado, puede
comprobar de antemano el nivel de cobertura WIFI que realmente existe en ese
93
Creador de un Mapa de Cobertura
punto y en el caso de que no sea suficiente comprobar si le merece la pena o no
contratar dicho servicio.
También puede ser útil la aplicación para cualquier usuario que quiera
comprobar la posibilidad de trabajar a distancia. Por ejemplo, una persona que
trabaja realizando cualquier tarea en el campo, puede comprobar los niveles de
cobertura existentes, y tantear la posibilidad de colocar un autómata que sea
capaz de realizar dichas tareas comunicándose con él a través de WIFI.
Otro usuario al que puede interesarle la aplicación es aquel que quiera
instalar una fábrica en un determinado punto lejos de la ciudad. Antes de
desplazarse a ese punto para realizar cualquier tipo de comprobación acera del
nivel de cobertura existente puede acceder a través de la página Web de manera
visual a dichos niveles, determinando si la zona cumple o no los requisitos
deseados en cuanto a cobertura.
También se pueden encontrar más utilidades a la aplicación utilizando
siempre como referente la posición, para poder utilizar la aplicación a modo de
localizador y los niveles de cobertura disponibles para tener siempre la opción
de elegir que red queremos utilizar para enviar dicha posición.
En este sentido la aplicación puede ser utilizada por una flota de
camiones u otro tipo de vehículos que sean utilizados para la entrega y recogida
de mercancía. A la hora de tener que especificar la localización exacta del
vehículo, para tener siempre localizada la mercancía, como gracias a esta
aplicación conocemos las coordenadas y los niveles de cobertura GSM, GPRS y
WIFI el sistema siempre puede intentar enviar dichas coordenadas de
localización a través de WIFI para ahorrar costes siempre y cuando fuera
posible. En caso contrario tendría que hacer uso de la red GPRS con los costes
que conlleva.
Otra funcionalidad que se puede añadir a la aplicación siguiendo esta
idea de poder elegir la red a la hora de mandar información relacionada con la
localización es en caso de robo del dispositivo móvil. En este caso podemos
enviar un sms al dispositivo móvil en cuestión para que nos envíe las
coordenadas exactas de su posición actual siempre teniendo la opción de elegir
la red debido a que se conocen los niveles de cobertura gracias a la aplicación.
Esta idea no sólo puede ser aplicada en caso de robo del dispositivo móvil ya
que puede ser utilizada para recibir información acerca de la localización de un
dispositivo móvil, por ejemplo de un menor de edad por cualquier motivo, sin
94
Creador de un Mapa de Cobertura
que suponga ningún coste dado que el dispositivo móvil conoce el nivel de
cobertura WIFI gracias a la aplicación y por tanto puede hacer uso de este
recurso.
Es posible también que haya casos en los que la opción de poder elegir
la red a utilizar no esté relacionada únicamente con el ahorro de costes sino que
también esté relacionada con la calidad de cada red. Esta idea puede ser
aplicada para aquellas empresas o personas que tengan una elevada necesidad
de enviar una serie de datos y por tanto deban disponer siempre de la mejor de
las redes disponibles, es decir, la red que más nivel de cobertura posea. Para
llevar a cabo esta idea se podría añadir algún tipo de implementación a esta
aplicación que permita al dispositivo móvil cambiar automáticamente de red en
cuestión del nivel de cobertura, que tanto para GSM, GPRS y WIFI sería
conocido.
Por último, y para finalizar este apartado, una funcionalidad que se
podría añadir en un futuro a la Web es la de poder establecer una serie de
opciones a la hora de mostrar los marcadores en el mapa. Esto se podría realizar
a través de una serie de campos en un formulario que nos permitiera introducir
opciones para que se nos mostraran en el mapa sólo aquellos marcadores que
sean de nuestro interés como por ejemplo los de una ciudad concreta, los que
representen zonas donde la cobertura supera un nivel mínimo introducido, etc.
95
Creador de un Mapa de Cobertura
Capítulo 9:
Análisis Temporal
En este capítulo intentaré mostrar un resumen aproximado del tiempo
empleado en realizar este proyecto. Cuantificando este tiempo en horas se
obtienen un total de 336 horas dedicadas al proyecto, las cuales se agrupan en
cuatro tareas principales que son las siguientes:
 Investigación
Dentro de este grupo podemos englobar todas las tareas previas a la
implementación, desde la elección y el estudio de la tecnología a
utilizar, investigación acerca del sistema operativo Symbian, entornos y
lenguajes de programación adecuados, etc. En mi caso, el lenguaje de
programación Symbian C++ no es de los más conocidos por lo que he
necesitado un estudio en profundidad para familiarizarme con él y con
el entorno de trabajo que he utilizado. Durante el desarrollo de la
aplicación Symbian también se ha requerido tiempo de investigación
para solventar cada una de las dudas y problemas que iban surgiendo. El
tiempo empleado para esta tarea ha sido un total de 67 horas.
96
Creador de un Mapa de Cobertura
 Desarrollo
Esta es la parte que requiere mayor inversión temporal puesto que
engloba toda la fase de diseño e implementación tanto de la aplicación
Symbian como de la aplicación Web. El tiempo empleado ha sido de
160 horas.
 Pruebas
Este grupo de tareas está íntimamente relacionado con el desarrollo, ya
que tras la implementación o modificación de cualquier aplicación
Symbian es necesario realizar una prueba en el dispositivo móvil para
comprobar que su resultado es el esperado. También se engloba aquí el
tiempo empleado en probar la aplicación Symbian una vez finalizada su
implementación y comprobar su resultado a través de la aplicación Web.
El tiempo empleado en esta fase del proyecto ha sido de 23 horas.
 Documentación
Aquí incluyo todo el tiempo empleado en realizar la documentación del
proyecto, empleando un total de 86 horas.
En el siguiente gráfico se pueden observar los porcentajes que emplean
cada una de las tareas principales sobre el tiempo total del proyecto.
7%
20%
47%
Investigación
Documentación
Desarrollo
Pruebas
26%
97
Creador de un Mapa de Cobertura
Capítulo 10:
Conclusiones
Una de las cosas que tenía bastante claras antes de elegir el proyecto fin
de carrera es que debería estar basado en una idea que realmente me gustase, ya
que la tarea de implementar una aplicación que no despierte demasiado interés
en el desarrollador puede llegar a ser muy tediosa. Otro de los factores que
influyó en mi decisión fue el lenguaje de programación. Como ya he comentado
en algún apartado anterior, Java y C++ eran las dos alternativas que manejaba a
la hora de elegir el lenguaje de programación en el que implementar la
aplicación del proyecto fin de carrera. La idea de implementar una aplicación
en Symbian C++ para dispositivos móviles que estuviera relacionada con
GoogleMap, y el hecho de disponer de un dispositivo móvil adecuado para
realizar las pruebas, fueron las causas que hicieron que me decantara finalmente
por este proyecto fin de carrera.
A través de la realización de este proyecto fin de carrera he conseguido
enfrentarme por primera vez al desarrollo de una aplicación por completo
desde sus inicios, tanto en la parte relacionada con Symbian OS, que era un
sistema y lenguaje totalmente desconocido para mí, como en la parte
98
Creador de un Mapa de Cobertura
relacionada con la aportación Web ya que aunque no era desconocida nunca
antes había desarrollado una aplicación Web relacionada con GoogleMap de
similares características a la de este proyecto fin de carrera.
Al ser la primera vez que implementaba un proyecto de esta magnitud
partiendo de cero he podido comprobar las dificultades con las que tienen que
enfrentarse los desarrolladores. Este hecho hace valorar de otra forma cualquier
aplicación que normalmente podemos considerar que no es muy buena,
apreciando realmente todo el trabajo que hay detrás.
Este proyecto tenía como objetivo inicial realizar una aplicación que
funcionase sobre la mayoría de los dispositivos móviles y que mediante acceso
a un GPS interno, externo o de modo manual almacenase los índices de
cobertura GSM, GPRS, y WIFI en un servidor y generase un mapa de estos.
Creo que es importante destacar la total consecución de este objetivo inicial sin
tener que variar o eliminar algún detalle de la idea inicial y realizando la
aplicación en Symbian OS de forma y manera que podamos añadir nuevas
funcionalidades sin ningún tipo de problema.
Otro aspecto a tener en cuenta de este proyecto es el desarrollo de una
aplicación en una plataforma como es Symbian OS, que aunque se basa en
C++, es un lenguaje de programación muy poco utilizado en nuestra escuela.
99
Creador de un Mapa de Cobertura
Capítulo 11:
Bibliografía
En este apartado quiero exponer toda la documentación que he utilizado
para poder desarrollar por completo este proyecto. Destacar que toda la
bibliografía utilizada ha sido información electrónica, es decir, a través de
internet.
Para llevar a cabo la aplicación en Symbian OS y resolver cualquier tipo
de duda he recurrido a los siguientes enlaces:
1.- Documentación existente en la SDK s60 3erd edition FP1
correspondiente a la versión 9.2 de Symbian OS. En esta documentación se
encuentran toda la API de dicha versión de Symbian OS e infinidad de
artículos, respuestas a dudas frecuentes, ejemplos de código, etc…
2.- http://www.forum.nokia.com. Esta es la página oficial en la que
Nokia pone a disposición de los desarrolladores cualquier tipo de información y
herramientas necesarias de manera totalmente gratuita para implementar
cualquier tipo de aplicación relacionada con los dispositivos móviles. Gracias a
100
Creador de un Mapa de Cobertura
este enlace he podido encontrar documentación acerca de numerosos aspectos
relacionados con Symbian OS. También he podido compartir y exponer todas
las dudas que me iban surgiendo a lo largo del desarrollo de este proyecto
mediante sus foros. Por último este enlace también me ha permitido acceder a
una sección denominada “Wiki” en la que hay multitud de ejemplos sobre
código ya implementado.
3.- http://developer.symbian.com. Esta es una de las páginas oficiales de
Symbian OS. A través de este enlace he podido encontrar todo tipo de
documentación, artículos y tutoriales relacionados con la programación en este
lenguaje. También me ha sido de utilidad para postear todas mis dudas
utilizando sus foros y para encontrar una gran cantidad de códigos de ejemplo.
4.- http://www.newlc.com. Gracias a este enlace, a través de sus foros,
he podido encontrar información relacionada con los problemas que iba
obteniendo a lo largo del desarrollo de la aplicación en Symbian OS.
A la hora de realizar el apartado de la memoria correspondiente al
funcionamiento general de las redes GSM, GPRS y WIFI he recurrido al
siguiente enlace:
- http://es.wikipedia.org.
Para poder llevar a cabo la parte de este proyecto relacionada con el
acceso a la base de datos, inserción de datos en la tabla y recorrido de dichos
datos, he tenido que implementar una serie de funciones utilizando PHP como
lenguaje de programación. Estos enlaces me han servido de utilidad:
1.- http://www.webtaller.com.
2.- http://www.forosdelweb.com.
Todo lo relacionado con GoogleMap y JavaScript, es decir, mapa,
controles, marcadores y ventanas de información ha sido implementado
utilizando la API de GoogleMap, a la cual podemos acceder a través de este
enlace:
http://code.google.com/intl/es/apis/maps/documentacion/reference.html.
101
Creador de un Mapa de Cobertura
En cuanto a las páginas Web, para el uso de capas de posicionamiento y
hojas de estilo de utilizado los siguientes manuales:
1.- http://www.librosweb.es/xhtml.
2.- http://www.librosweb.es/css.
102
Descargar