Centinela Bluetooth para Windows Mobile, jugando con RegistryState

Se acabó el darte cuenta al llegar al trabajo que dejaste la mochila con el portátil en casa… y es que cansado ya de salir corriendo de casa y darme cuenta «demasiado tarde» de que no llevo el portátil encima se me ocurrió inspirado en la nueva idea de Nokia (bueno no tan nueva todos conocemos los busca llaves) que están desarrollando un sistema para localizar objetos con el móvil, el desarrollar algo similar para Windows Mobile y claro, sin tener que gastarme ni un euro que esta la cosa muy mal para hacer derroches.

image

 

El objetivo ha sido crear una aplicación capaz de avisarme en la PDA si me separo de mi manos libres Bluetooth, además el aviso debe saltar aunque la aplicación NO este corriendo en ese momento y aunque la PDA NO esté encendida… Con lo que dejando el manos libres en la mochila si me alejo saltara la alarma.

image

 

Así que manos a la obra, para hacerlo tan solo he necesitado en lo que a hardware se refiere mi PDA HTC P3300 con Windows Mobile 5.0 y el manos libres Bluetooth, para todo lo demás RegistryState de Microsoft.WindowsMobile.Status y algunas llamadas a Pinvoke.

Mediante RegistryState podemos detectar cuando se produce algún cambio en cualquier clave del registro de nuestro dispositivo, y además nos genera el evento correspondiente y nos provee de los métodos necesarios para recuperar los valores que deseemos, basándonos en esto, la clave del registro HKEY_LOCAL_MACHINESystemStateHardwareBluetooth se actualiza con los cambios de estado del Bluetooth de nuestro dispositivo por lo que empezaremos por ahí.

image

En nuestra aplicación para poder capturar dichos cambios tan solo necesitamos crear lo siguiente:

//Como detectar los cambios producidos en el registro

(…)

    const string registryKey = @»HKEY_LOCAL_MACHINESystemStateHardware»;
    const string registryValueName = @»Bluetooth»;

    Microsoft.WindowsMobile.Status.RegistryState rg;    
    rg = new RegistryState(registryKey, registryValueName);                       
    rg.Changed += new ChangeEventHandler(rg_Changed); 
(…)

void rg_Changed(object sender, ChangeEventArgs args)
{  

}

De este modo cada vez que se produzca un cambio en esta clave (Activemos o desactivemos el Bluetooth, conectemos o desconectemos un dispositivo) se ejecutara en nuestro caso la función rg_Changed.

Así que con esto ya tenemos la primera parte resuelta, en caso de tener la PDA emparejada con el manos libres, si nos dejamos el manos libres en la mochila y nos alejamos se perderá la conexión y se producirá un cambio en el estado ejecutándose el método rg_Changed, y ahí podemos poner que vibre la PDA o que suene la flauta si hace falta, pero que ocurre si nuestra aplicación NO se está ejecutando en ese momento… pues obviamente que no funcionara, pero también lo podemos resolver con cuatro líneas de código gracias al método EnableApplicationLauncher que nos permite asociar una aplicación a un evento del sistema. Es decir que si ocurre un cambio, como puede ser el del estado del Bluetooth, que ejecute la aplicación que especificaremos por código.

Para ello agregaremos

//Como hacer que se ejecute una aplicación al detectar un cambio en el estado del dispositivo

const string appId = «DetectorBT»;
const string applicationFileName = @»Archivos de programaDetectorBTDetectorBT.exe»;
rg.EnableApplicationLauncher(appId, applicationFileName);

Así aun cuando cerremos la aplicación si nuestra PDA está encendida si se ejecuta cualquier cambio en la clave Bluetooth nuestra aplicación se ejecutara y ya tenemos otro punto solucionado… pero ahora viene «lo gordo», está claro que si nos acordamos de encender la PDA para ver que no se nos olvida nada nos acordaremos del portatil y esta claro que a las 7 de la mañana no te vas a acordar de encender la PDA por lo que debemos implementar «algo» que active la PDA para que veamos el aviso.

El como encender la pda lo podemos resolver con dos llamadas a nativo PowerPolicyNotify y SetSystemPowerState como se muestra a continuación

//Como encender la PDA mediante código

[DllImport(«coredll.dll», CharSet = CharSet.Unicode)]
private static extern bool PowerPolicyNotify(int dwMessage, int dwData);

[DllImport(«coredll.dll», SetLastError = true)]
static extern int SetSystemPowerState(string psState, int StateFlags, int Options);

/// <summary>
/// Despierta el dispositivo
/// </summary>
public void WakeUpPDA()
{
    PowerPolicyNotify((int)PPN_Message.PPN_UNATTENDEDMODE, 1);
    int iReturnResult = SetSystemPowerState(null, (int)PowerState.POWER_STATE_ON, (int)PowerRequirement.POWER_FORCE);
}

Así que de este modo si llamamos a WakeUpPDA cuando por ejemplo perdamos el control del manos libres y el estado vuelva a encendido y en espera (valor 9) despertamos la PDA y veremos el aviso que hayamos creado.

Con todo esto os dejo la aplicación de ejemplo Centinela Bluetooth para que alguno se anime a mejorarla, está claro que lo genial sería que fuese capaz de calcular la distancia a la que se encuentra pero en 2 horas no me ha dado tiempo a mucho mas.

Una de las opciones que estaba barajando era la de intentar estimar a que distancia se encuentra el dispositivo pero dadas las características del protocolo bluetooth y del tipo de dispositivo que estoy utilizando (uno de tipo 3 con alcance hasta 100 metros) no ha sido posible.

Todo esto está desarrollado para Windows Mobile 5.0 de ahí que utilice RegistryState en lugar de SystemSate para poder utilizar esta aplicación como ejemplo.

Saludos!!!

José Antonio Gallego

Ups, casi se me olvida aquí os dejo la solución con el ejemplo para Visual Studio 2008 y Windows Mobile 5.0 (MobileNUG.DetectorBT);

7 comentarios sobre “Centinela Bluetooth para Windows Mobile, jugando con RegistryState”

  1. Hola Jose Antonio, me llamo Eulalio. Soy de Jaén y tengo un problemilla con mi spv m600. El tema está en que se desconecta el bluetooth solo y no hay medios de activarlo de nuevo, tengo que reiniciarla o apargarla y encenderla de nuevo, y a veces… ni eso. He estado ojeando tu blog y como he visto que quizás cambiando algo del registro pudiese ser que estuviese siempre activado, en fin no se si me podrás ayudar. si puedes… envíame un correo a «natuver@natuver.com». Muchas gracias por adelantado. Un saludo.

  2. José esta muy bacano tu blog, por fa quisiera saber como funcionaria tu software pero NO con el manos libres , si no con otro celular, mi correo es helverdd@yahoo.com.

    Muchas gracias por tu colaboración y esta muy interesante tu pagina.
    Helver- (Colombia)

  3. Jose Antonio, muy práctica tu aplicaciòn, felicidades, quisiera saber si es posible utilizar la funcionalidad del registro para detectar dispositivos que quieran ingresar a mi equipo (hackear). Como puedo implementarlo? Mi correo es josedc01@gmail.com

Responder a anonymous Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *