[Compact Framework] Spegnere la scheda WiFi

Sull'onda delle "ricette" del mio omonimo, spendo anch'io "due byte" per qualche trucchismo sul Compact Framework (sul quale mi sono ritrovato
a lavorare anch'io).

Il problema che mi sono trovato davanti è stato quello di dover "capire" lo stato della connessione wifi (acceso, spento, idle) ed agire di conseguenza PRIMA dello startup dell'applicazione (o in caso di problemi di connessione).

Purtroppo, i modelli dei PocketPC che utilizzano l'applicazione, sono diversi e, a seconda di questi, il metodo (non presente nel CF.NET 1.1) per spegnere e riaccendere la scheda WiFi integrata è diverso.

Al fine di non incrementare lo "spaghetti code", ho iniziato con la produzione di una DLL separata che astraesse il compito da parte dell'applicazione principale: una Class-Factory ritorna un'istanza concreta del "wifiController"; tale classe espone un'interfaccia ben definita IWiFiController.

Tale interfaccia è 'si fatta:

public interface IWiFiController
{
    bool WiFiOff();
    bool WiFiOn();
    bool ToggleWiFi();        
    string DeviceModelName 
    {
        get;
        set;
    }

    WiFiStatus CurrentWiFiStatus 
    {
        get;
    }

}


I modelli di PocketPC attualmente utilizzati dall'applicazione sono: DELL Axim X51v, DELL Axim X30 e, new entry, iPAQ hx2490b .

Ahimè, per i primi due, l'implementazione dei metodi WifiOn e WiFiOff è stata alquanto "sporca" dato che, il produttore, NON ha reso pubblica NESSUNA API per compiere tale compito smile_confused.
Tale soluzione consiste "semplicemente" nel cercare la presenza di due eseguibili :

  • "\Windows\WirelessPower.exe" per l'Axim X30
  • \Windows\WirelessOnOff.exe per l'Axim X51v

tali eseguibili sono richiamati dal sistema operativo quando viene premuto il corrispondente pulsante (hardware) per disabilitare o abilitare la connessione WiFi.

Ciò che mi rammarrica è che, tali eseguibili, NON HANNO STATO ovvero spengono la WiFi se è accesa e la accendono se è spenta. NON ho MODO di controllare, quindi, lo stato attuale della connessione se NON Pingando il server dopo l'esecuzione del comando ed, eventualmente, rieseguendolo nella speranza che lo stato precedente fosse OFF.

Quei "furboni" della HP (ex Compaq), invece, espongono alcune API tramite la dll iPaqUtil.dll .

Al fine di spegnere e riaccendere la WiFi, quindi, è stato sufficiente fare una chiamata alle funzioni esposte.

La classe che è saltata fuori è la seguente:

 

public class iPaqWiFiController : IWiFiController
{
    [DllImport("iPAQUtil.dll")] 
    public static extern bool iPAQSetWLANRadio(ref int val); 

    [DllImport("iPAQUtil.dll")] 
    public static extern bool iPAQGetWLANRadioStatus(ref int val);
    
    private int ON;
    private int OFF;

    public iPaqWiFiController()
    {
        detectOnOffStates();
    }

    private void detectOnOffStates() 
    {
        if(Environment.OSVersion.Version.Minor==20) // power on and off ints are reversed since PPC 2003 SE 
        { 
            OFF = 1; 
            ON = 0; 
        } 
        else 
        { 
            OFF = 0; 
            ON = 1; 
        } 
    }

    #region IWiFiController Members

    public bool WiFiOff()
    {
        int power = OFF;
        bool result = true;
        try 
        {
            iPAQSetWLANRadio(ref power);            
        } 
        catch 
        {
            result = false;
        }

        return result;
    }

    public bool WiFiOn()
    {
        int power = ON;
        bool result = true;
        try 
        {
            iPAQSetWLANRadio(ref power);            
        } 
        catch 
        {
            result = false;
        }

        return result;
    }

    public bool ToggleWiFi()
    {            
        int power = 0; 
        iPAQGetWLANRadioStatus(ref power);
        if(power==OFF) 
        { 
            WiFiOn();
            Thread.Sleep(2000);
        } 
        else 
        {
            WiFiOff();
            Thread.Sleep(2000);
            WiFiOn();
            Thread.Sleep(2000);
        }

        return (CurrentWiFiStatus==WiFiStatus.On);
    }

    private string _deviceModelName = "iPaq";
    public string DeviceModelName 
    {
        get { return _deviceModelName; }
        set { _deviceModelName = value; }
    }

    public WiFiStatus CurrentWiFiStatus 
    {
        get 
        {
            int power = 0; 
            WiFiStatus status = WiFiStatus.Unknown;
            iPAQGetWLANRadioStatus(ref power);

            if(power==ON) 
            {
                status = WiFiStatus.On;
            }

            if (power==OFF) 
            {
                status = WiFiStatus.Off;
            }

            return status;
        }
    }

    #endregion

 

Da notare come, anche in questo caso, ci sono "gabole" legate allo stato ON e OFF (ovvero, al fatto che, da una certa versione in poi, il significato cambia).

Spero che questo articolo/post possa essere d'aiuto a qualcuno e che, qualcuno di buon cuore, mi dica come fare il detect dello stato della WiFi anche sui Dell (che, purtroppo, ha anche ufficializzato lo smantellamento della linea Axim).

posted @ Wednesday, April 11, 2007 6:20 PM

Print

Comments on this entry:

# re: [Compact Framework] Spegnere la scheda WiFi

Left by dave at 4/9/2008 9:48 PM
Gravatar
ciao, mi chiamo davide e sto sviluppando un'applicazione x wm con vs 2008, quindi basata su .net cf 3.5.
Ho letto il tuo articolo su come disabilitare la scheda wifi, che ho trovato molto interessante, ma soprattutto particolare quanto il problema che sto tentando di risolvere e che vengo a spiegarti nella speranza che tu possa saperne qualcosa.
La mia applicazione, deve effettuare una chiamata telefonica ad un numero tramite Microsoft.WindowsMobile.Telephony.Phone.
A questo punto, una volta inoltrata la chiamata, trascorrono sempre 4-5 sec prima che il segnale giunga al destinatario.
Ciò di cui ho bisogno, è conoscere esattamente il momento in cui il telefono destinatario riceve il segnale di chiamata (capisci che dire 4-5 secondi o anche di più, nel caso di scarso segnale, sia troppo approssimativo).
Purtroppo il .net cf, non mi fornisce nessuna proprietà tra quelle presenti nella classe SystemState, che mi ritorni un booleano o altro tipo, su quel particolare stato.
Esiste solo SystemProperty.PhoneCallCalling, che però mi ritorna true nel momento in cui lancio la chiamata, compresi quindi quei maledetti secondi variabili, che non mi consentono l'estrema precisione nei calcoli che vengono a seguire.
Ti sarei molto grato per un tuo eventuale aiuto.
Grazie
Davide
Comments have been closed on this topic.
«May»
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678