wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/genscaninfo.cpp
changeset 0 c40eb8fe8501
equal deleted inserted replaced
-1:000000000000 0:c40eb8fe8501
       
     1 /*
       
     2 * Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Class to dig information of scan results.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "genscaninfo.h"
       
    20 #include "genscaninfoie.h"
       
    21 
       
    22 // Default values for information element IDs.
       
    23 const u8_t WPA_IE_ID              = 221;
       
    24 const u8_t SCAN_WPA_OUI_LENGTH    = 4;
       
    25 const u8_t SCAN_WPA_OUI[]         = { 0x00, 0x50, 0xF2, 0x01 };
       
    26 const u8_t SCAN_WSC_OUI[]         = { 0x00, 0x50, 0xF2, 0x04 };
       
    27 
       
    28 const u8_t SCAN_OUI_TYPE_OFFSET = 3;
       
    29 const u8_t SCAN_OUI_SUBTYPE_OFFSET = 4;
       
    30 
       
    31 /** Offset from AttributeType field to DataLength field */
       
    32 const u8_t SCAN_WSC_IE_DATA_LENGTH_OFFSET = 2;
       
    33 
       
    34 /** Offset from AttributeType field to Data field */
       
    35 const u8_t SCAN_WSC_IE_DATA_AREA_OFFSET = 4;
       
    36 
       
    37 /** Offset to first Protected Setup attribute type in IE */
       
    38 const u8_t SCAN_WSC_IE_PROTECTED_SETUP_DATA_OFFSET = 2+4;
       
    39 
       
    40 /** IDs for different data elements in WSC IE. */
       
    41 const u16_t SCAN_WSC_IE_AP_SETUP_LOCKED       = 0x1057;
       
    42 
       
    43 // ================= MEMBER FUNCTIONS =======================
       
    44 
       
    45 // ---------------------------------------------------------------------------
       
    46 // ---------------------------------------------------------------------------
       
    47 //
       
    48 ScanInfo::ScanInfo( const ScanList& scan_list ) :
       
    49     ScanListIterator( scan_list ), 
       
    50     ie_iter_m( current_m + MGMT_BODY_OFFSET )
       
    51     {
       
    52     }
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 // ---------------------------------------------------------------------------
       
    56 //
       
    57 WlanSecurityMode ScanInfo::SecurityMode()
       
    58     {
       
    59     ScanInfoIe ie;
       
    60     return ie.SecurityMode( *this );
       
    61     }
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 // ---------------------------------------------------------------------------
       
    65 //
       
    66 WlanScanError ScanInfo::InformationElement(
       
    67     u8_t ie_id, 
       
    68     u8_t& ie_length, 
       
    69     const u8_t** ie_data )
       
    70     {
       
    71     // IE is not found when the whole scan info element is gone through.
       
    72     //
       
    73     // The Element format is:
       
    74     // +----+----+--...--+
       
    75     // | a  | b  | c     |
       
    76     // +----+----+--...--+
       
    77     // where
       
    78     // a) Element ID (1 byte)
       
    79     // b) Length (1 byte)
       
    80     // c) Information (length bytes)
       
    81     //
       
    82 
       
    83     u8_t ie, len;
       
    84     const u8_t* data;
       
    85 
       
    86     if ( FirstIE( ie, len, &data ) != WlanScanError_Ok )
       
    87         {
       
    88         ie_length = 0;
       
    89         *ie_data = NULL;
       
    90         return WlanScanError_IeNotFound;
       
    91         }
       
    92 
       
    93     WlanScanError ret( WlanScanError_Ok );
       
    94 
       
    95     while ( ie != ie_id && ret == WlanScanError_Ok )
       
    96         {
       
    97         ret = NextIE( ie, len, &data );
       
    98         }
       
    99 
       
   100     ie_length = len;
       
   101     *ie_data = data;
       
   102     return ret;
       
   103     }
       
   104 
       
   105 // ---------------------------------------------------------------------------
       
   106 // ---------------------------------------------------------------------------
       
   107 //
       
   108 WlanScanError ScanInfo::WpaIE(
       
   109     u8_t& ie_length, 
       
   110     const u8_t** ie_data )
       
   111     {
       
   112     // Element format is:
       
   113     // +----+-----+-----+-----+------+-------+--...--+-------+--...--+--------+
       
   114     // | ID | Len | OUI | Ver | GKCS | PKCSC | PKSCL | AKMSC | AKMSL | RSNCap |
       
   115     // +----+-----+-----+-----+------+-------+--...--+-------+--...--+--------+
       
   116     // where
       
   117     // ID     = Element ID = 221 (1 octet)
       
   118     // Len    = Length (1 octet)
       
   119     // OUI    = 00:50:F2:01 (4 octets)
       
   120     // Ver    = Version (2 octets)
       
   121     // GKCS   = Group Key Cipher Suite (4 octets)
       
   122     // PKCSC  = Pairwise Key Cipher Suite Count (2 octets)
       
   123     // PKCSL  = Pairwise Key Cipher Suite List (4*m octets)
       
   124     // AKMSC  = Authenticated Key Management Suite Count (2 octets)
       
   125     // AKMSL  = Authenticated Key Management Suite List (4*n octets)
       
   126     // RSNCap = RSN Capabilities
       
   127 
       
   128     u8_t ie( WPA_IE_ID ), len;
       
   129     const u8_t* data;
       
   130 
       
   131     // Find out the first element
       
   132     if ( InformationElement( WPA_IE_ID, len, &data ) != WlanScanError_Ok )
       
   133         { // Okay, it didn't exist.
       
   134         ie_length = 0;
       
   135         *ie_data = NULL;
       
   136         return WlanScanError_IeNotFound;
       
   137         }
       
   138 
       
   139     // The ID is correct but check also the UID.
       
   140     WlanScanError ret( WlanScanError_Ok );
       
   141 
       
   142     while ( ret == WlanScanError_Ok &&
       
   143             ( ie != WPA_IE_ID ||
       
   144               len < SCAN_WPA_OUI_LENGTH ||
       
   145               !( data[0] == SCAN_WPA_OUI[0] && data[1] == SCAN_WPA_OUI[1] &&
       
   146                  data[2] == SCAN_WPA_OUI[2] && data[3] == SCAN_WPA_OUI[3] ) ) )
       
   147         {
       
   148         ret = NextIE( ie, len, &data );
       
   149         }
       
   150 
       
   151     // Check is the element was corrupted
       
   152     if ( ie != WPA_IE_ID )
       
   153         {
       
   154         ie_length = 0;
       
   155         *ie_data = NULL;
       
   156         return WlanScanError_IeNotFound;
       
   157         }
       
   158 
       
   159     ie_length = len;
       
   160     *ie_data = data;
       
   161     return ret;
       
   162     }
       
   163 
       
   164 // ---------------------------------------------------------------------------
       
   165 // ---------------------------------------------------------------------------
       
   166 //
       
   167 WlanScanError ScanInfo::InformationElement(
       
   168     u8_t ie_id,
       
   169     const WlanIeOui& ie_oui,
       
   170     u8_t ie_oui_type,
       
   171     u8_t& ie_length, 
       
   172     const u8_t** ie_data )
       
   173     {
       
   174     // Element format is:
       
   175     // +----+-----+-----+-----+------+-------+--...--+-------+--...--+--------+
       
   176     // | ID | Len | OUI |     |      |       |       |       |       |        |
       
   177     // +----+-----+-----+-----+------+-------+--...--+-------+--...--+--------+
       
   178     // where
       
   179     // ID     = Element ID (1 octet)
       
   180     // Len    = Length (1 octet)
       
   181     // OUI    = OUI (3 octets)
       
   182     // OUItyp = OUI Type (1 octet)
       
   183 
       
   184     u8_t ie( ie_id ); 
       
   185     u8_t len( 0 );
       
   186     const u8_t* data;
       
   187 
       
   188     // Find the first element
       
   189     if ( InformationElement( ie_id, len, &data ) 
       
   190          != WlanScanError_Ok )
       
   191         { // Okay, it didn't exist.
       
   192         ie_length = 0;
       
   193         *ie_data = NULL;
       
   194         return WlanScanError_IeNotFound;
       
   195         }
       
   196 
       
   197     // The ID is correct but also the OUI and OUI Type need to match
       
   198     WlanScanError ret( WlanScanError_Ok );
       
   199 
       
   200     while ( ret == WlanScanError_Ok && 
       
   201             ( ie != ie_id || 
       
   202               !( data[0] == ie_oui[0] && 
       
   203                  data[1] == ie_oui[1] &&
       
   204                  data[2] == ie_oui[2] 
       
   205                ) ||
       
   206               *( data + SCAN_OUI_TYPE_OFFSET ) != ie_oui_type
       
   207             ) 
       
   208           )
       
   209         {
       
   210         ret = NextIE( ie, len, &data );
       
   211         }
       
   212 
       
   213     // Check if the element is corrupted
       
   214     if ( ie != ie_id )
       
   215         {
       
   216         ie_length = 0;
       
   217         *ie_data = NULL;
       
   218         return WlanScanError_IeNotFound;
       
   219         }
       
   220 
       
   221     ie_length = len;
       
   222     *ie_data = data;
       
   223     return ret;
       
   224     }
       
   225 
       
   226 // ---------------------------------------------------------------------------
       
   227 // ---------------------------------------------------------------------------
       
   228 //
       
   229 WlanScanError ScanInfo::InformationElement(
       
   230     u8_t ie_id,
       
   231     const WlanIeOui& ie_oui,
       
   232     u8_t ie_oui_type,
       
   233     u8_t ie_oui_subtype,
       
   234     u8_t& ie_length, 
       
   235     const u8_t** ie_data )
       
   236     {
       
   237     // Element format is:
       
   238     // +----+-----+-----+-----+------+-------+--...--+-------+--...--+--------+
       
   239     // | ID | Len | OUI |     |      |       |       |       |       |        |
       
   240     // +----+-----+-----+-----+------+-------+--...--+-------+--...--+--------+
       
   241     // where
       
   242     // ID     = Element ID (1 octet)
       
   243     // Len    = Length (1 octet)
       
   244     // OUI    = OUI (3 octets)
       
   245     // OUItyp = OUI Type (1 octet)
       
   246 
       
   247     u8_t ie( ie_id ); 
       
   248     u8_t len( 0 );
       
   249     const u8_t* data;
       
   250 
       
   251     // Find the first element
       
   252     if ( InformationElement( ie_id, len, &data ) 
       
   253          != WlanScanError_Ok )
       
   254         { // Okay, it didn't exist.
       
   255         ie_length = 0;
       
   256         *ie_data = NULL;
       
   257         return WlanScanError_IeNotFound;
       
   258         }
       
   259 
       
   260     // The ID is correct but also the OUI and OUI Type need to match
       
   261     WlanScanError ret( WlanScanError_Ok );
       
   262 
       
   263     while ( ret == WlanScanError_Ok && 
       
   264             ( ie != ie_id || 
       
   265               !( data[0] == ie_oui[0] && 
       
   266                  data[1] == ie_oui[1] &&
       
   267                  data[2] == ie_oui[2] 
       
   268                ) ||
       
   269               *( data + SCAN_OUI_TYPE_OFFSET ) != ie_oui_type ||
       
   270               *( data + SCAN_OUI_SUBTYPE_OFFSET ) != ie_oui_subtype              
       
   271             ) 
       
   272           )
       
   273         {
       
   274         ret = NextIE( ie, len, &data );
       
   275         }
       
   276 
       
   277     // Check if the element is corrupted
       
   278     if ( ie != ie_id )
       
   279         {
       
   280         ie_length = 0;
       
   281         *ie_data = NULL;
       
   282         return WlanScanError_IeNotFound;
       
   283         }
       
   284 
       
   285     ie_length = len;
       
   286     *ie_data = data;
       
   287     return ret;
       
   288     }
       
   289 
       
   290 // ---------------------------------------------------------------------------
       
   291 // ---------------------------------------------------------------------------
       
   292 //
       
   293 WlanScanError ScanInfo::FirstIE( 
       
   294     u8_t& ie_id, 
       
   295     u8_t& ie_length, 
       
   296     const u8_t** ie_data )
       
   297     {
       
   298     if( !current_m )
       
   299         {
       
   300         return WlanScanError_IeNotFound;
       
   301         }
       
   302     ie_iter_m = current_m + MGMT_BODY_OFFSET;
       
   303     return CurrentIE( ie_id, ie_length, ie_data );
       
   304     }
       
   305 
       
   306 // ---------------------------------------------------------------------------
       
   307 // ---------------------------------------------------------------------------
       
   308 //
       
   309 WlanScanError ScanInfo::NextIE(
       
   310     u8_t& ie_id, 
       
   311     u8_t& ie_length, 
       
   312     const u8_t** ie_data )
       
   313     {
       
   314     if( !current_m )
       
   315         {
       
   316         return WlanScanError_IeNotFound;
       
   317         }
       
   318     ie_iter_m += *( ie_iter_m + 1 ) + 2;
       
   319     return CurrentIE( ie_id, ie_length, ie_data );
       
   320     }
       
   321 
       
   322 // ---------------------------------------------------------------------------
       
   323 // ---------------------------------------------------------------------------
       
   324 //
       
   325 WlanScanError ScanInfo::CurrentIE(
       
   326     u8_t& ie_id, 
       
   327     u8_t& ie_length, 
       
   328     const u8_t** ie_data ) const
       
   329     {
       
   330     if ( !current_m || ie_iter_m >= current_m + Size() )
       
   331         {
       
   332         ie_id = 0;
       
   333         ie_length = 0;
       
   334         *ie_data = NULL;
       
   335         return WlanScanError_IeNotFound;
       
   336         }
       
   337 
       
   338     ie_id = *ie_iter_m;
       
   339     ie_length = *( ie_iter_m+1 );
       
   340     *ie_data = ie_iter_m+2;
       
   341     return WlanScanError_Ok;
       
   342 }
       
   343 
       
   344 // ---------------------------------------------------------------------------
       
   345 // ---------------------------------------------------------------------------
       
   346 //
       
   347 bool_t ScanInfo::IsProtectedSetupSupported()
       
   348     {
       
   349     u8_t ie_length = 0;
       
   350     const u8_t* ie_data = NULL;
       
   351     const WlanIeOui ie_oui = { SCAN_WSC_OUI[0], SCAN_WSC_OUI[1], SCAN_WSC_OUI[2] };
       
   352     const u8_t ie_oui_type = SCAN_WSC_OUI[3];
       
   353     
       
   354     WlanScanError err = InformationElement( WPA_IE_ID,
       
   355                                             ie_oui, ie_oui_type,
       
   356                                             ie_length, &ie_data );
       
   357     
       
   358     if (err == WlanScanError_IeNotFound
       
   359         || ie_data == NULL 
       
   360         || ie_length == 0 )
       
   361         {
       
   362         return false_t;
       
   363         }
       
   364     
       
   365     // WSC IE is found, next check whether AP setup is locked (locked state would prevent use of Protected Setup)
       
   366     return !IsApSetupLocked( ie_data, ie_length );
       
   367     }
       
   368 
       
   369 
       
   370 // ---------------------------------------------------------------------------
       
   371 // ---------------------------------------------------------------------------
       
   372 bool_t ScanInfo::IsApSetupLocked(
       
   373     const u8_t* ie_data,
       
   374     const u8_t ie_length ) const
       
   375     {
       
   376     u16_t index( SCAN_WSC_IE_PROTECTED_SETUP_DATA_OFFSET );
       
   377     
       
   378     while ( (index + SCAN_WSC_IE_DATA_LENGTH_OFFSET + 1) < ie_length)
       
   379         {
       
   380         // Make big endian to little endian conversion.
       
   381         u16_t attribute_type = (ie_data[index]<<8) 
       
   382                              | (ie_data[index+1]);
       
   383         
       
   384         u16_t attribute_data_length = (ie_data[index + SCAN_WSC_IE_DATA_LENGTH_OFFSET]<<8) 
       
   385                                     | (ie_data[index + SCAN_WSC_IE_DATA_LENGTH_OFFSET+1]);
       
   386         
       
   387         // Check if all attribute data does not fit current IE.
       
   388         if ( ( index + attribute_data_length + SCAN_WSC_IE_DATA_AREA_OFFSET ) > ie_length)
       
   389             {
       
   390             // attribute does not fit current IE
       
   391             return false_t;
       
   392             }
       
   393             
       
   394         if (attribute_type == SCAN_WSC_IE_AP_SETUP_LOCKED)
       
   395             {
       
   396             // AP setup locked attribute found, return its value.
       
   397             return ie_data[index + SCAN_WSC_IE_DATA_AREA_OFFSET];
       
   398             }
       
   399         
       
   400         // update index to start of next attribute
       
   401         index += SCAN_WSC_IE_DATA_AREA_OFFSET + attribute_data_length;
       
   402         }
       
   403     // 
       
   404     return false_t;
       
   405     }