wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_tools_parser.cpp
changeset 0 c40eb8fe8501
child 16 5fb7af913dfd
equal deleted inserted replaced
-1:000000000000 0:c40eb8fe8501
       
     1 /*
       
     2 * Copyright (c) 2005-2009 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:  Simple parser functions for core
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 35 %
       
    20 */
       
    21 
       
    22 #include "core_tools_parser.h"
       
    23 #include "core_tools.h"
       
    24 #include "core_frame_beacon.h"
       
    25 #include "core_frame_dot11.h"
       
    26 #include "core_frame_wmm_ie.h"
       
    27 #include "core_frame_wmm_ie_tspec.h"
       
    28 #include "core_frame_qbss_load_ie.h"
       
    29 #include "am_debug.h"
       
    30 
       
    31 // ======== MEMBER FUNCTIONS ========
       
    32 
       
    33 // ---------------------------------------------------------------------------
       
    34 // ---------------------------------------------------------------------------
       
    35 //
       
    36 core_connect_status_e core_tools_parser_c::is_ap_compatible_with_iap(
       
    37     abs_core_wpx_adaptation_c& wpx_adaptation,
       
    38     core_ap_data_c& ap_data,
       
    39     core_iap_data_c& iap_data,
       
    40     core_settings_c& core_settings,
       
    41     bool_t is_cm_active,
       
    42     bool_t ignore_channels )
       
    43     {
       
    44     const core_mac_address_s mac = ap_data.bssid();
       
    45 
       
    46     DEBUG6( "core_tools_parser_c::is_ap_compatible_with_iap() - BSSID %02X:%02X:%02X:%02X:%02X:%02X",
       
    47         mac.addr[0], mac.addr[1], mac.addr[2],
       
    48         mac.addr[3], mac.addr[4], mac.addr[5] );
       
    49 
       
    50     if ( iap_data.operating_mode() == core_operating_mode_infrastructure &&
       
    51          !ap_data.is_infra() )
       
    52         {
       
    53         DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - IAP is infrastructure, AP is IBSS" );
       
    54         return core_connect_mode_infra_required_but_ibss_found;
       
    55         }
       
    56     else if ( iap_data.operating_mode() == core_operating_mode_ibss &&
       
    57               ap_data.is_infra() )
       
    58         {
       
    59         DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - IAP is IBSS, AP is infrastructure" );
       
    60         return core_connect_mode_ibss_required_but_infra_found;
       
    61         }
       
    62 
       
    63     if ( !core_settings.is_permanent_whitelist_empty() ||
       
    64          !iap_data.is_iap_whitelist_empty() )
       
    65         {
       
    66         if ( !core_settings.is_mac_in_permanent_whitelist(mac ) &&
       
    67              !iap_data.is_mac_in_iap_whitelist( mac ) )
       
    68             {
       
    69             DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - whitelist defined, not in list" );
       
    70             return core_connect_ap_not_whitelisted;
       
    71             }
       
    72         }
       
    73 
       
    74     if ( core_settings.is_mac_in_permanent_blacklist( mac ) ||
       
    75          iap_data.is_mac_in_iap_blacklist( mac ) )
       
    76         {
       
    77         DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - blacklisted" );
       
    78         return core_connect_ap_permanently_blacklisted;
       
    79         }
       
    80 
       
    81     if ( !ignore_channels )
       
    82     	{
       
    83         if ( !core_settings.is_valid_channel(
       
    84             ap_data.band(), ap_data.channel() ) )
       
    85             {
       
    86             DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - invalid channel" );
       
    87             return core_connect_ap_outside_defined_region;
       
    88             }
       
    89     	}
       
    90 
       
    91     core_connect_status_e wpx_reason( core_connect_ok );
       
    92 
       
    93     switch ( iap_data.security_mode() )
       
    94         {
       
    95         case core_security_mode_allow_unsecure:
       
    96             /**
       
    97              * Check WPX requirements.
       
    98              */
       
    99             if ( !wpx_adaptation.is_ap_wpx_compatible_with_iap(
       
   100                 wpx_reason,
       
   101                 ap_data,
       
   102                 iap_data ) )
       
   103                 {
       
   104                 return wpx_reason;
       
   105                 }
       
   106 
       
   107             /**
       
   108              * The only requirement in this mode is that the AP doesn't have privacy enabled.
       
   109              */
       
   110             if ( ap_data.is_privacy_enabled() )
       
   111                 {
       
   112                 DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - AP has privacy enabled" );
       
   113                 return core_connect_iap_open_but_ap_requires_encryption;
       
   114                 }
       
   115 
       
   116             break;
       
   117         case core_security_mode_wep:
       
   118             /**
       
   119              * Check WPX requirements.
       
   120              */
       
   121             if ( !wpx_adaptation.is_ap_wpx_compatible_with_iap(
       
   122                 wpx_reason,
       
   123                 ap_data,
       
   124                 iap_data ) )
       
   125                 {
       
   126                 return wpx_reason;
       
   127                 }
       
   128 
       
   129             /**
       
   130              * Privacy has to be enabled.
       
   131              */
       
   132             if ( !ap_data.is_privacy_enabled() )
       
   133                 {
       
   134                 DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - AP doesn't have privacy enabled" );
       
   135                 return core_connect_iap_wep_but_ap_has_no_privacy;
       
   136                 }
       
   137 
       
   138             /**
       
   139              * If WPA IE or RSN IE is present, static WEP is not supported.
       
   140              */
       
   141             if ( ap_data.is_wpa_ie_present() ||
       
   142                  ap_data.is_rsn_ie_present() )
       
   143                 {
       
   144                 DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - AP has WPA/RSN IE present" );
       
   145                 return core_connect_iap_wep_but_ap_has_wpa_ie;
       
   146                 }
       
   147 
       
   148             break;
       
   149         case core_security_mode_802dot1x:
       
   150             /**
       
   151              * Check WPX requirements.
       
   152              */
       
   153             if ( !wpx_adaptation.is_ap_wpx_compatible_with_iap(
       
   154                 wpx_reason,
       
   155                 ap_data,
       
   156                 iap_data ) )
       
   157                 {
       
   158                 return wpx_reason;
       
   159                 }
       
   160 
       
   161             /**
       
   162              * If WPA IE or RSN IE is present, we must check that AP supports EAP or WPX fast-roam.
       
   163              */
       
   164             if ( ap_data.is_wpa_ie_present() ||
       
   165                  ap_data.is_rsn_ie_present() )
       
   166                 {
       
   167                 u32_t key_management = ap_data.key_management_suites() &
       
   168                     ( core_key_management_eap | core_key_management_wpx_fast_roam );
       
   169                 if ( !key_management )
       
   170                     {
       
   171                     DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - no EAP as key management" );
       
   172                     return core_connect_wpa_eap_required_but_ap_has_no_support;
       
   173                     }
       
   174                 }
       
   175 
       
   176             break;
       
   177         case core_security_mode_wpa:
       
   178             {
       
   179             /**
       
   180              * Check WPX requirements.
       
   181              */
       
   182             if ( !wpx_adaptation.is_ap_wpx_compatible_with_iap(
       
   183                 wpx_reason,
       
   184                 ap_data,
       
   185                 iap_data ) )
       
   186                 {
       
   187                 return wpx_reason;
       
   188                 }
       
   189 
       
   190             /**
       
   191              * In this mode WPA IE or RSN IE must be present and we must have valid
       
   192              * ciphers (TKIP or CCMP) and a valid key management suite (EAP or PSK).
       
   193              * Privacy is required.
       
   194              */
       
   195             if ( !ap_data.is_privacy_enabled() )
       
   196                 {
       
   197                 DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - AP doesn't have privacy enabled" );
       
   198                 return core_connect_iap_wpa_but_ap_has_no_privacy;
       
   199                 }
       
   200 
       
   201             if ( !ap_data.is_wpa_ie_present() &&
       
   202                  !ap_data.is_rsn_ie_present() )
       
   203                 {
       
   204                 DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - no WPA IE or RSN IE present" );
       
   205                 return core_connect_wpa_ie_required_but_ap_has_none;
       
   206                 }
       
   207 
       
   208             if ( iap_data.is_psk_used() )
       
   209                 {
       
   210                 u32_t key_management = ap_data.key_management_suites() &
       
   211                     core_key_management_preshared;
       
   212                 if ( !key_management )
       
   213                     {
       
   214                     DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - no PSK as key management" );
       
   215                     return core_connect_wpa_psk_required_but_ap_has_no_support;
       
   216                     }
       
   217                 }
       
   218             else
       
   219                 {
       
   220                 u32_t key_management = ap_data.key_management_suites() &
       
   221                     core_key_management_eap;
       
   222                 if ( !key_management )
       
   223                     {
       
   224                     DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - no EAP as key management" );
       
   225                     return core_connect_wpa_eap_required_but_ap_has_no_support;
       
   226                     }
       
   227                 }
       
   228 
       
   229             u32_t pairwise_ciphers = ap_data.pairwise_ciphers() &
       
   230                 ( core_cipher_suite_tkip | core_cipher_suite_ccmp );
       
   231             u32_t group_cipher = ap_data.group_cipher() &
       
   232                 ( core_cipher_suite_tkip | core_cipher_suite_ccmp );
       
   233             if ( !pairwise_ciphers ||
       
   234                  !group_cipher )
       
   235                 {
       
   236                 DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - no valid ciphers" );
       
   237                 return core_connect_wpa_ap_has_no_valid_ciphers;
       
   238                 }
       
   239 
       
   240             if ( is_cm_active &&
       
   241                  ( ap_data.best_pairwise_cipher() == core_cipher_suite_tkip ||
       
   242                    ap_data.best_group_cipher() == core_cipher_suite_tkip ) )
       
   243                 {
       
   244                 DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - WPA counter measures active" );
       
   245                 return core_connect_wpa_counter_measures_active;
       
   246                 }
       
   247 
       
   248             break;
       
   249             }
       
   250         case core_security_mode_wpa2only:
       
   251             {
       
   252             /**
       
   253              * Check WPX requirements.
       
   254              */
       
   255             if ( !wpx_adaptation.is_ap_wpx_compatible_with_iap(
       
   256                 wpx_reason,
       
   257                 ap_data,
       
   258                 iap_data ) )
       
   259                 {
       
   260                 return wpx_reason;
       
   261                 }
       
   262 
       
   263             /**
       
   264              * RSN IE, CCMP cipher and valid key management suite (EAP or PSK) are required in
       
   265              * this mode. Privacy is required.
       
   266              */
       
   267             if ( !ap_data.is_privacy_enabled() )
       
   268                 {
       
   269                 DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - AP doesn't have privacy enabled" );
       
   270                 return core_connect_iap_wpa_but_ap_has_no_privacy;
       
   271                 }
       
   272 
       
   273             if ( !ap_data.is_rsn_ie_present() )
       
   274                 {
       
   275                 DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - no RSN IE present" );
       
   276                 return core_connect_wpa_ie_required_but_ap_has_none;
       
   277                 }
       
   278 
       
   279             if ( iap_data.is_psk_used() )
       
   280                 {
       
   281                 u32_t key_management = ap_data.key_management_suites() &
       
   282                     core_key_management_preshared;
       
   283                 if ( !key_management )
       
   284                     {
       
   285                     DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - no PSK as key management" );
       
   286                     return core_connect_wpa_psk_required_but_ap_has_no_support;
       
   287                     }
       
   288                 }
       
   289             else
       
   290                 {
       
   291                 u32_t key_management = ap_data.key_management_suites() &
       
   292                     core_key_management_eap;
       
   293                 if ( !key_management )
       
   294                     {
       
   295                     DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - no EAP as key management" );
       
   296                     return core_connect_wpa_eap_required_but_ap_has_no_support;
       
   297                     }
       
   298                 }
       
   299 
       
   300             u32_t pairwise_ciphers = ap_data.pairwise_ciphers() &
       
   301                 core_cipher_suite_ccmp;
       
   302             u32_t group_cipher = ap_data.group_cipher() &
       
   303                 core_cipher_suite_ccmp;
       
   304             if ( !pairwise_ciphers ||
       
   305                  !group_cipher )
       
   306                 {
       
   307                 DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - CCMP not supported" );
       
   308                 return core_connect_wpa_ap_has_no_valid_ciphers;
       
   309                 }
       
   310 
       
   311             break;
       
   312             }
       
   313         case core_security_mode_wapi:
       
   314             {
       
   315             /**
       
   316              * Check WPX requirements.
       
   317              */
       
   318             if ( !wpx_adaptation.is_ap_wpx_compatible_with_iap(
       
   319                 wpx_reason,
       
   320                 ap_data,
       
   321                 iap_data ) )
       
   322                 {
       
   323                 return wpx_reason;
       
   324                 }
       
   325 
       
   326             /**
       
   327              * In this mode WAPI IE must be present and we must have valid ciphers
       
   328              * and a valid key management suite. Privacy is required.
       
   329              */
       
   330             if ( !ap_data.is_privacy_enabled() )
       
   331                 {
       
   332                 DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - AP doesn't have privacy enabled" );
       
   333                 return core_connect_iap_wapi_but_ap_has_no_privacy;
       
   334                 }
       
   335 
       
   336             if ( !ap_data.is_wapi_ie_present() )
       
   337                 {
       
   338                 DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - no WAPI IE present" );
       
   339                 return core_connect_wapi_ie_required_but_ap_has_none;
       
   340                 }
       
   341 
       
   342             if ( iap_data.is_psk_used() )
       
   343                 {
       
   344                 u32_t key_management = ap_data.key_management_suites() &
       
   345                     core_key_management_wapi_psk;
       
   346                 if ( !key_management )
       
   347                     {
       
   348                     DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - no WAPI PSK as key management" );
       
   349                     return core_connect_wapi_psk_required_but_ap_has_no_support;
       
   350                     }
       
   351                 }
       
   352             else
       
   353                 {
       
   354                 u32_t key_management = ap_data.key_management_suites() &
       
   355                     core_key_management_wapi_certificate;
       
   356                 if ( !key_management )
       
   357                     {
       
   358                     DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - no WAPI certificate as key management" );
       
   359                     return core_connect_wapi_certificate_required_but_ap_has_no_support;
       
   360                     }
       
   361                 }
       
   362 
       
   363             u32_t pairwise_ciphers = ap_data.pairwise_ciphers() &
       
   364                 core_cipher_suite_wpi;
       
   365             u32_t group_cipher = ap_data.group_cipher() &
       
   366                 core_cipher_suite_wpi;
       
   367             if ( !pairwise_ciphers ||
       
   368                  !group_cipher )
       
   369                 {
       
   370                 DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - no valid ciphers" );
       
   371                 return core_connect_wapi_ap_has_no_valid_ciphers;
       
   372                 }
       
   373 
       
   374             break;
       
   375             }
       
   376         }
       
   377 
       
   378     DEBUG( "core_tools_parser_c::is_ap_compatible_with_iap() - OK" );
       
   379     return core_connect_ok;
       
   380     }
       
   381 
       
   382 // ---------------------------------------------------------------------------
       
   383 // ---------------------------------------------------------------------------
       
   384 //
       
   385 core_connect_status_e core_tools_parser_c::is_ap_suitable(
       
   386     abs_core_wpx_adaptation_c& wpx_adaptation,
       
   387     core_ap_data_c& ap_data,
       
   388     core_iap_data_c& iap_data,
       
   389     core_settings_c& core_settings,
       
   390     core_connection_data_c& connection_data,
       
   391     u8_t min_rcpi,
       
   392     const medium_time_s& min_medium_time,
       
   393     bool_t is_cm_active,
       
   394     const core_mac_address_s& current_bssid )
       
   395     {
       
   396     const core_mac_address_s bssid(
       
   397         ap_data.bssid() );
       
   398 
       
   399     if ( current_bssid == bssid )
       
   400         {
       
   401         DEBUG( "core_tools_parser_c::is_ap_suitable() - currently connected to this AP" );
       
   402         return core_connect_unspecified_failure;
       
   403         }
       
   404 
       
   405     if ( connection_data.is_mac_in_temporary_blacklist( bssid ) )
       
   406         {
       
   407         DEBUG( "core_tools_parser_c::is_ap_suitable() - AP is temporarily blacklisted" );
       
   408         return core_connect_ap_temporarily_blacklisted;
       
   409         }
       
   410 
       
   411     core_connect_status_e ret = core_tools_parser_c::is_ap_compatible_with_iap(
       
   412         wpx_adaptation,
       
   413         ap_data,
       
   414         iap_data,
       
   415         core_settings,
       
   416         is_cm_active );
       
   417     if ( ret != core_connect_ok )
       
   418         {
       
   419         DEBUG( "core_tools_parser_c::is_ap_suitable() - IAP doesn't match the AP" );
       
   420         return ret;
       
   421         }
       
   422 
       
   423     if ( min_rcpi != RCPI_VALUE_NONE &&
       
   424          ap_data.rcpi() < min_rcpi )
       
   425         {
       
   426         DEBUG2( "core_tools_parser_c::is_ap_suitable() - signal too weak (RCPI is %u, required RCPI is %u)",
       
   427             ap_data.rcpi(), min_rcpi );
       
   428         return core_connect_ap_signal_too_weak;
       
   429         }
       
   430 
       
   431     bool_t is_ac_required_for_voice =
       
   432         connection_data.traffic_stream_list().is_traffic_stream_for_access_class( core_access_class_voice );
       
   433     bool_t is_ac_required_for_video =
       
   434         connection_data.traffic_stream_list().is_traffic_stream_for_access_class( core_access_class_video );
       
   435     bool_t is_ac_required_for_best_effort =
       
   436         connection_data.traffic_stream_list().is_traffic_stream_for_access_class( core_access_class_best_effort );
       
   437     bool_t is_ac_required_for_background =
       
   438         connection_data.traffic_stream_list().is_traffic_stream_for_access_class( core_access_class_background );
       
   439 
       
   440     if ( min_medium_time != MEDIUM_TIME_NOT_DEFINED )
       
   441         {
       
   442         ASSERT( is_ac_required_for_voice ||
       
   443             is_ac_required_for_video ||
       
   444             is_ac_required_for_best_effort ||
       
   445             is_ac_required_for_background );
       
   446 
       
   447         if ( !ap_data.is_wmm_ie_present() )
       
   448             {
       
   449             DEBUG( "core_tools_parser_c::is_ap_suitable() - AP doesn't have a WMM IE" );
       
   450             return core_connect_ap_has_no_admission_control;
       
   451             }
       
   452 
       
   453         if ( is_ac_required_for_voice &&
       
   454              !ap_data.is_admission_control_required( core_access_class_voice ) )
       
   455             {
       
   456             DEBUG( "core_tools_parser_c::is_ap_suitable() - AP doesn't require admission control for Voice" );
       
   457             return core_connect_ap_has_no_admission_control;
       
   458             }
       
   459 
       
   460         if ( is_ac_required_for_video &&
       
   461              !ap_data.is_admission_control_required( core_access_class_video ) )
       
   462             {
       
   463             DEBUG( "core_tools_parser_c::is_ap_suitable() - AP doesn't require admission control for Video" );
       
   464             return core_connect_ap_has_no_admission_control;
       
   465             }
       
   466 
       
   467         if ( is_ac_required_for_best_effort &&
       
   468              !ap_data.is_admission_control_required( core_access_class_best_effort ) )
       
   469             {
       
   470             DEBUG( "core_tools_parser_c::is_ap_suitable() - AP doesn't require admission control for Background" );
       
   471             return core_connect_ap_has_no_admission_control;
       
   472             }
       
   473 
       
   474         if ( is_ac_required_for_background &&
       
   475              !ap_data.is_admission_control_required( core_access_class_background ) )
       
   476             {
       
   477             DEBUG( "core_tools_parser_c::is_ap_suitable() - AP doesn't require admission control for BestEffort" );
       
   478             return core_connect_ap_has_no_admission_control;
       
   479             }
       
   480 
       
   481         bool_t is_adm_capacity_found( false_t );
       
   482         medium_time_s admission_capacities(
       
   483             ADMISSION_CAPACITIES_NOT_DEFINED );
       
   484         ap_data.admission_capacity( admission_capacities );
       
   485 
       
   486         /**
       
   487          * Check required medium time by user priority.
       
   488          */
       
   489         for( u8_t idx( 0 ); idx < MAX_QOS_USER_PRIORITY; ++idx )
       
   490             {
       
   491             if( min_medium_time.up[idx] )
       
   492                 {
       
   493                 if( admission_capacities.up[idx] < min_medium_time.up[idx] )
       
   494                     {
       
   495                     DEBUG3( "core_tools_parser_c::is_ap_suitable() - not enough admission capacity for UP %u: %u, required %u",
       
   496                         idx, admission_capacities.up[idx], min_medium_time.up[idx] );
       
   497 
       
   498                     return core_connect_ap_has_no_free_admission_capability;
       
   499                     }
       
   500                 else if( admission_capacities.up[idx] != ADMISSION_CAPACITY_NOT_DEFINED )
       
   501                     {
       
   502                     DEBUG3( "core_tools_parser_c::is_ap_suitable() - admission capacity for UP %u: %u, required %u",
       
   503                         idx, admission_capacities.up[idx], min_medium_time.up[idx] );
       
   504 
       
   505                     is_adm_capacity_found = true_t;
       
   506                     }
       
   507                 else
       
   508                     {
       
   509                     DEBUG1( "core_tools_parser_c::is_ap_suitable() - no admission capacity advertised for UP %u",
       
   510                         idx );
       
   511                     }
       
   512                 }
       
   513             }
       
   514 
       
   515         /**
       
   516          * Check required medium time by access class.
       
   517          */
       
   518         u16_t total_min_medium_time( 0 );
       
   519         for( u8_t idx( 0 ); idx < MAX_QOS_ACCESS_CLASS; ++idx )
       
   520             {           
       
   521             if( min_medium_time.ac[idx] )
       
   522                 {
       
   523                 total_min_medium_time += min_medium_time.ac[idx];
       
   524 
       
   525                 if( admission_capacities.ac[idx] < min_medium_time.ac[idx] )
       
   526                     {
       
   527                     DEBUG3( "core_tools_parser_c::is_ap_suitable() - not enough admission capacity for AC %u: %u, required %u",
       
   528                         idx, admission_capacities.ac[idx], min_medium_time.ac[idx] );
       
   529 
       
   530                     return core_connect_ap_has_no_free_admission_capability;
       
   531                     }
       
   532                 else if( admission_capacities.ac[idx] != ADMISSION_CAPACITY_NOT_DEFINED )
       
   533                     {
       
   534                     DEBUG3( "core_tools_parser_c::is_ap_suitable() - admission capacity for AC %u: %u, required %u",
       
   535                         idx, admission_capacities.ac[idx], min_medium_time.ac[idx] );
       
   536 
       
   537                     is_adm_capacity_found = true_t;
       
   538                     }
       
   539                 else
       
   540                     {
       
   541                     DEBUG1( "core_tools_parser_c::is_ap_suitable() - no admission capacity advertised for AC %u",
       
   542                         idx );
       
   543                     }
       
   544                 }
       
   545             }
       
   546 
       
   547         if( !is_adm_capacity_found )            
       
   548             {
       
   549             const core_frame_qbss_load_ie_c* qbss_load_ie = ap_data.qbss_load_ie();
       
   550             if ( qbss_load_ie &&
       
   551                  qbss_load_ie->admission_capacity() < total_min_medium_time )
       
   552                 {
       
   553                 is_adm_capacity_found = true_t;
       
   554                 
       
   555                 DEBUG2( "core_tools_parser_c::is_ap_suitable() - not enough admission capacity (%u, required %u)",
       
   556                     qbss_load_ie->admission_capacity(), total_min_medium_time );
       
   557                 delete qbss_load_ie;
       
   558 
       
   559                 return core_connect_ap_has_no_free_admission_capability;
       
   560                 }
       
   561 
       
   562             delete qbss_load_ie;
       
   563             qbss_load_ie = NULL;
       
   564             }
       
   565 
       
   566         /**
       
   567          * If the AP doesn't advertise any admission capacity information,
       
   568          * we'll assume there's enough capacity.
       
   569          */
       
   570         if( !is_adm_capacity_found )
       
   571             {
       
   572             DEBUG( "core_tools_parser_c::is_ap_suitable() - AP doesn't advertise any admission capacity information" );
       
   573             }
       
   574         }
       
   575 
       
   576     DEBUG( "core_tools_parser_c::is_ap_suitable() - AP is suitable" );
       
   577     return core_connect_ok;
       
   578     }
       
   579 
       
   580 // ---------------------------------------------------------------------------
       
   581 // ---------------------------------------------------------------------------
       
   582 //
       
   583 core_ap_information_s core_tools_parser_c::get_ap_info(
       
   584     const core_iap_data_c& iap_data,
       
   585     core_ap_data_c& ap_data )
       
   586     {
       
   587     core_ap_information_s info;
       
   588     core_tools_c::fillz(
       
   589         &info,
       
   590         sizeof( info ) );
       
   591 
       
   592     info.ssid = ap_data.ssid();
       
   593     info.bssid = ap_data.bssid();
       
   594     info.capabilities = ap_data.capabilities();
       
   595     info.channel = ap_data.channel();
       
   596     info.rcpi = ap_data.rcpi();
       
   597     info.security_mode = core_tools_c::security_mode(
       
   598         iap_data,
       
   599         ap_data );
       
   600 
       
   601     /**
       
   602      * Parse basic and supported rates to own bitmaps.
       
   603      */
       
   604     info.basic_rates = 0;
       
   605     info.supported_rates = 0;
       
   606     for( core_frame_dot11_ie_c* ie = ap_data.frame()->first_ie(); ie; ie = ap_data.frame()->next_ie() )
       
   607         {
       
   608         if ( ie->element_id() == core_frame_dot11_ie_c::core_frame_dot11_ie_element_id_supported_rates ||
       
   609              ie->element_id() == core_frame_dot11_ie_c::core_frame_dot11_ie_element_id_extended_rates )
       
   610             {
       
   611             u32_t temp_basic_rates( 0 );
       
   612             u32_t temp_supported_rates( 0 );
       
   613 
       
   614             core_tools_parser_c::parse_rates(
       
   615                 ie->data() + CORE_FRAME_DOT11_IE_HEADER_LENGTH,
       
   616                 ie->length(),
       
   617                 temp_basic_rates,
       
   618                 temp_supported_rates );
       
   619 
       
   620             info.basic_rates |= temp_basic_rates;
       
   621             info.supported_rates |= temp_supported_rates;
       
   622             }
       
   623 
       
   624         delete ie;
       
   625         }
       
   626     info.is_ac_required_for_voice =
       
   627         ap_data.is_admission_control_required( core_access_class_voice );
       
   628     info.is_ac_required_for_video =
       
   629         ap_data.is_admission_control_required( core_access_class_video );
       
   630     info.is_ac_required_for_best_effort =
       
   631         ap_data.is_admission_control_required( core_access_class_best_effort );
       
   632     info.is_ac_required_for_background =
       
   633         ap_data.is_admission_control_required( core_access_class_background );
       
   634     info.is_wpx = ap_data.is_wpx();
       
   635 
       
   636     return info;
       
   637     }
       
   638 
       
   639 // ---------------------------------------------------------------------------
       
   640 // ---------------------------------------------------------------------------
       
   641 //
       
   642 bool_t core_tools_parser_c::get_wmm_traffic_stream_params(
       
   643     core_frame_dot11_c& frame,
       
   644     u8_t tid,
       
   645     core_traffic_stream_params_s& tspec )
       
   646     {
       
   647     for( core_frame_dot11_ie_c* ie = frame.first_ie(); ie; ie = frame.next_ie() )
       
   648         {
       
   649         if ( ie->element_id() == core_frame_dot11_ie_c::core_frame_dot11_ie_element_id_wmm_tspec )
       
   650             {
       
   651             core_frame_wmm_ie_tspec_c* tspec_ie = core_frame_wmm_ie_tspec_c::instance( *ie );
       
   652             if ( tspec_ie &&
       
   653                  tspec_ie->tid() == tid )
       
   654                 {
       
   655                 DEBUG1( "core_tools_parser_c::get_wmm_traffic_stream_params() - TSPEC with TID %u found",
       
   656                     tid );
       
   657 
       
   658                 tspec.is_periodic_traffic = tspec_ie->is_periodic_traffic();
       
   659                 tspec.direction = tspec_ie->direction();
       
   660                 tspec.nominal_msdu_size = tspec_ie->nominal_msdu_size();
       
   661                 tspec.maximum_msdu_size = tspec_ie->maximum_msdu_size();
       
   662                 tspec.minimum_service_interval = tspec_ie->minimum_service_interval();
       
   663                 tspec.maximum_service_interval = tspec_ie->maximum_service_interval();
       
   664                 tspec.inactivity_interval = tspec_ie->inactivity_interval();
       
   665                 tspec.suspension_interval = tspec_ie->suspension_interval();
       
   666                 tspec.service_start_time = tspec_ie->service_start_time();
       
   667                 tspec.minimum_data_rate = tspec_ie->minimum_data_rate();
       
   668                 tspec.mean_data_rate = tspec_ie->mean_data_rate();
       
   669                 tspec.peak_data_rate = tspec_ie->peak_data_rate();
       
   670                 tspec.maximum_burst_size = tspec_ie->maximum_burst_size();
       
   671                 tspec.delay_bound = tspec_ie->delay_bound();
       
   672                 tspec.minimum_phy_rate = tspec_ie->minimum_phy_rate();
       
   673                 tspec.surplus_bandwidth_allowance = tspec_ie->surplus_bandwidth_allowance();
       
   674                 tspec.medium_time = tspec_ie->medium_time();
       
   675 
       
   676                 delete tspec_ie;
       
   677                 tspec_ie = NULL;
       
   678 
       
   679                 delete ie;
       
   680                 ie = NULL;
       
   681 
       
   682                 return true_t;
       
   683                 }
       
   684 
       
   685             delete tspec_ie;
       
   686             tspec_ie = NULL;
       
   687             }
       
   688 
       
   689         delete ie;
       
   690         ie = NULL;
       
   691         }
       
   692 
       
   693     return false_t;
       
   694     }
       
   695 
       
   696 // ---------------------------------------------------------------------------
       
   697 // ---------------------------------------------------------------------------
       
   698 //
       
   699 void core_tools_parser_c::parse_rates(
       
   700     const u8_t* data,
       
   701     u8_t data_length,
       
   702     u32_t& basic_rates,
       
   703     u32_t& supported_rates )
       
   704     {
       
   705     DEBUG( "core_tools_parser_c::parse_rates()" );
       
   706 
       
   707     basic_rates = 0;
       
   708     supported_rates = 0;
       
   709 
       
   710     for( u8_t idx( 0 ); idx < data_length; ++idx )
       
   711         {
       
   712         core_tx_rate_e rate(
       
   713             core_tools_c::convert_tx_rate_to_tx_rate_enum(
       
   714                 data[idx] & ~TX_RATE_BASIC_MASK ) );
       
   715 
       
   716         supported_rates |= rate;
       
   717 
       
   718         if ( data[idx] & TX_RATE_BASIC_MASK )
       
   719             {
       
   720             /**
       
   721              * The highest bit is enabled, the rate is both a basic rate
       
   722              * and a supported rate.
       
   723              */
       
   724             basic_rates |= rate;
       
   725             }
       
   726         }
       
   727     }
       
   728 
       
   729 // ---------------------------------------------------------------------------
       
   730 // ---------------------------------------------------------------------------
       
   731 //
       
   732 core_tools_parser_c::core_tools_parser_c()
       
   733     {
       
   734     DEBUG( "core_tools_parser_c::core_tools_parser_c()" );
       
   735     }