ANEXO A - Universidad de Sevilla

Anuncio
Anexo A: Código Fuente
José Ramón Fernández Acosta
ANEXO A: CÓDIGO FUENTE
A.1 Aplicación para la captura de muestras
A.1.1 Código para Captura de muestras
import
import
import
import
import
org.placelab.core.BeaconMeasurement;
org.placelab.core.WiFiReading;
org.placelab.spotter.Spotter;
org.placelab.spotter.SpotterException;
org.placelab.spotter.WiFiSpotter;
import java.io.*;
import java.util.Timer;
import java.util.TimerTask;
/**
* A sample that creates a WiFiSpotter and uses it to get measurements.
* This will only return readings if a WiFi card is present.
*/
public class WiFiSpotterExample {
int nrep = 0;
static int interval = 200;
String log ;
static Spotter s = new WiFiSpotter(interval);
PrintWriter write = null;
public WiFiSpotterExample (String name, int num, int inter) {
try{
log = name;
interval = inter;
File fichero = new File("C:/tmp/" + log);
FileWriter fichwrite = new FileWriter(fichero);
BufferedWriter datos = new BufferedWriter(fichwrite);
write = new PrintWriter(datos);
s.open();
Timer timer = new Timer();
timer.scheduleAtFixedRate (timerTask, 0, interval);
while (nrep< num);
timer.cancel();
write.close();
} catch (SpotterException ex) {
ex.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
// Pad out a string to the passed length
public static String pad(String str, int len) {
StringBuffer sb = new StringBuffer(str);
for (int i=str.length(); i < len; i++) {
sb.append(" ");
}
return sb.toString();
}
86
Sistema de Localización en Interiores Basado en Redes WiFi
Universidad de Sevilla
TimerTask timerTask = new TimerTask(){
public void run(){
try{
BeaconMeasurement m = (BeaconMeasurement) s.getMeasurement();
write.println(m.numberOfReadings() + " APs were seen");
if (m.numberOfReadings() > 0) {
write.println(pad("MAC Address", 20) + pad("SSID", 30)
+ pad("RSSI", 10));
// Iterate through the Vector and print the readings
for (int i = 0; i < m.numberOfReadings(); i++) {
WiFiReading r = (WiFiReading) m.getReading(i);
write.println(pad(r.getId(), 20)
+ pad(r.getSsid(), 30) + pad("" + r.getRssi(), 10));
}
write.println();
}
nrep++;
} catch (SpotterException ex) {
ex.printStackTrace();
}
}
};
}
A.1.2 Interfaz de la aplicación de captura de muestras
import java.awt.*;
// Clase que nos permite introducir un nombre de fichero, un numero de
// medidas y un intervalo de medidas para hacer las mediciones de RSSI.
public class Medidor extends Frame {
static String fichero = new String ("0");
static int valorX = 0;
static int valorZ = 0;
TextField dTexto,xTexto,zTexto;
public Medidor() {
super( "Medidor RSSI" );
// Creamos la barra de menú, los botones de las bases y los
// paneles que vamos a utilizar para posicionar los
// Componentes
MenuBar menub = new MenuBar();
Button Bin = new Button( "Tomar medidas" );
Panel p1 = new Panel();
Panel p2 = new Panel();
Panel p3 = new Panel();
Panel p4 = new Panel();
// Creamos el menú desplegable
Menu menu = new Menu( "Aplicación" );
menu.add( new MenuItem( "Salir" ) );
menub.add( menu );
setMenuBar( menub );
// Incorporamos los botones a uno de los paneles
p3.setLayout( new FlowLayout() );
p3.add( Bin );
// Creamos los dos campos de texto que vamos a utilizar, uno
// para la introducción del número decimal que queremos
// convertir y el otro para presentar el número convertido
// Y asociamos cada uno de los campos, junto con su etiqueta
// explicativa a uno de los paneles
Label dEtiq = new Label( " Nombre del fichero:" );
Label xEtiq = new Label( "Número de medidas:" );
Label zEtiq = new Label("Intervalo de medidas:");
87
Anexo A: Código Fuente
José Ramón Fernández Acosta
dTexto = new TextField( fichero,7 ); // 7 caracteres como máximo
xTexto = new TextField( Integer.toString( valorX ),7 );
zTexto = new TextField( Integer.toString( valorZ ),7);
p1.setLayout( new FlowLayout( FlowLayout.LEFT ) );
p2.setLayout( new FlowLayout( FlowLayout.LEFT ) );
p4.setLayout( new FlowLayout( FlowLayout.LEFT ) );
p1.add( dEtiq );
p1.add( dTexto );
p2.add( xEtiq );
p2.add( xTexto );
p4.add( zEtiq );
p4.add( zTexto );
// Incorporamos los paneles a la ventana
add( "First",p1 );
add( "Center",p2 );
add( "South",p3 );
add( "After",p4 );
}
// Fija el tamaño de la ventana y la presenta en pantalla
public void start() {
resize( 400,200 );
show();
}
// Controlador de eventos, que hace caso solamente al evento de
// destrucción de la ventana y a los eventos de los botones.
// Efectúa operación de conversión que corresponde al botón que se
// pulsa y llama al método que hace aparecer el nuevo valor en
// el campo de texto del valor convertido
public boolean handleEvent( Event evt ) {
if( evt.target instanceof MenuItem )
{
if( "Salir".equals( ( (MenuItem)evt.target).getLabel() ) )
{
hide();
dispose();
System.exit( 0 );
return false;
}
return( true );
}
else if( evt.target instanceof Button && evt.id == 1001)
{
String boton = ( (Button)evt.target).getLabel();
// Tomar medidas
if( boton.equals( "Tomar medidas" ) )
{
fichero = dTexto.getText();
valorX = Integer.parseInt( xTexto.getText() );
valorZ = Integer.parseInt( zTexto.getText() );
actualizaSpotter();
}
return( true );
}
return false;
}
public void actualizaSpotter() {
new WiFiSpotterExample(fichero, valorX, valorZ);
}
88
Sistema de Localización en Interiores Basado en Redes WiFi
Universidad de Sevilla
public static void main( String args[] ) {
Medidor c = new Medidor();
c.start();
}
}
//--------------------------------------- Final del fichero Convertidor.java
89
Anexo A: Código Fuente
José Ramón Fernández Acosta
A.2 Cliente de localización
A.2.1 Código cliente de localización
import
import
import
import
import
import
import
org.placelab.core.BeaconMeasurement;
org.placelab.core.WiFiReading;
org.placelab.spotter.Spotter;
org.placelab.spotter.SpotterException;
org.placelab.spotter.WiFiSpotter;
java.util.Timer;
java.util.TimerTask;
public class WiFiSpotterCliente {
int nrep = 0;
private int interval = 200;
private Spotter s = new WiFiSpotter(interval);
boolean terminado = false;
int rssi[];
int auxrssi[]=new int[20];
String mac[] = {"00:0a:52:7a:79:c1", "00:0b:85:80:af:98",
"00:0b:85:80:af:9d", "00:0b:85:80:af:9e", "00:0b:85:80:b4:08",
"00:0b:85:80:b4:0d", "00:0b:85:80:b4:0f", "00:0b:85:80:bc:58",
"00:0b:85:80:bc:5e", "00:0b:85:80:bc:5f", "00:0b:85:80:bd:0e",
"00:0b:85:80:bd:0f", "00:0b:85:81:6f:78", "00:0b:85:81:6f:7e",
"00:0b:85:81:6f:7f", "00:0b:85:81:7b:68", "00:0b:85:81:7b:6e",
"00:0b:85:81:7b:6f", "00:13:f7:7a:44:47", "00:1f:9d:21:fe:b0"};
public WiFiSpotterCliente (int vector[], int num, int inter) {
try{
rssi= vector;
interval = inter;
s.open();
Timer timer = new Timer();
timer.scheduleAtFixedRate (timerTask, 0, interval);
while (nrep< num);
timer.cancel();
terminado = true;
} catch (SpotterException ex) {
ex.printStackTrace();
}
}
//Timer que muestrea las medidas de señal wifi cada intervalo de tiempo
//y durante el numero de muestras que se quiere medir
TimerTask timerTask = new TimerTask(){
public void run(){
try{
BeaconMeasurement m = (BeaconMeasurement) s.getMeasurement();
if (m.numberOfReadings() > 0) {
// Itera a través del vector y muestra las medidas
for (int i = 0; i < m.numberOfReadings(); i++) {
WiFiReading r = (WiFiReading) m.getReading(i);
rellena_vector_rssi(auxrssi, mac, r.getRssi(),
r.getId());
}
media_vector(rssi, auxrssi);
}
nrep++;
} catch (SpotterException ex) {
ex.printStackTrace();
}
}
};
90
Sistema de Localización en Interiores Basado en Redes WiFi
Universidad de Sevilla
private void rellena_vector_rssi(int vectorssi[], String vectormac[],
int rssi, String mac){
for (int i=0; i< vectormac.length; i++){
if(vectormac[i].equals(mac)){
vectorssi[i]=rssi;
i= vectormac.length;
}
}
}
//Halla la media del vector rssi del numero de muestras medido
private void media_vector(int vector1[], int vector2[]){
int n;
for(int i=0; i<vector1.length; i++){
if(vector1[i]!=0 && vector2[i]!=0){
n=2;
}
else{
n=1;
}
vector1[i]=(vector1[i]+vector2[i])/n;
}
}
//funcion que indica que el proceso de recogida de muestras ha terminado
public boolean finconex(){
return terminado;
}
}
91
Anexo A: Código Fuente
José Ramón Fernández Acosta
A.2.1 Código interfaz cliente
// Configurar un cliente que reciba una petición del servidor, envíe
// una cadena al servidor y cierre la conexión
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Cliente extends JFrame {
private
private
private
private
private
private
private
JTextField campoIntroducir;
JTextArea areaPantalla;
ObjectOutputStream salida;
ObjectInputStream entrada;
ServerSocket cliente;
Socket conexion;
int contador = 1;
WiFiSpotterCliente cliente;
int ejemplo[]= new int[20];
// configurar GUI
public Cliente()
{
super( "Cliente" );
Container contenedor = getContentPane();
// crear campoIntroducir y registrar componente de escucha
campoIntroducir = new JTextField();
campoIntroducir.setEditable( false );
campoIntroducir.addActionListener(
new ActionListener() {
// enviar mensaje al cliente
public void actionPerformed( ActionEvent evento )
{
enviarDatos( evento.getActionCommand() );
campoIntroducir.setText( "" );
}
}
);
contenedor.add( campoIntroducir, BorderLayout.NORTH );
// crear areaPantalla
areaPantalla = new JTextArea();
contenedor.add( new JScrollPane( areaPantalla ),
BorderLayout.CENTER );
setSize( 300, 150 );
setVisible( true );
} // fin del constructor de Cliente
92
Sistema de Localización en Interiores Basado en Redes WiFi
Universidad de Sevilla
// configurar y ejecutar el cliente
public void ejecutarCliente()
{
// configurar cliente para que reciba conexiones; procesar las conexiones
try {
// Paso 1: crear un objeto ServerSocket.
cliente = new ServerSocket( 12345, 100 );
while ( true ) {
try {
esperarConexion();// Paso 2: esperar una conexión
obtenerFlujos();// Paso 3: obtener flujos de entrada y salida.
procesarConexion(); // Paso 4: procesar la conexión.
}
// procesar excepción EOFException cuando el servidor cierre la conexión
catch ( EOFException excepcionEOF ) {
System.err.println( "El servidor terminó conexión" );
}
finally {
cerrarConexion();
++contador;
}
// Paso 5: cerrar la conexión
} // fin de instrucción while
} // fin del bloque try
// procesar problemas con E/S
catch ( IOException excepcionES ) {
excepcionES.printStackTrace();
}
} // fin del método ejecutarCliente
// esperar que la conexión llegue, después mostrar información de la conexión
private void esperarConexion() throws IOException
{
mostrarMensaje( "Esperando una conexión\n" );
conexion = cliente.accept(); // permitir al cliente aceptar la conexión
mostrarMensaje( "Conexión " + contador + " recibida de: " +
conexion.getInetAddress().getHostName() );
}
// obtener flujos para enviar y recibir datos
private void obtenerFlujos() throws IOException
{
// establecer flujo de salida para los objetos
salida = new ObjectOutputStream( conexion.getOutputStream() );
salida.flush(); // vaciar buffer de salida para enviar información de
encabezado
// establecer flujo de entrada para los objetos
entrada = new ObjectInputStream( conexion.getInputStream() );
mostrarMensaje( "\nSe recibieron los flujos de E/S\n" );
}
93
Anexo A: Código Fuente
José Ramón Fernández Acosta
// procesar la conexión con el servidor mediante el protocolo de comunicación
correspondiente
private void procesarConexion() throws IOException
{
String mensaje;
try {
mensaje = ( String ) entrada.readObject();
if (!mensaje.equals("CLIENTE>>> LOCALIZACION")){
cerrarConexion();
++contador;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// enviar mensaje de conexión exitosa al cliente
mensaje = "Conexión exitosa";
enviarDatos( mensaje );
cliente = new WiFiSpotterCliente (ejemplo, 3, 500);
while(!cliente.finconex());
System.out.println("termino");
for(int i=0; i<20; i++){
enviarDatos( String.valueOf(ejemplo[i]) );
}
// habilitar campoIntroducir para que el usuario del servidor pueda
enviar mensajes
establecerCampoTextoEditable( true );
} // fin del método procesarConexion
// cerrar flujos y socket
private void cerrarConexion()
{
mostrarMensaje( "\nFinalizando la conexión\n" );
establecerCampoTextoEditable( false ); // deshabilitar campoIntroducir
try {
salida.close();
entrada.close();
conexion.close();
}
catch( IOException excepcionES ) {
excepcionES.printStackTrace();
}
}
// enviar mensaje al cliente
private void enviarDatos( String mensaje )
{
// enviar objeto al cliente
try {
salida.writeObject( mensaje );
salida.flush();
mostrarMensaje( "\n" + mensaje );
}
// procesar problemas que pueden ocurrir al enviar el objeto
catch ( IOException excepcionES ) {
areaPantalla.append( "\nError al escribir objeto" );
}
}
94
Sistema de Localización en Interiores Basado en Redes WiFi
Universidad de Sevilla
// método utilitario que es llamado desde otros subprocesos para manipular
// areaPantalla en el subproceso despachador de eventos
private void mostrarMensaje( final String mensajeAMostrar )
{
// mostrar mensaje del subproceso de ejecución despachador de eventos
SwingUtilities.invokeLater(
new Runnable() {
// clase interna para asegurar que la GUI se actualice apropiadamente
public void run() // actualiza areaPantalla
{
areaPantalla.append( mensajeAMostrar );
areaPantalla.setCaretPosition(
areaPantalla.getText().length() );
}
}
// fin de la clase interna
); // fin de la llamada a SwingUtilities.invokeLater
}
// método utilitario que es llamado desde otros subprocesos para manipular
// campoIntroducir en el subproceso despachador de eventos
private void establecerCampoTextoEditable( final boolean editable )
{
// mostrar mensaje del subproceso de ejecución despachador de eventos
SwingUtilities.invokeLater(
new Runnable() { // clase interna para asegurar que la GUI se
actualice apropiadamente
public void run() // establece la capacidad de modificar
campoIntroducir
{
campoIntroducir.setEditable( editable );
}
}
// fin de la clase interna
); // fin de la llamada a SwingUtilities.invokeLater
}
public static void main( String args[] )
{
Cliente aplicacion = new Cliente();
aplicacion.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
aplicacion.ejecutarCliente();
}
}
// fin de la clase Cliente
95
Anexo A: Código Fuente
José Ramón Fernández Acosta
A.3 Servidor de Localización
A.3.1 Código Servidor de localización
import
import
import
import
import
java.sql.Connection;
java.sql.DriverManager;
java.sql.ResultSet;
java.sql.SQLException;
java.sql.Statement;
class Localizacion {
static
static
static
static
static
String
String
String
String
int k=
driver = "org.postgresql.Driver";
connectString = "jdbc:postgresql://localhost:5432/postgres";
user = "postgres";
password = "postgres";
3;
//valor de k para el método de los k-vecinos
private Localizacion(int vector_rssi[]) {
int
int
int
int
i=0;
j=0;
AP=0, LOCS=0;
muestra[][];
int dist[]; //vector a rellenar
array muestra al vector_rssi
String distloc[];
float xloc[] = new float[k];
float yloc[] = new float[k];
float w = 0; //variable para el
float xfin=0; //valor final en x
float yfin=0; //valor final en y
con la distancia de cada vector del
peso asignado a los k-vecinos
del punto de localización
del punto de localización
try {
Class.forName(driver);
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
Connection con;
try {
con = DriverManager.getConnection(connectString, user ,
password);
Statement stmt =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
Statement stmt2 =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
Statement stmt3 =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT locname, apmac,
avg(rssi) FROM muestras " +
"group by locname, apmac order by locname, apmac");
ResultSet rs2= stmt2.executeQuery("SELECT DISTINCT ON
(locname) locname FROM muestras");
ResultSet rs3= stmt3.executeQuery("SELECT * FROM macpersan");
AP = numero_aps(rs3);
LOCS = localizaciones_posibles(rs2);
muestra = new int[LOCS][AP];
dist = new int[LOCS];
distloc = new String[LOCS];
96
Sistema de Localización en Interiores Basado en Redes WiFi
Universidad de Sevilla
while(rs.next()){
System.out.println(rs.getString("locname")+"
rs.getInt("avg"));
}
"+
rs.beforeFirst();
while(rs.next()){
rs2.beforeFirst();
i=0;
while(rs2.next()){
rs3.beforeFirst();
j=0;
while(rs3.next()){
if(rs.getString("apmac").equals(rs3.getString("apmac")) &&
rs.getString("locname").equals(rs2.getString("locname")) ){
System.out.println(rs.getString("locname")+"
"+ rs.getInt("avg") +" "+i+"
"+j);
muestra[i][j]=rs.getInt("avg");
}
j++;
}
i++;
}
}
rs2.beforeFirst();
i=0;
while(rs2.next()){
rs3.beforeFirst();
j=0;
while(rs3.next()){
System.out.print(muestra[i][j]+ "
j++;
}
i++;
System.out.println();
}
");
vector_de_distancia(rs2, rs3, dist, vector_rssi, muestra);
vector_de_localizaciones(rs2, distloc);
ordena_vectores( dist, distloc);
i=0;
rs2.beforeFirst();
while(rs2.next()){
System.out.print(dist[i]+ " ");
i++;
}
System.out.println();
i=0;
rs2.beforeFirst();
while(rs2.next()){
System.out.print(distloc[i]+ " ");
i++;
}
System.out.println();
rs = stmt.executeQuery("SELECT * FROM persanloc");
for(i=0; i<3; i++){
while(rs.next()){
if(rs.getString("locname").equals(distloc[i])){
xloc[i]=rs.getInt("xloc");
yloc[i]=rs.getInt("yloc");
}
97
Anexo A: Código Fuente
José Ramón Fernández Acosta
}
rs.beforeFirst();
System.out.println(xloc[i]+ " " + yloc[i]);
}
for(i=0; i<3; i++){
xloc[i]= xloc[i]/dist[i];
yloc[i]= yloc[i]/dist[i];
w += (float) 1/dist[i];
System.out.println(xloc[i] + " " + yloc[i] + " " + w);
}
for(i=0; i<3; i++){
xfin +=xloc[i]/w;
yfin +=yloc[i]/w;
}
System.out.println(xfin + " " + yfin);
stmt.close();
con.close();
locvision ventanita = new locvision(xfin, yfin);
} catch (SQLException e) {
e.printStackTrace();
}
}
//devuelve el número de puntos de acceso del sistema
private int numero_aps(ResultSet rs){
int i=0;
try {
while(rs.next()){
i++;
}
} catch (SQLException e) {
e.printStackTrace();
}
return i;
}
//devuelve el número de localizaciones posibles del sistema
private int localizaciones_posibles(ResultSet rs){
int i=0;
try {
while(rs.next()){
i++;
}
} catch (SQLException e) {
e.printStackTrace();
}
return i;
}
//rellena el vector con la id de cada una de las localizaciones
private void vector_de_localizaciones(ResultSet rs, String vector[]){
int i=0;
try {
rs.beforeFirst();
while(rs.next()){
vector[i] = rs.getString("locname");
i++;
98
Sistema de Localización en Interiores Basado en Redes WiFi
Universidad de Sevilla
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//ordena vectores de menor a mayor
private void ordena_vectores(int distancia[], String iddistancia[]){
int i=0;
int j=0;
int pos_min;
int tmp;
String stmp;
for(i=0; i < distancia.length-1 ; i++){
pos_min=i;
for(j=i+1; j < distancia.length; j++)
if(distancia[j]<distancia[pos_min])
pos_min=j;
tmp=distancia[i];
distancia[i]=distancia[pos_min];
distancia[pos_min]=tmp;
stmp=iddistancia[i];
iddistancia[i]=iddistancia[pos_min];
iddistancia[pos_min]=stmp;
}
}
//calcula el vector de distancias
private void vector_de_distancia(ResultSet rs, ResultSet rs1,
int vector[], int vector1[], int vector2[][]){
int i=0,j=0;
try {
rs.beforeFirst();
while(rs.next()){
j=0;
rs1.beforeFirst();
while(rs1.next()){
vector[i] += (vector1[j] - vector2[i][j]) * (vector1[j] vector2[i][j]);
j++;
}
System.out.print(vector[i]+ " ");
i++;
}
System.out.println();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void main(String args[]){
int Nap=0;
int rssi[];
//Esta parte del código es para obtener el número de puntos de acceso
//en el sistema para el main del programa.
try {
Class.forName(driver);
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
99
Anexo A: Código Fuente
José Ramón Fernández Acosta
Connection con;
try {
con = DriverManager.getConnection(connectString, user , password);
Statement stmt =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs= stmt.executeQuery("SELECT * FROM macpersan");
while(rs.next()){
Nap++;
}
stmt.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
rssi= new int[Nap];
Servidor aplicacion;
Localizacion algoritmo;
aplicacion = new Servidor(Nap);
while(!aplicacion.finconex())
aplicacion.rellenavector(rssi);
algoritmo = new Localizacion(rssi);
}
}
100
Sistema de Localización en Interiores Basado en Redes WiFi
Universidad de Sevilla
A.3.2 Código del servidor
import
import
import
import
import
java.io.*;
java.net.*;
java.awt.*;
java.awt.event.*;
javax.swing.*;
public class Servidor extends JFrame {
private JTextField campoIntroducir;
private JTextArea areaPantalla;
private ObjectOutputStream salida;
private ObjectInputStream entrada;
private String mensaje = "";
private String servidor;
private Socket servidor;
private JButton conectar;
boolean terminado = false;
int ejemplo[];
int N;
public Servidor( /*host*/ int n)
{
super( "Servidor" );
N=n;
ejemplo= new int[N];
Container contenedor = getContentPane();
// crear campoIntroducir y registrar componente de escucha
campoIntroducir = new JTextField();
campoIntroducir.setEditable( true );
campoIntroducir.addActionListener(
new ActionListener() {
// enviar mensaje al servidor
public void actionPerformed( ActionEvent evento )
{
enviarDatos( evento.getActionCommand() );
campoIntroducir.setText( "" );
}
}
);
contenedor.add( campoIntroducir, BorderLayout.NORTH );
// crear areaPantalla
areaPantalla = new JTextArea();
contenedor.add( new JScrollPane( areaPantalla ),
BorderLayout.CENTER );
conectar = new JButton("Conectar");
conectar.addActionListener(
new ActionListener() {
public void actionPerformed( ActionEvent evento )
{
servidor = campoIntroducir.getText();
System.out.println(servidor);
ejecutarServidor();
}
}
);
contenedor.add( conectar, BorderLayout.EAST);
setSize( 300, 150 );
setVisible( true );
} // fin del constructor de Servidor
101
Anexo A: Código Fuente
José Ramón Fernández Acosta
// conectarse al servidor y procesar mensajes del servidor
private void ejecutarServidor()
{
// conectarse al servidor, obtener flujos, procesar la conexión
try {
conectarAServidor(); // Paso 1: crear un socket para la conexión
obtenerFlujos(); // Paso 2: obtener los flujos de entrada y salida
procesarConexion(); // Paso 3: procesar la conexión
terminado=true;
procesar una conexión
}
//es un semáforo para indicar que se acaba de
// el cliente cerró la conexión
catch ( EOFException excepcionEOF ) {
System.err.println( "El cliente termino la conexión");
}
// procesar los problemas que pueden ocurrir al comunicarse con el
servidor
catch ( IOException excepcionES ) {
excepcionES.printStackTrace();
}
finally {
//cerrarConexion(); // Paso 4: cerrar la conexión
}
} // fin del método ejecutarServidor
// conectarse al servidor
private void conectarAServidor() throws IOException
{
establecerCampoTextoEditable( true );
mostrarMensaje( "Intentando realizar conexión\n" );
// crear Socket para realizar la conexión con el servidor
servidor = new Socket( InetAddress.getByName( servidor ), 12345 );
// mostrar la información de la conexión
mostrarMensaje( "Conectado a: " +
servidor.getInetAddress().getHostName() );
}
// obtener flujos para enviar y recibir datos
private void obtenerFlujos() throws IOException
{
// establecer flujo de salida para los objetos
salida = new ObjectOutputStream( servidor.getOutputStream() );
salida.flush(); // vaciar buffer de salida para enviar información de
encabezado
// establecer flujo de entrada para los objetos
entrada = new ObjectInputStream( servidor.getInputStream() );
mostrarMensaje( "\nSe recibieron los flujos de E/S\n" );
}
102
Sistema de Localización en Interiores Basado en Redes WiFi
Universidad de Sevilla
// procesar la conexión con el servidor
private void procesarConexion() throws IOException
{
int i=0;
// habilitar campoIntroducir para que el usuario del servidor pueda
enviar mensajes
establecerCampoTextoEditable( true );
enviarDatos( "LOCALIZACION" );
do { // procesar mensajes enviados del servidor
// leer mensaje y mostrarlo en pantalla
try {
mensaje = ( String ) entrada.readObject();
if(!mensaje.equals("Conexión exitosa")){
ejemplo[i]=Integer.parseInt(mensaje);
//System.out.println(ejemplo[i]);
i++;
}
mostrarMensaje( "\n" + mensaje );
}
// atrapar los problemas que pueden ocurrir al leer del servidor
catch ( ClassNotFoundException excepcionClaseNoEncontrada ) {
mostrarMensaje( "\nSe recibió un objeto de tipo desconocido" );
}
} while ( i<N );
} // fin del método procesarConexion
// cerrar flujos y socket
private void cerrarConexion()
{
mostrarMensaje( "\nCerrando conexión" );
establecerCampoTextoEditable( false ); // deshabilitar campoIntroducir
try {
salida.close();
entrada.close();
servidor.close();
}
catch( IOException excepcionES ) {
excepcionES.printStackTrace();
}
}
// enviar mensaje al servidor
private void enviarDatos( String mensaje )
{
// enviar objeto al servidor
try {
salida.writeObject( "CLIENTE>>> " + mensaje );
salida.flush();
mostrarMensaje( "\nCLIENTE>>> " + mensaje );
}
// procesar los problemas que pueden ocurrir al enviar el objeto
catch ( IOException excepcionES ) {
areaPantalla.append( "\nError al escribir el objeto" );
}
}
103
Anexo A: Código Fuente
José Ramón Fernández Acosta
// método utilitario que es llamado desde otros subprocesos para manipular
// areaPantalla en el subproceso despachador de eventos
private void mostrarMensaje( final String mensajeAMostrar )
{
// mostrar mensaje del subproceso de ejecución de la GUI
SwingUtilities.invokeLater(
new Runnable() { // clase interna para asegurar que la GUI se
actualice apropiadamente
public void run() // actualiza areaPantalla
{
areaPantalla.append( mensajeAMostrar );
areaPantalla.setCaretPosition(
areaPantalla.getText().length() );
}
}
// fin de la clase interna
); // fin de la llamada a SwingUtilities.invokeLater
}
// método utilitario que es llamado desde otros subprocesos para manipular
// campoIntroducir en el subproceso despachador de eventos
private void establecerCampoTextoEditable( final boolean editable )
{
// mostrar mensaje del subproceso de ejecución de la GUI
SwingUtilities.invokeLater(
new Runnable() { // clase interna para asegurar que la GUI se
actualice apropiadamente
public void run() // establece la capacidad de modificar
campoIntroducir
{
campoIntroducir.setEditable( editable );
}
}
// fin de la clase interna
); // fin de la llamada a SwingUtilities.invokeLater
}
//rellena un vector que se le pasa como referencia
public void rellenavector(int [] vectorssi)
{
for(int i=0;i<N;i++){
vectorssi [i]= ejemplo[i];
}
}
//devuelve el valor del semáforo definido antes, para saber si ha
terminado una conexión
public boolean finconex(){
return terminado;
}
} // fin de la clase Servidor
104
Sistema de Localización en Interiores Basado en Redes WiFi
Universidad de Sevilla
A.3.3 Código Representación de la localización
// Demostración de un mapa de imágenes.
import java.awt.*;
import javax.swing.*;
public class locvision extends JFrame {
private JLabel estado;
float xmap;
float ymap;
// establecer componentes de escucha del ratón
public locvision(float x, float y) {
estado = new JLabel();
MiPanel mipanel = new MiPanel();
getContentPane().add(mipanel);
getContentPane().add(estado, BorderLayout.SOUTH);
setSize(900,400);
setVisible(true);
xmap=x;
ymap=y;
} // fin del método init
private class MiPanel extends JPanel {
private ImageIcon imagenMapa;
public MiPanel() {
imagenMapa = new ImageIcon( "bin/oficinas.gif" ); //obtener la
imagen
}
// mostrar imagenMapa
public void paint( Graphics g ) {
super.paint( g );
imagenMapa.paintIcon( this, g, 0, 0 );
g.drawOval((int) xmap, (int) ymap, 5, 5 );
}
// devolver leyenda del tip correspondiente, con base en las
coordenadas del ratón
}
} // fin de la clase MapaImagenes
105
Anexo A: Código Fuente
José Ramón Fernández Acosta
A.4 Código aplicación cambio de formato de ficheros
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
struct nodo{
char mac[20];
char ssid[20];
int rssi;
struct nodo *sig;
};
typedef struct nodo NODO;
char c[50];
int i;
int n;
int ap=0;
int apaux=0;
int muest=0;
FILE *fp = NULL;
FILE *fout = NULL;
NODO *ptr = NULL;
NODO *ptraux = NULL;
NODO *ptraux2= NULL;
NODO *pmac = NULL;
fp = fopen(argv[1], "r");
fout = fopen(argv[2], "w+");
ptr = (NODO*) malloc ( 1000*sizeof(NODO) );
ptraux = ptr;
/*reservamos espacio para*/
/*1000 estructuras de nodo*/
if(argc != 3){
printf("a.exe archivo-ent archivo-sal\n");
exit(1);
}
/* En esta primera funcion realizamos la entrada de datos del archivo en */
/* el formato especificado a las listas creadas */
while ( (n=fscanf(fp, "%i", &ap)) != EOF )
{
fgets(c, 128, fp);
fgets(c, 128, fp);
while (apaux < ap)
{
fscanf(fp, "%s", c);
i=0;
while(c[i] != ' ')
{
ptraux->mac[i] = c[i];
i++;
}
fscanf(fp, "%s", c);
i=0;
while(c[i] != ' ')
{
ptraux->ssid[i] = c[i];
i++;
}
ptraux->rssi = atoi(c);
if(ptraux->rssi >=0 )
{
fscanf(fp, "%i", &i);
106
Sistema de Localización en Interiores Basado en Redes WiFi
Universidad de Sevilla
ptraux->rssi = i;
}
ptraux->sig = ptraux+1;
fgets(c, 128, fp);
apaux++;
ptraux++;
}
fgets(c, 128, fp);
apaux=0;
}
fclose(fp);
/*En esta segunda funcion vamos a ordenar las */
ptraux->sig = NULL;
/*listas en grupos referenciados por la mac*/
ptraux=ptr;
pmac=ptr;
while (pmac->sig != NULL)
{
while (ptraux->sig != NULL)
{
if ( (!strcmp( pmac->mac, ptraux->mac )) && (ptraux != pmac))
{
ptraux2->sig= ptraux->sig;
ptraux->sig=pmac->sig;
pmac->sig=ptraux;
pmac=pmac->sig;
}
ptraux2=ptraux;
ptraux=ptraux->sig;
}
pmac=pmac->sig;
ptraux=pmac;
}
fp = fopen(argv[2], "w+");
/*En esta tercera funcion imprimimos en el */
pmac=ptr;
/*fichero de salida las listas en el formato*/
ptraux=pmac;
/*de salida especificado*/
while(ptraux->sig != NULL)
{
i=0;
while( argv[1][i] != '.')
{
fprintf(fout, "%c", argv[1][i]);
i++;
}
fprintf(fout,
muest++;
fprintf(fout,
fprintf(fout,
fprintf(fout,
"\t");
"%i\t", muest);
"%s\t", ptraux->mac);
"%i\n", ptraux->rssi);
if ( strcmp( ptraux->mac, ptraux->sig->mac ) ){
muest=0;
}
ptraux = ptraux->sig;
}
fclose(fout);
free(ptr);
ptr=ptraux=ptraux2=pmac=NULL;
return 0;
}
107
Anexo A: Código Fuente
José Ramón Fernández Acosta
A.5 Script de automatización de creación de la base de datos
A.5.1 Código SQL de creación de tablas
DROP TABLE muestras;
DROP TABLE persanloc;
DROP TABLE macpersan;
-- Table: persanloc
CREATE TABLE persanloc
(
locname character varying(10) NOT NULL,
xloc integer NOT NULL,
yloc integer NOT NULL,
zloc integer,
sala character varying(20),
descripcion character varying(30),
CONSTRAINT persanloc_pkey PRIMARY KEY (locname)
);
-- Table: macpersan
CREATE TABLE macpersan
(
apname character varying(10) NOT NULL,
apmac character varying(20) NOT NULL,
apmac1 character varying(20) NOT NULL,
apmac2 character varying(20) NOT NULL,
apmac3 character varying(20) NOT NULL,
xloc integer,
yloc integer,
zloc integer,
CONSTRAINT macpersan_pkey PRIMARY KEY (apmac, apname),
CONSTRAINT macpersan_apmac_key UNIQUE (apmac),
CONSTRAINT macpersan_apmac_key1 UNIQUE (apmac)
);
-- Table: muestras
CREATE TABLE muestras
(
locname character varying(10) NOT NULL,
muestra integer NOT NULL,
apmac character varying(20) NOT NULL,
rssi integer NOT NULL,
CONSTRAINT muestras_pkey PRIMARY KEY (locname, apmac, muestra),
CONSTRAINT muestras_locname_fkey FOREIGN KEY (locname)
REFERENCES persanloc (locname) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);
copy persanloc from '/persan/persanloc.txt';
copy macpersan (apname, apmac, apmac1, apmac2, apmac3) from
'/persan/macpersan.txt';
copy muestras from '/persan/muestras.txt';
108
Sistema de Localización en Interiores Basado en Redes WiFi
Universidad de Sevilla
A.5.2 Código Batch para la automatización de la creación de la base de datos
@echo off
SET PATH=c:\CYGNUS\CYGWIN~1\H-I586~1\BIN;%PATH%
mkdir operaciones
cd operaciones
copy ..\*.txt
echo ********************************************
echo *** Adaptación del formato de ficheros ***
echo ********************************************
REM
REM
REM
REM
REM
****************************************************
bucle para pasar todos los archivos de muestras
al formato correcto mediante la llamada al programa
de adaptación de formato
****************************************************
for %%X in (*.txt) do ..\formato %%X %%X.sal
REM
REM
REM
REM
****************************************************
copia todos los archivos generados a un solo archivo
usando el parámetro /b
****************************************************
copy /b *.sal salida.txt
move salida.txt ..\muestras.txt
cd..
rmdir /s /q operaciones
echo
echo
echo
echo
REM
REM
REM
REM
REM
REM
********************************************
***
Creación de la base de datos
***
***
tablas y datos
***
********************************************
****************************************************
el siguiente comando tendremos que cambiarlo por la
ruta de la carpeta bin de postgresql o establecerla
como variable del sistema y borrar el siguiente
comando
****************************************************
set path=C:\Program Files\PostgreSQL\8.3\bin
set PGPASSWORD=postgres
psql -U postgres -c "CREATE DATABASE bd_muestras;"< creabd.sql
REM el siguiente comando evita que postgresql me pida la contraseña y
se pare el script
set PGPASSWORD=postgres
psql -U postgres -d bd_muestras < creabd.sql
pause
109
Descargar