--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/genscaninfo.cpp Tue Feb 02 02:03:13 2010 +0200
@@ -0,0 +1,405 @@
+/*
+* Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Class to dig information of scan results.
+*
+*/
+
+
+#include "genscaninfo.h"
+#include "genscaninfoie.h"
+
+// Default values for information element IDs.
+const u8_t WPA_IE_ID = 221;
+const u8_t SCAN_WPA_OUI_LENGTH = 4;
+const u8_t SCAN_WPA_OUI[] = { 0x00, 0x50, 0xF2, 0x01 };
+const u8_t SCAN_WSC_OUI[] = { 0x00, 0x50, 0xF2, 0x04 };
+
+const u8_t SCAN_OUI_TYPE_OFFSET = 3;
+const u8_t SCAN_OUI_SUBTYPE_OFFSET = 4;
+
+/** Offset from AttributeType field to DataLength field */
+const u8_t SCAN_WSC_IE_DATA_LENGTH_OFFSET = 2;
+
+/** Offset from AttributeType field to Data field */
+const u8_t SCAN_WSC_IE_DATA_AREA_OFFSET = 4;
+
+/** Offset to first Protected Setup attribute type in IE */
+const u8_t SCAN_WSC_IE_PROTECTED_SETUP_DATA_OFFSET = 2+4;
+
+/** IDs for different data elements in WSC IE. */
+const u16_t SCAN_WSC_IE_AP_SETUP_LOCKED = 0x1057;
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+ScanInfo::ScanInfo( const ScanList& scan_list ) :
+ ScanListIterator( scan_list ),
+ ie_iter_m( current_m + MGMT_BODY_OFFSET )
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+WlanSecurityMode ScanInfo::SecurityMode()
+ {
+ ScanInfoIe ie;
+ return ie.SecurityMode( *this );
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+WlanScanError ScanInfo::InformationElement(
+ u8_t ie_id,
+ u8_t& ie_length,
+ const u8_t** ie_data )
+ {
+ // IE is not found when the whole scan info element is gone through.
+ //
+ // The Element format is:
+ // +----+----+--...--+
+ // | a | b | c |
+ // +----+----+--...--+
+ // where
+ // a) Element ID (1 byte)
+ // b) Length (1 byte)
+ // c) Information (length bytes)
+ //
+
+ u8_t ie, len;
+ const u8_t* data;
+
+ if ( FirstIE( ie, len, &data ) != WlanScanError_Ok )
+ {
+ ie_length = 0;
+ *ie_data = NULL;
+ return WlanScanError_IeNotFound;
+ }
+
+ WlanScanError ret( WlanScanError_Ok );
+
+ while ( ie != ie_id && ret == WlanScanError_Ok )
+ {
+ ret = NextIE( ie, len, &data );
+ }
+
+ ie_length = len;
+ *ie_data = data;
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+WlanScanError ScanInfo::WpaIE(
+ u8_t& ie_length,
+ const u8_t** ie_data )
+ {
+ // Element format is:
+ // +----+-----+-----+-----+------+-------+--...--+-------+--...--+--------+
+ // | ID | Len | OUI | Ver | GKCS | PKCSC | PKSCL | AKMSC | AKMSL | RSNCap |
+ // +----+-----+-----+-----+------+-------+--...--+-------+--...--+--------+
+ // where
+ // ID = Element ID = 221 (1 octet)
+ // Len = Length (1 octet)
+ // OUI = 00:50:F2:01 (4 octets)
+ // Ver = Version (2 octets)
+ // GKCS = Group Key Cipher Suite (4 octets)
+ // PKCSC = Pairwise Key Cipher Suite Count (2 octets)
+ // PKCSL = Pairwise Key Cipher Suite List (4*m octets)
+ // AKMSC = Authenticated Key Management Suite Count (2 octets)
+ // AKMSL = Authenticated Key Management Suite List (4*n octets)
+ // RSNCap = RSN Capabilities
+
+ u8_t ie( WPA_IE_ID ), len;
+ const u8_t* data;
+
+ // Find out the first element
+ if ( InformationElement( WPA_IE_ID, len, &data ) != WlanScanError_Ok )
+ { // Okay, it didn't exist.
+ ie_length = 0;
+ *ie_data = NULL;
+ return WlanScanError_IeNotFound;
+ }
+
+ // The ID is correct but check also the UID.
+ WlanScanError ret( WlanScanError_Ok );
+
+ while ( ret == WlanScanError_Ok &&
+ ( ie != WPA_IE_ID ||
+ len < SCAN_WPA_OUI_LENGTH ||
+ !( data[0] == SCAN_WPA_OUI[0] && data[1] == SCAN_WPA_OUI[1] &&
+ data[2] == SCAN_WPA_OUI[2] && data[3] == SCAN_WPA_OUI[3] ) ) )
+ {
+ ret = NextIE( ie, len, &data );
+ }
+
+ // Check is the element was corrupted
+ if ( ie != WPA_IE_ID )
+ {
+ ie_length = 0;
+ *ie_data = NULL;
+ return WlanScanError_IeNotFound;
+ }
+
+ ie_length = len;
+ *ie_data = data;
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+WlanScanError ScanInfo::InformationElement(
+ u8_t ie_id,
+ const WlanIeOui& ie_oui,
+ u8_t ie_oui_type,
+ u8_t& ie_length,
+ const u8_t** ie_data )
+ {
+ // Element format is:
+ // +----+-----+-----+-----+------+-------+--...--+-------+--...--+--------+
+ // | ID | Len | OUI | | | | | | | |
+ // +----+-----+-----+-----+------+-------+--...--+-------+--...--+--------+
+ // where
+ // ID = Element ID (1 octet)
+ // Len = Length (1 octet)
+ // OUI = OUI (3 octets)
+ // OUItyp = OUI Type (1 octet)
+
+ u8_t ie( ie_id );
+ u8_t len( 0 );
+ const u8_t* data;
+
+ // Find the first element
+ if ( InformationElement( ie_id, len, &data )
+ != WlanScanError_Ok )
+ { // Okay, it didn't exist.
+ ie_length = 0;
+ *ie_data = NULL;
+ return WlanScanError_IeNotFound;
+ }
+
+ // The ID is correct but also the OUI and OUI Type need to match
+ WlanScanError ret( WlanScanError_Ok );
+
+ while ( ret == WlanScanError_Ok &&
+ ( ie != ie_id ||
+ !( data[0] == ie_oui[0] &&
+ data[1] == ie_oui[1] &&
+ data[2] == ie_oui[2]
+ ) ||
+ *( data + SCAN_OUI_TYPE_OFFSET ) != ie_oui_type
+ )
+ )
+ {
+ ret = NextIE( ie, len, &data );
+ }
+
+ // Check if the element is corrupted
+ if ( ie != ie_id )
+ {
+ ie_length = 0;
+ *ie_data = NULL;
+ return WlanScanError_IeNotFound;
+ }
+
+ ie_length = len;
+ *ie_data = data;
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+WlanScanError ScanInfo::InformationElement(
+ u8_t ie_id,
+ const WlanIeOui& ie_oui,
+ u8_t ie_oui_type,
+ u8_t ie_oui_subtype,
+ u8_t& ie_length,
+ const u8_t** ie_data )
+ {
+ // Element format is:
+ // +----+-----+-----+-----+------+-------+--...--+-------+--...--+--------+
+ // | ID | Len | OUI | | | | | | | |
+ // +----+-----+-----+-----+------+-------+--...--+-------+--...--+--------+
+ // where
+ // ID = Element ID (1 octet)
+ // Len = Length (1 octet)
+ // OUI = OUI (3 octets)
+ // OUItyp = OUI Type (1 octet)
+
+ u8_t ie( ie_id );
+ u8_t len( 0 );
+ const u8_t* data;
+
+ // Find the first element
+ if ( InformationElement( ie_id, len, &data )
+ != WlanScanError_Ok )
+ { // Okay, it didn't exist.
+ ie_length = 0;
+ *ie_data = NULL;
+ return WlanScanError_IeNotFound;
+ }
+
+ // The ID is correct but also the OUI and OUI Type need to match
+ WlanScanError ret( WlanScanError_Ok );
+
+ while ( ret == WlanScanError_Ok &&
+ ( ie != ie_id ||
+ !( data[0] == ie_oui[0] &&
+ data[1] == ie_oui[1] &&
+ data[2] == ie_oui[2]
+ ) ||
+ *( data + SCAN_OUI_TYPE_OFFSET ) != ie_oui_type ||
+ *( data + SCAN_OUI_SUBTYPE_OFFSET ) != ie_oui_subtype
+ )
+ )
+ {
+ ret = NextIE( ie, len, &data );
+ }
+
+ // Check if the element is corrupted
+ if ( ie != ie_id )
+ {
+ ie_length = 0;
+ *ie_data = NULL;
+ return WlanScanError_IeNotFound;
+ }
+
+ ie_length = len;
+ *ie_data = data;
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+WlanScanError ScanInfo::FirstIE(
+ u8_t& ie_id,
+ u8_t& ie_length,
+ const u8_t** ie_data )
+ {
+ if( !current_m )
+ {
+ return WlanScanError_IeNotFound;
+ }
+ ie_iter_m = current_m + MGMT_BODY_OFFSET;
+ return CurrentIE( ie_id, ie_length, ie_data );
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+WlanScanError ScanInfo::NextIE(
+ u8_t& ie_id,
+ u8_t& ie_length,
+ const u8_t** ie_data )
+ {
+ if( !current_m )
+ {
+ return WlanScanError_IeNotFound;
+ }
+ ie_iter_m += *( ie_iter_m + 1 ) + 2;
+ return CurrentIE( ie_id, ie_length, ie_data );
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+WlanScanError ScanInfo::CurrentIE(
+ u8_t& ie_id,
+ u8_t& ie_length,
+ const u8_t** ie_data ) const
+ {
+ if ( !current_m || ie_iter_m >= current_m + Size() )
+ {
+ ie_id = 0;
+ ie_length = 0;
+ *ie_data = NULL;
+ return WlanScanError_IeNotFound;
+ }
+
+ ie_id = *ie_iter_m;
+ ie_length = *( ie_iter_m+1 );
+ *ie_data = ie_iter_m+2;
+ return WlanScanError_Ok;
+}
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+bool_t ScanInfo::IsProtectedSetupSupported()
+ {
+ u8_t ie_length = 0;
+ const u8_t* ie_data = NULL;
+ const WlanIeOui ie_oui = { SCAN_WSC_OUI[0], SCAN_WSC_OUI[1], SCAN_WSC_OUI[2] };
+ const u8_t ie_oui_type = SCAN_WSC_OUI[3];
+
+ WlanScanError err = InformationElement( WPA_IE_ID,
+ ie_oui, ie_oui_type,
+ ie_length, &ie_data );
+
+ if (err == WlanScanError_IeNotFound
+ || ie_data == NULL
+ || ie_length == 0 )
+ {
+ return false_t;
+ }
+
+ // WSC IE is found, next check whether AP setup is locked (locked state would prevent use of Protected Setup)
+ return !IsApSetupLocked( ie_data, ie_length );
+ }
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+bool_t ScanInfo::IsApSetupLocked(
+ const u8_t* ie_data,
+ const u8_t ie_length ) const
+ {
+ u16_t index( SCAN_WSC_IE_PROTECTED_SETUP_DATA_OFFSET );
+
+ while ( (index + SCAN_WSC_IE_DATA_LENGTH_OFFSET + 1) < ie_length)
+ {
+ // Make big endian to little endian conversion.
+ u16_t attribute_type = (ie_data[index]<<8)
+ | (ie_data[index+1]);
+
+ u16_t attribute_data_length = (ie_data[index + SCAN_WSC_IE_DATA_LENGTH_OFFSET]<<8)
+ | (ie_data[index + SCAN_WSC_IE_DATA_LENGTH_OFFSET+1]);
+
+ // Check if all attribute data does not fit current IE.
+ if ( ( index + attribute_data_length + SCAN_WSC_IE_DATA_AREA_OFFSET ) > ie_length)
+ {
+ // attribute does not fit current IE
+ return false_t;
+ }
+
+ if (attribute_type == SCAN_WSC_IE_AP_SETUP_LOCKED)
+ {
+ // AP setup locked attribute found, return its value.
+ return ie_data[index + SCAN_WSC_IE_DATA_AREA_OFFSET];
+ }
+
+ // update index to start of next attribute
+ index += SCAN_WSC_IE_DATA_AREA_OFFSET + attribute_data_length;
+ }
+ //
+ return false_t;
+ }