diff -r 000000000000 -r c40eb8fe8501 wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/genscaninfo.cpp --- /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; + }