none
How to make sure that a particualt Access Point is connected to WLAN? RRS feed

  • Question

  • Hello,

    Windows CE 6.0 platform.

    The NDIS driver on the device potentially could have multiple configured Access Points plus the device could have LAN connection.

    How could I make sure [or double check] that the WLAN connection is established through a particulat Access Point?

    It can be WZCS APIs or NativeMethods...any thoughts would be greatly appreciated.

     

     

    • Moved by Jesse Jiang Monday, October 10, 2011 8:14 AM (From:Visual Studio Smart Device Development – Visual Basic and C# Projects)
    Friday, October 7, 2011 3:26 PM

All replies

  • Hello,

     

    I think your issue should be raised in the Windows Embedded Compact Platform Development. I believe they will know more information of this issue than us, and I will move this one to that forum.

     

    Thanks for your understanding,

     

    Best regards,

    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, October 10, 2011 8:14 AM
  • Hi,

    Do you have shell? If so please, please type  "wzctool -q" at command shell.

    It will display the currently connected AP. Hope it helps.

    <WINCEROOT>\PUBLIC\COMMON\OAK\DRIVERS\NETSAMP\WZCTOOL

    Regards,

    Wince User

    Monday, October 10, 2011 9:30 AM
  • Thank you for reply.

    However I think it would not help. I've been *playing around* with OpenNETCF lib and wzctool for quite sometime now and it looks like the internal [so to speak] information stored in NDIS driver is different from what's going on....

    Here is the sample and situation I am trying to solve.

    When you add a new Access Point you have to provide a WEP key [let's say it's WEP-enabled]. The problem is even if you provide a wrong key the AP will be stored in the NDIS driver and to you everything will be looking OK. As you understand in that case you would not be connected...

    If you do the same thing from inside Adapter settings on the WinCE device if you provide incorrect key you would not see a circle around the tower [reflecting the fact there is no connection] and if you provide correct key - there will be a circle...

    How does the OS know?

     

    Monday, October 10, 2011 1:28 PM
  • Let's try it under different angle :)

    On the device you go to "AdapterProperties"->"Wireless Information" and select appropriate Access Point. Right click on it and then "Connect". Un-check "The key is provided automatically" and then enter a key into the Network Key field.

    There is a "Status" field on the Wireless Information screen.

    If you provided correct key the status will go "Associated with..." and then to "Connected to..."

    If you provided incorrect key the status will stuck on "Associated with..."

    How does the OS know?

    Tuesday, October 11, 2011 2:56 PM
  • The "Connected to" message, as well as the aspect of the WiFi icon on the taskbar are 'triggered' by the UpdateConnectionStatus function exported by NETUI: ETHMAN calls this function with fConnected = TRUE when it detects that the IP address of the adapter is valid (which means != "0.0.0.0").

    Take a look at %_WINCEROOT%\PUBLIC\COMMON\OAK\DRIVERS\NETUI\wzcquickcfgui.c and %_WINCEROOT%\PUBLIC\COMMON\OAK\DRIVERS\NETSAMP\ETHMAN\ethman.c for more details


    Luca Calligaris lucaDOTcalligarisATeurotechDOTcom www.eurotech.com Check my blog: http://lcalligaris.wordpress.com
    Tuesday, October 11, 2011 3:29 PM
  • Luca, Thanks!

    I looked at it...

    If your adapter's IP settings are set to "Obtain IP address from DHCP server" then the status gets stuck on "Associating with...". Apparently it cannot get the IP from the server...

    If you set IP to a static IP on the device then even if the provided WEP key is wrong(!!!) you will get status "Connected to..."

    I think it's wrong. It sounds like a bug...

    At the same time, because I use OpenNETCF library, in the code I get the same notification sequence for both cases - when I try connecting with correct or wrong key:

    In the adapter's wireless network log file:

    - Preferred list exhausted - on disconnect;

    - Associating with <AP> - 0n "Associating with...;

    - Associated with <AP> - on "Connected to..."

    However in the library I am getting only two notifications: NdisNotificationType.NdisMediaDisconnect and NdisNotificationType.NdisMediaConnect.

    I think I need to get messages from WzcEventLoggingQueue (wzcmsg.h) to get all statuses...

    I am already running late... Maybe I could get working sample :)

    Thanks again,

     

     

    Tuesday, October 11, 2011 7:44 PM
  • OK, I need help with this "Wireless Networking Log".

    I assumed that on my device the WZC Service is running because I can get all info from it and also I assumed that the "WzcEventLoggingQueue"  is present because the the log file is getting updated.

    The code is based on P2PMessageQueue and the WinCE Platform Builder samples above.

    The problem is I am missing something - I am getting notifications from P2PMessageQueue class but on return the AdapterLogEntry is empty.

    Could you please tell what's missing, why the structure is empty.

    Thank you!

    The code:

    <code>

    namespace Testing
    {
        internal class LogEntryConstants
        {
            internal const int CURRENT_LOGGING_VERSION = 4;
            internal const int DEFAULT_MAX_MESSAGES = 16;
            internal const string WZC_MSGQUEUE_NAME = "WzcEventLoggingQueue";
        }
    /*
            //  The LogID posted by zero config..
            //  For all IDs, ptcAdapterName is always valid.
            //#define WZC_STARTED                     0xffffffff      //  Other args invalid.
            //#define WZC_ASSOCIATING                 0x00000001      //  Valid pucSSID
            //#define WZC_FAILED_ASSOCIATION          0x00000002      //  Valid pucSSID
            //#define WZC_SUCCESSFUL_ASSOCIATION      0x00000003      //  Valid pucSSID : Valid pucBSSID (for infrastructure only)
            //#define WZC_CLOSE_EAPOL_SESSION         0x00000004      //  Valid pucSSID
            //#define WZC_AUTHENTICATING              0x00000005      //  Valid pucSSID : Valid pucBSSID : dwArg1 == Retry number
            //#define WZC_AUTHENTICATED               0x00000006      //  Valid pucSSID : Valid pucBSSID
            //#define WZC_CANCEL_AUTH                 0x00000007      //  Valid pucSSID
            //#define WZC_FAILED_AUTH_NO_RETRY        0x00000008      //  Valid pucSSID : dwArs is always ERROR_CANCELLED.
            //#define WZC_FAILED_AUTH_WILL_RETRY      0x00000009      //  Valid pucSSID : dwArg == Failure reason.
            //#define WZC_PREFERED_LIST_EXHAUSTED     0x0000000a      //  None valid.
            //#define WZC_REAUTHENTICATING            0x0000000b      //  Valid pucSSID ; Valid pucBSSID
            //#define WZC_VISIBLE_NETWORK             0x0000000c      //  None valid. (this is sent only in WZC_PREFERED_LIST_EXHAUSTED case).
                                                                    //      as indication that there is at least one visible network out there.
            //#define WZC_ASSOCIATED_NO_8021X         WZC_SUCCESSFUL_ASSOCIATION
                                                                    //  Valid pucSSID : Valid pucBSSID (for infrastructure only)
            //#define WZC_ASSOCIATED_REQUIRES_8021X   0x0000000d      //  Valid pucSSID : Valid pucBSSID (for infrastructure only)
            //#define WZC_CONFIGURED                  0x0000000e      //  Valid pucSSID
    */
        public enum LOGID_TYPE : uint
        {
            WZC_STARTED                     = 0xffffffff,
            WZC_ASSOCIATING                 = 0x00000001,
            WZC_FAILED_ASSOCIATION          = 0x00000002,
            WZC_SUCCESSFUL_ASSOCIATION      = 0x00000003,
            WZC_CLOSE_EAPOL_SESSION         = 0x00000004,
            WZC_AUTHENTICATING              = 0x00000005,
            WZC_AUTHENTICATED               = 0x00000006,
            WZC_CANCEL_AUTH                 = 0x00000007,
            WZC_FAILED_AUTH_NO_RETRY        = 0x00000008,
            WZC_FAILED_AUTH_WILL_RETRY      = 0x00000009,
            WZC_PREFERED_LIST_EXHAUSTED     = 0x0000000a,
            WZC_REAUTHENTICATING            = 0x0000000b,
            WZC_VISIBLE_NETWORK             = 0x0000000c,
            WZC_ASSOCIATED_NO_8021X         = WZC_SUCCESSFUL_ASSOCIATION,
            WZC_ASSOCIATED_REQUIRES_8021X   = 0x0000000d,
            WZC_CONFIGURED                  = 0x0000000e,
        }

        public class AdapterLogEntry : Message
        {
    /*
            typedef struct
            { 
                DWORD       dwLogId;                    //  WZC_XXX defined below..
                DWORD       dwCurrentLogVersion;        //  To make we are using the correct client..
                UCHAR       pucSSID[33];                //  SSID is 32 byte string, add 1 byte for NULL termination.
                UCHAR       pucBSSID[6];                //  MAC address of the AP we are associated with.
                DWORD       dwArg;                      //  Misc..
                DWORD       dwInfrastructureMode;       //  Value should be read as NDIS_802_11_NETWORK_INFRASTRUCTURE.
                FILETIME    ftTimeStamp;                //  Time stamp of when log is created.
                TCHAR       ptcAdapterName[MAX_PATH];   //  Adapter name..
           
            }   LOG_ENTRY, *PLOG_ENTRY;
    */
            private const int PUCSSID_LENGTH = 33; // in chars, WCHAR - have to multiply by 2
            private const int PUCBSSID_LENGTH = 6;
            private const int MAX_PATH = 260;

            public const int Size = 583;                  // total length
            internal byte[] data = new byte[Size];

            public AdapterLogEntry() { }
            public const int LogIdOffset = 0;
            public long dwLogId
            {
                get { return BitConverter.ToInt32(data, LogIdOffset); }
            }

            public const int CurrentLogVersionOffset = LogIdOffset + 4;
            public long dwCurrentLogVersion
            {
                get { return BitConverter.ToInt32(data, CurrentLogVersionOffset); }
            }

            public const int pucSSIDOffset = CurrentLogVersionOffset + 4;
            public string pucSSID
            {
                get
                {
                    String s = System.Text.Encoding.Unicode.GetString(data, pucSSIDOffset, PUCSSID_LENGTH);
                    int l = s.IndexOf('\0');
                    if (l != -1)
                        return s.Substring(0, l);
                    return s;
                }
            }
            public const int pucBSSIDOffset = pucSSIDOffset + PUCSSID_LENGTH;
            public string pucBSSID
            {
                get
                {
                    String s = System.Text.Encoding.Unicode.GetString(data, pucSSIDOffset, PUCBSSID_LENGTH);
                    int l = s.IndexOf('\0');
                    if (l != -1)
                        return s.Substring(0, l);
                    return s;
                }
            }
            public const int ArgOffset = pucBSSIDOffset + PUCBSSID_LENGTH;
            public long dwArg
            {
                get { return BitConverter.ToInt32(data, ArgOffset); }
            }

            public const int InfrastructureModeOffset = ArgOffset + 4;
            public long dwInfrastructureMode
            {
                get { return BitConverter.ToInt32(data, InfrastructureModeOffset); }
            }

            public const int TimeStampOffset = InfrastructureModeOffset + 4;
            public DateTime ftTimeStamp
            {
                get { return DateTime.FromFileTime(BitConverter.ToInt64(data, InfrastructureModeOffset)); } // 8 bytes
            }

            public const int ptcAdapterNameOffset = TimeStampOffset + 8;
            public string ptcAdapterName
            {
                get
                {
                    String s = System.Text.Encoding.Unicode.GetString(data, ptcAdapterNameOffset, MAX_PATH*2);
                    int l = s.IndexOf('\0');
                    if (l != -1)
                        return s.Substring(0, l);
                    return s;
                }
            }

            public byte[] getBytes()
            {
                return data;
            }

            public static implicit operator byte[](AdapterLogEntry log)
            {
                return log.data;
            }
        }

        public delegate void AdapterLogEntryNotificationEventHandler(object sender, AdapterLogEntryNotificationArgs e);

        public class AdapterLogEntryNotificationArgs : System.EventArgs
        {  
            private AdapterLogEntry entry;

            public AdapterLogEntry Entry
            {
                get { return Entry;  }
            }

            public AdapterLogEntryNotificationArgs(AdapterLogEntry e)
            {
                entry = e;
            }
        }

        public class AdapterLogMonitor
        {
            private P2PMessageQueue p2pmq = null;
            public static AdapterLogMonitor Monitor = new AdapterLogMonitor();
            public bool Active
            {
                get
                {
                    return (p2pmq != null);
                }
            }

            public event AdapterLogEntryNotificationEventHandler AdapterLogNotification;

            private AdapterLogMonitor() {}

            ~AdapterLogMonitor()
            {
                this.StopLogMonitoring();
            }

            public void StartLogMonitoring()
            {
                if (!Active)
                {
                    p2pmq = new P2PMessageQueue(true, LogEntryConstants.WZC_MSGQUEUE_NAME,
                                                AdapterLogEntry.Size, LogEntryConstants.DEFAULT_MAX_MESSAGES);
                    p2pmq.DataOnQueueChanged += new EventHandler(p2pmq_DataOnQueueChanged);

                }
            }

            void p2pmq_DataOnQueueChanged(object sender, EventArgs e)
            {
                try
                {
                    while (p2pmq != null && p2pmq.MessagesInQueueNow > 0)
                    {
                        AdapterLogEntry logEntry = new AdapterLogEntry();
                        if (p2pmq.Receive(logEntry , -1) == ReadWriteResult.OK)
                        {
                            OnAdapterLogNotification(new AdapterLogEntryNotificationArgs(logEntry));
                        }
                    }           
                }
                catch (ApplicationException)
                {
                    this.StopLogMonitoring();
                }
            }

            public void StopLogMonitoring()
            {
                if (Active)
                {
                    P2PMessageQueue q = p2pmq;
                    p2pmq = null;
                    q.Close();
                }
            }

            protected virtual void OnAdapterLogNotification(AdapterLogEntryNotificationArgs e)
            {
                if (AdapterLogNotification != null)
                {
                    AdapterLogNotification(this, e);
                }
            }
        }
    }

    </code>

    Wednesday, October 12, 2011 4:54 PM
  • I found some errors on my side.

    Here is working code.

    <code>

    namespace Testing
    {
        internal class WirelessNetworkingLogConstants
        {
            internal const int CURRENT_LOGGING_VERSION = 4;
            internal const int DEFAULT_MAX_MESSAGES = 16;
            internal const string WZC_MSGQUEUE_NAME = "WzcEventLoggingQueue";
        }
    /*
            //  The LogID posted by zero config..
            //  For all IDs, ptcAdapterName is always valid.
            //#define WZC_STARTED                     0xffffffff      //  Other args invalid.
            //#define WZC_ASSOCIATING                 0x00000001      //  Valid pucSSID
            //#define WZC_FAILED_ASSOCIATION          0x00000002      //  Valid pucSSID
            //#define WZC_SUCCESSFUL_ASSOCIATION      0x00000003      //  Valid pucSSID : Valid pucBSSID (for infrastructure only)
            //#define WZC_CLOSE_EAPOL_SESSION         0x00000004      //  Valid pucSSID
            //#define WZC_AUTHENTICATING              0x00000005      //  Valid pucSSID : Valid pucBSSID : dwArg1 == Retry number
            //#define WZC_AUTHENTICATED               0x00000006      //  Valid pucSSID : Valid pucBSSID
            //#define WZC_CANCEL_AUTH                 0x00000007      //  Valid pucSSID
            //#define WZC_FAILED_AUTH_NO_RETRY        0x00000008      //  Valid pucSSID : dwArs is always ERROR_CANCELLED.
            //#define WZC_FAILED_AUTH_WILL_RETRY      0x00000009      //  Valid pucSSID : dwArg == Failure reason.
            //#define WZC_PREFERED_LIST_EXHAUSTED     0x0000000a      //  None valid.
            //#define WZC_REAUTHENTICATING            0x0000000b      //  Valid pucSSID ; Valid pucBSSID
            //#define WZC_VISIBLE_NETWORK             0x0000000c      //  None valid. (this is sent only in WZC_PREFERED_LIST_EXHAUSTED case).
                                                                    //      as indication that there is at least one visible network out there.
            //#define WZC_ASSOCIATED_NO_8021X         WZC_SUCCESSFUL_ASSOCIATION
                                                                    //  Valid pucSSID : Valid pucBSSID (for infrastructure only)
            //#define WZC_ASSOCIATED_REQUIRES_8021X   0x0000000d      //  Valid pucSSID : Valid pucBSSID (for infrastructure only)
            //#define WZC_CONFIGURED                  0x0000000e      //  Valid pucSSID
    */
        public struct FILETIME
        {
            public int dwLowDateTime;
            public int dwHighDateTime;
        }

        public enum WZC_ID_TYPE : uint
        {
            WZC_STARTED = 0xffffffff,
            WZC_ASSOCIATING = 0x00000001,
            WZC_FAILED_ASSOCIATION = 0x00000002,
            WZC_SUCCESSFUL_ASSOCIATION = 0x00000003,
            WZC_CLOSE_EAPOL_SESSION = 0x00000004,
            WZC_AUTHENTICATING = 0x00000005,
            WZC_AUTHENTICATED = 0x00000006,
            WZC_CANCEL_AUTH = 0x00000007,
            WZC_FAILED_AUTH_NO_RETRY = 0x00000008,
            WZC_FAILED_AUTH_WILL_RETRY = 0x00000009,
            WZC_PREFERED_LIST_EXHAUSTED = 0x0000000a,
            WZC_REAUTHENTICATING = 0x0000000b,
            WZC_VISIBLE_NETWORK = 0x0000000c,
            WZC_ASSOCIATED_NO_8021X = WZC_SUCCESSFUL_ASSOCIATION,
            WZC_ASSOCIATED_REQUIRES_8021X = 0x0000000d,
            WZC_CONFIGURED = 0x0000000e,
        }

        public class WirelessNetworkingLog : Message
        {
    /*
            typedef struct
            { 
                DWORD       dwLogId;                    //  WZC_XXX defined below..
                DWORD       dwCurrentLogVersion;        //  To make we are using the correct client..
                UCHAR       pucSSID[33];                //  SSID is 32 byte string, add 1 byte for NULL termination.
                UCHAR       pucBSSID[6];                //  MAC address of the AP we are associated with.
                DWORD       dwArg;                      //  Misc..
                DWORD       dwInfrastructureMode;       //  Value should be read as NDIS_802_11_NETWORK_INFRASTRUCTURE.
                FILETIME    ftTimeStamp;                //  Time stamp of when log is created.
                TCHAR       ptcAdapterName[MAX_PATH];   //  Adapter name..
           
            }   LOG_ENTRY, *PLOG_ENTRY;
    */
            private const int PUCSSID_LENGTH = 33; // in chars, WCHAR - have to multiply by 2
            private const int PUCBSSID_LENGTH = 6;
            private const int MAX_PATH = 260;

            public const int Size = 583;                  // total length
            internal byte[] data = new byte[Size];

            public WirelessNetworkingLog() { }

            public const int LogIdOffset = 0;
            public WZC_ID_TYPE dwLogId
            {
                get { return (WZC_ID_TYPE)BitConverter.ToInt32(data, LogIdOffset); }
            }

            public const int CurrentLogVersionOffset = LogIdOffset + 4;
            public int dwCurrentLogVersion
            {
                get { return BitConverter.ToInt32(data, CurrentLogVersionOffset); }
            }

            public const int pucSSIDOffset = CurrentLogVersionOffset + 4;
            public string pucSSID
            {
                get
                {
                    String s = System.Text.Encoding.ASCII.GetString(data, pucSSIDOffset, PUCSSID_LENGTH);
                    int l = s.IndexOf('\0');
                    if (l != -1)
                        return s.Substring(0, l);
                    return s;
                }
            }

            public const int pucBSSIDOffset = pucSSIDOffset + PUCSSID_LENGTH;
            public string pucBSSID
            {
                get
                {
                    String s = System.Text.Encoding.ASCII.GetString(data, pucSSIDOffset, PUCBSSID_LENGTH);
                    int l = s.IndexOf('\0');
                    if (l != -1)
                        return s.Substring(0, l);
                    return s;
                }
            }

            public const int ArgOffset = pucBSSIDOffset + PUCBSSID_LENGTH;
            public int dwArg
            {
                get { return BitConverter.ToInt32(data, ArgOffset); }
            }

            public const int InfrastructureModeOffset = ArgOffset + 4;
            public int dwInfrastructureMode
            {
                get { return BitConverter.ToInt32(data, InfrastructureModeOffset); }
            }

            public const int TimeStampOffset = InfrastructureModeOffset + 4;
            public FILETIME ftTimeStamp
            {
                get
                {
                    FILETIME ft;
                    ft.dwLowDateTime = BitConverter.ToInt32(data, TimeStampOffset);
                    ft.dwHighDateTime = BitConverter.ToInt32(data, TimeStampOffset + 4);
                    return ft;
                }
            }

            public const int ptcAdapterNameOffset = TimeStampOffset + 8;
            public string ptcAdapterName
            {
                get
                {
                    String s = System.Text.Encoding.Unicode.GetString(data, ptcAdapterNameOffset, 2*MAX_PATH);
                    int l = s.IndexOf('\0');
                    if (l != -1)
                        return s.Substring(0, l);
                    return s;
                }
            }

            public override byte[] MessageBytes
            {
                get
                {
                    return data;
                }
                set
                {
                    data = value;
                }
            }
        }

        public delegate void WirelessNetworingLogNotificationEventHandler(object sender, WirelessNetworkingLogNotificationArgs e);

        public class WirelessNetworkingLogNotificationArgs : System.EventArgs
        {  
            private WirelessNetworkingLog entry;

            public WirelessNetworkingLog Entry
            {
                get { return entry;  }
            }

            public WirelessNetworkingLogNotificationArgs(WirelessNetworkingLog e)
            {
                entry = e;
            }
        }

        public class WirelessNetworkingLogMonitor
        {
            private P2PMessageQueue p2pmq = null;

            public static WirelessNetworkingLogMonitor Monitor = new WirelessNetworkingLogMonitor();

            public bool Active
            {
                get
                {
                    return (p2pmq != null);
                }
            }

            public event WirelessNetworingLogNotificationEventHandler WirelessNetworkingLogNotification;

            private WirelessNetworkingLogMonitor() {}

            ~WirelessNetworkingLogMonitor()
            {
                this.StopLogMonitoring();
            }

            public void StartLogMonitoring()
            {
                if (!Active)
                {
                    // Create a point-to-point message queue to get the notifications.
                    p2pmq = new P2PMessageQueue(true, WirelessNetworkingLogConstants.WZC_MSGQUEUE_NAME,
                                                WirelessNetworkingLog.Size,
                                                WirelessNetworkingLogConstants.DEFAULT_MAX_MESSAGES);

                    p2pmq.DataOnQueueChanged += new EventHandler(p2pmq_DataOnQueueChanged);
                }
            }

            void p2pmq_DataOnQueueChanged(object sender, EventArgs e)
            {
                try
                {
                    while (p2pmq != null && p2pmq.MessagesInQueueNow > 0)
                    {
                        WirelessNetworkingLog logEntry = new WirelessNetworkingLog();

                        // Read the event data.
                        if (p2pmq.Receive(logEntry , -1) == ReadWriteResult.OK)
                        {
                            //NOTE: it reports Access Point name on attaching only
                            OnWirelessNetworkingLogNotification(new WirelessNetworkingLogNotificationArgs(logEntry));
                        }
                    }           
                }
                catch (ApplicationException)
                {
                    this.StopLogMonitoring();
                }
            }

            public void StopLogMonitoring()
            {
                if (Active)
                {
                    P2PMessageQueue q = p2pmq;
                    p2pmq = null;
                    q.Close();
                }
            }

            protected virtual void OnWirelessNetworkingLogNotification(WirelessNetworkingLogNotificationArgs e)
            {
                if (WirelessNetworkingLogNotification != null)
                {
                    WirelessNetworkingLogNotification(this, e);
                }
            }
        }
    }

    </code>

    Wednesday, October 19, 2011 5:07 PM