wlan_bearer/wlanldd/wlan_common/umac_common/src/UmacDot11State.cpp
changeset 0 c40eb8fe8501
child 10 0abc8c98be24
equal deleted inserted replaced
-1:000000000000 0:c40eb8fe8501
       
     1 /*
       
     2 * Copyright (c) 2002-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:   Implementation of the WlanDot11State class.
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 85 %
       
    20 */
       
    21 
       
    22 #include "config.h"
       
    23 #include "UmacDot11State.h"
       
    24 #include "UmacWsaAddKey.h"
       
    25 #include "UmacWsaKeyIndexMapper.h"
       
    26 #include "umacaddbroadcastwepkey.h"
       
    27 #include "UmacWsaWriteMib.h"
       
    28 #include "UmacWsaReadMib.h"
       
    29 #include "umacwhaconfigurequeue.h"
       
    30 #include "umacwhaconfigureac.h"
       
    31 #include "umacconfiguretxautoratepolicy.h"
       
    32 #include "UmacContextImpl.h"
       
    33 #include "wha_mibDefaultvalues.h"
       
    34 #include "FrameXferBlock.h"
       
    35 #include "umacelementlocator.h"
       
    36 
       
    37 struct TRate2NwsaRate
       
    38     {
       
    39     TRate       iTrate;
       
    40     WHA::TRate  iNwsaRate;
       
    41     };
       
    42 
       
    43 const TRate2NwsaRate KTRate2NwsaRateTable[] =
       
    44     {
       
    45         { E1Mbps, WHA::KRate1Mbits },
       
    46         { E2Mbps, WHA::KRate2Mbits },
       
    47         { E5_5Mbps, WHA::KRate5_5Mbits },
       
    48         { E11Mbps, WHA::KRate11Mbits },
       
    49         { E22Mbps, WHA::KRate22Mbits },
       
    50     };
       
    51 
       
    52 class TRate2NwsaRatePredicate
       
    53     {
       
    54 public:
       
    55 
       
    56     explicit TRate2NwsaRatePredicate( const TRate aRate )
       
    57         : iKey( aRate ) {};
       
    58 
       
    59     TBool operator() ( const TRate2NwsaRate& aEntry ) const
       
    60         {
       
    61         return aEntry.iTrate == iKey;
       
    62         }
       
    63 
       
    64 private:
       
    65 
       
    66     // Prohibit copy constructor.
       
    67     TRate2NwsaRatePredicate ( const TRate2NwsaRatePredicate & );
       
    68     // Prohibit assigment operator.
       
    69     TRate2NwsaRatePredicate& operator= ( const TRate2NwsaRatePredicate & );
       
    70 
       
    71     const TRate iKey;
       
    72     };
       
    73 
       
    74 // ============================ MEMBER FUNCTIONS ===============================
       
    75 
       
    76 // -----------------------------------------------------------------------------
       
    77 // 
       
    78 // -----------------------------------------------------------------------------
       
    79 //
       
    80 TBool WlanDot11State::Scan(
       
    81     WlanContextImpl& aCtxImpl,
       
    82     TScanMode aMode,                    
       
    83     const TSSID& aSSID,                 
       
    84     TRate aScanRate, 
       
    85     SChannels& aChannels,
       
    86     TUint32 aMinChannelTime,            
       
    87     TUint32 aMaxChannelTime,
       
    88     TBool aSplitScan )
       
    89     {
       
    90 
       
    91     WHA::TRate rate( 0 );
       
    92     ResolveScanRate( aCtxImpl, aScanRate, rate );
       
    93 
       
    94     // call the "real scan"
       
    95     return RealScan( aCtxImpl, aMode, aSSID, rate, aChannels, 
       
    96         aMinChannelTime, aMaxChannelTime, aSplitScan );
       
    97     }
       
    98 
       
    99 // -----------------------------------------------------------------------------
       
   100 // 
       
   101 // -----------------------------------------------------------------------------
       
   102 //
       
   103 TBool WlanDot11State::StopScan( WlanContextImpl& aCtxImpl )
       
   104     {
       
   105     // as we are here it means that we have received a stop scan request
       
   106     // even though there is no scan ongoing. This should only happen if the
       
   107     // mgmt client has been in the process of making a stop scan request and 
       
   108     // hasn't noticed that the scan has already completed. Anyhow in this 
       
   109     // case we just complete the request
       
   110     OnOidComplete( aCtxImpl, KErrNone );
       
   111     // signal caller that no state transition occurred
       
   112     return EFalse;    
       
   113     }
       
   114 
       
   115 // -----------------------------------------------------------------------------
       
   116 // 
       
   117 // -----------------------------------------------------------------------------
       
   118 //
       
   119 TBool WlanDot11State::SetPowerMode(
       
   120     WlanContextImpl& aCtxImpl,
       
   121     TPowerMode aPowerMode,
       
   122     TBool aDisableDynamicPowerModeManagement,
       
   123     TWlanWakeUpInterval aWakeupModeInLightPs, 
       
   124     TUint8 aListenIntervalInLightPs,
       
   125     TWlanWakeUpInterval aWakeupModeInDeepPs,
       
   126     TUint8 aListenIntervalInDeepPs )
       
   127     {
       
   128     OsTracePrint( KPwrStateTransition, (TUint8*)
       
   129         ("UMAC: WlanDot11State::SetPowerMode: aPowerMode: %d"), aPowerMode );
       
   130 
       
   131     TBool ret( EFalse );
       
   132 
       
   133     // store desired new dot11 power management mode by WLAN Mgmt Client
       
   134     aCtxImpl.ClientDot11PwrMgmtMode( aPowerMode );
       
   135     
       
   136     aCtxImpl.DynamicPwrModeMgtDisabled( aDisableDynamicPowerModeManagement );
       
   137     if ( aDisableDynamicPowerModeManagement )
       
   138         {
       
   139         aCtxImpl.StopPowerModeManagement();
       
   140         }
       
   141     
       
   142     aCtxImpl.SetClientLightPsModeConfig( 
       
   143         aWakeupModeInLightPs, 
       
   144         aListenIntervalInLightPs );
       
   145 
       
   146     aCtxImpl.SetClientDeepPsModeConfig( 
       
   147             aWakeupModeInDeepPs, 
       
   148             aListenIntervalInDeepPs );
       
   149     
       
   150     // in case WLAN Mgmt Client wishes to use PS mode, Light PS is the initial
       
   151     // desired PS mode configuration
       
   152     aCtxImpl.SetDesiredPsModeConfig( 
       
   153         aCtxImpl.ClientLightPsModeConfig() );
       
   154     
       
   155     if ( aCtxImpl.CurrentDot11PwrMgmtMode() !=
       
   156          aCtxImpl.ClientDot11PwrMgmtMode() )
       
   157         {
       
   158         // there is a difference in current dot11 power management mode and 
       
   159         // WLAN Mgmt Client's desired dot11 power management mode
       
   160         
       
   161         // So, WLAN Mgmt Client's desired dot11 power management mode becomes
       
   162         // our new desired mode
       
   163         aCtxImpl.DesiredDot11PwrMgmtMode( aCtxImpl.ClientDot11PwrMgmtMode() );
       
   164 
       
   165         // callee will complete the mgmt command
       
   166         ret = OnDot11PwrMgmtTransitRequired( aCtxImpl );
       
   167         }
       
   168     else
       
   169         {
       
   170         // no dot11 power management mode transition required.
       
   171         
       
   172         // See if there is difference in desired vs. current wake-up setting,
       
   173         // which we only need to worry about if the requested pwr mgmt
       
   174         // mode is PS
       
   175         if ( aPowerMode == EPowerModePs && 
       
   176              DifferenceInPsModeWakeupSettings( aCtxImpl ) )
       
   177             {
       
   178             // callee shall complete the request
       
   179             ret = OnWlanWakeUpIntervalChange( aCtxImpl );
       
   180             }
       
   181         else
       
   182             {
       
   183             // no action required regarding the wake-up setting, either
       
   184             
       
   185             // one possibility is that the following has happened: WLAN Mgmt
       
   186             // client has requested us to use PS mode when possible, but we 
       
   187             // have dynamically changed to CAM mode because of data traffic. 
       
   188             // If that is the case and now the WLAN Mgmt client wants us
       
   189             // to stay in CAM mode, make sure that the dynamic power mode 
       
   190             // management is deactivated
       
   191             if ( aPowerMode == EPowerModeCam )
       
   192                 {
       
   193                 OsTracePrint( KPwrStateTransition, (TUint8*)
       
   194                     ("UMAC: WlanDot11State::SetPowerMode: CAM requested when we already are in CAM. Make sure that dynamic pwr mode mgmt is not active") );
       
   195                 
       
   196                 aCtxImpl.StopPowerModeManagement();                    
       
   197                 }
       
   198             else
       
   199                 {
       
   200                 if ( !aDisableDynamicPowerModeManagement )
       
   201                     {
       
   202                     // in case the only change is that now dynamic pwr
       
   203                     // mode mgmt is again allowed, make sure it is active
       
   204                     aCtxImpl.StartPowerModeManagement();
       
   205                     }
       
   206                 }
       
   207             }
       
   208         
       
   209         // complete the mgmt command
       
   210         OnOidComplete( aCtxImpl );
       
   211         }
       
   212 
       
   213     return ret;
       
   214     }
       
   215 
       
   216 // -----------------------------------------------------------------------------
       
   217 // 
       
   218 // -----------------------------------------------------------------------------
       
   219 //
       
   220 TBool WlanDot11State::EnableUserData(
       
   221     WlanContextImpl& aCtxImpl )
       
   222     {
       
   223     TBool stateChange( EFalse );
       
   224     aCtxImpl.iEnableUserData = ETrue;
       
   225     OnOidComplete( aCtxImpl, KErrNone );
       
   226     aCtxImpl.iUmac.UserDataReEnabled();
       
   227 
       
   228     // signal global state transition event
       
   229     return stateChange;
       
   230     }
       
   231 
       
   232 // -----------------------------------------------------------------------------
       
   233 // 
       
   234 // -----------------------------------------------------------------------------
       
   235 //
       
   236 TBool WlanDot11State::DisableUserData(
       
   237     WlanContextImpl& aCtxImpl )
       
   238     {
       
   239     aCtxImpl.iEnableUserData = EFalse;
       
   240     OnOidComplete( aCtxImpl, KErrNone );
       
   241     // signal caller that no state transition occurred
       
   242     return EFalse;
       
   243     }
       
   244 
       
   245 // -----------------------------------------------------------------------------
       
   246 // 
       
   247 // -----------------------------------------------------------------------------
       
   248 //
       
   249 void WlanDot11State::OnConfigureUmacMib(
       
   250     WlanContextImpl& aCtxImpl,
       
   251     TUint16 aRTSThreshold,             
       
   252     TUint32 aMaxTxMSDULifetime )        
       
   253     {
       
   254     OsTracePrint( KUmacDetails, (TUint8*)
       
   255         ("UMAC: WlanDot11State::OnConfigureUmacMib") );
       
   256     OsTracePrint( KUmacDetails, (TUint8*)
       
   257         ("UMAC: WlanDot11State::OnConfigureUmacMib: RTSThreshold: %d"), 
       
   258         aRTSThreshold );
       
   259     OsTracePrint( KUmacDetails, (TUint8*)
       
   260         ("UMAC: WlanDot11State::OnConfigureUmacMib: maxTxMSDULifetime: %d"), 
       
   261         aMaxTxMSDULifetime );
       
   262 
       
   263     aCtxImpl.iWlanMib.dot11RTSThreshold = aRTSThreshold;
       
   264     
       
   265     for ( TUint i = 0; i < WHA::EQueueIdMax; ++i )
       
   266         {
       
   267         aCtxImpl.iWlanMib.dot11MaxTransmitMSDULifetime[i] = aMaxTxMSDULifetime;
       
   268         }
       
   269 
       
   270     aCtxImpl.iWlanMib.dot11MaxTransmitMSDULifetimeDefault = aMaxTxMSDULifetime;
       
   271             
       
   272     for ( TUint i = 0; i < WHA::EQueueIdMax; ++i )
       
   273         {
       
   274         aCtxImpl.iWlanMib.iMediumTime[i] = KDot11MediumTimeDefault;
       
   275         }        
       
   276     }
       
   277 
       
   278 // -----------------------------------------------------------------------------
       
   279 // 
       
   280 // -----------------------------------------------------------------------------
       
   281 //
       
   282 void WlanDot11State::AddDefaultBroadcastWepKeyComplete( 
       
   283     WlanContextImpl& aCtxImpl ) const
       
   284     {
       
   285     OnOidComplete( aCtxImpl );
       
   286     }
       
   287 
       
   288 // -----------------------------------------------------------------------------
       
   289 // 
       
   290 // -----------------------------------------------------------------------------
       
   291 //
       
   292 void WlanDot11State::ResolveScanRate( 
       
   293     WlanContextImpl& /*aCtxImpl*/,
       
   294     const TRate aRate, 
       
   295     WHA::TRate& aScanRate )
       
   296     {
       
   297     const TRate2NwsaRatePredicate unary_predicate( aRate );
       
   298 
       
   299     const TRate2NwsaRate* const end 
       
   300         = KTRate2NwsaRateTable 
       
   301         + (sizeof(KTRate2NwsaRateTable) / sizeof(TRate2NwsaRate));
       
   302     const TRate2NwsaRate* pos 
       
   303         = find_if( KTRate2NwsaRateTable, end, unary_predicate );
       
   304 
       
   305     if ( pos == end )
       
   306         {
       
   307         // not found; an implementation error
       
   308         OsAssert( (TUint8*)("UMAC: panic"),(TUint8*)(WLAN_FILE), __LINE__ );
       
   309         }
       
   310 
       
   311     aScanRate = pos->iNwsaRate;
       
   312     }
       
   313 
       
   314 // -----------------------------------------------------------------------------
       
   315 // 
       
   316 // -----------------------------------------------------------------------------
       
   317 //
       
   318 TBool WlanDot11State::NetworkCapabilityInformationMet(
       
   319     WlanContextImpl& aCtxImpl)
       
   320     {
       
   321     if ( // do this if channel agility bit is not set    
       
   322         ( !aCtxImpl.GetCapabilityInformation().IsChannelAgilityBitSet() ))        
       
   323         {
       
   324         // mimic the preamble bit from AP
       
   325         // as some APs might not let us in if not matched
       
   326         if ( aCtxImpl.GetCapabilityInformation().IsShortPreambleBitSet() )
       
   327             {
       
   328             (aCtxImpl.GetAssociationRequestFrame())
       
   329                 .SetCapabilityShortPreamble();
       
   330             (aCtxImpl.GetHtAssociationRequestFrame())
       
   331                 .SetCapabilityShortPreamble();
       
   332             (aCtxImpl.GetReassociationRequestFrame())
       
   333                 .SetCapabilityShortPreamble();
       
   334             (aCtxImpl.GetHtReassociationRequestFrame())
       
   335                 .SetCapabilityShortPreamble();                
       
   336                 
       
   337             aCtxImpl.UseShortPreamble( ETrue );
       
   338             }
       
   339         else
       
   340             {
       
   341             (aCtxImpl.GetAssociationRequestFrame())
       
   342                 .ClearCapabilityShortPreamble();
       
   343             (aCtxImpl.GetHtAssociationRequestFrame())
       
   344                 .ClearCapabilityShortPreamble();
       
   345             (aCtxImpl.GetReassociationRequestFrame())
       
   346                 .ClearCapabilityShortPreamble();
       
   347             (aCtxImpl.GetHtReassociationRequestFrame())
       
   348                 .ClearCapabilityShortPreamble();                
       
   349 
       
   350             aCtxImpl.UseShortPreamble( EFalse );
       
   351             }
       
   352 
       
   353         // clear both CF fields as we don't support PCF
       
   354         aCtxImpl.GetAssociationRequestFrame().ClearCFfields();
       
   355         aCtxImpl.GetHtAssociationRequestFrame().ClearCFfields();
       
   356         aCtxImpl.GetReassociationRequestFrame().ClearCFfields();
       
   357         aCtxImpl.GetHtReassociationRequestFrame().ClearCFfields();
       
   358 
       
   359         // clear also all the fields we don't understand
       
   360         aCtxImpl.GetAssociationRequestFrame().ClearReservedFields();
       
   361         aCtxImpl.GetHtAssociationRequestFrame().ClearReservedFields();
       
   362         aCtxImpl.GetReassociationRequestFrame().ClearReservedFields();
       
   363         aCtxImpl.GetHtReassociationRequestFrame().ClearReservedFields();
       
   364 
       
   365         // we don't do PBCC
       
   366         aCtxImpl.GetAssociationRequestFrame().ClearCapabilityPbcc();
       
   367         aCtxImpl.GetHtAssociationRequestFrame().ClearCapabilityPbcc();
       
   368         aCtxImpl.GetReassociationRequestFrame().ClearCapabilityPbcc();
       
   369         aCtxImpl.GetHtReassociationRequestFrame().ClearCapabilityPbcc();
       
   370         
       
   371         if ( aCtxImpl.EncryptionStatus() != EEncryptionDisabled )
       
   372             {
       
   373             // privacy desired
       
   374             aCtxImpl.GetAssociationRequestFrame().SetWepBit();
       
   375             aCtxImpl.GetHtAssociationRequestFrame().SetWepBit();
       
   376             aCtxImpl.GetReassociationRequestFrame().SetWepBit();
       
   377             aCtxImpl.GetHtReassociationRequestFrame().SetWepBit();                
       
   378             }
       
   379         else
       
   380             {
       
   381             aCtxImpl.GetAssociationRequestFrame().ClearWepBit();
       
   382             aCtxImpl.GetHtAssociationRequestFrame().ClearWepBit();
       
   383             aCtxImpl.GetReassociationRequestFrame().ClearWepBit();
       
   384             aCtxImpl.GetHtReassociationRequestFrame().ClearWepBit();                
       
   385             }
       
   386         if ( aCtxImpl.RadioMeasurement() != EFalse )
       
   387             {
       
   388             // Radio measurements desired
       
   389             OsTracePrint (KInfoLevel, (TUint8 *)("UMAC: Radio measurements enabled"));
       
   390             aCtxImpl.GetAssociationRequestFrame().SetRMBit();
       
   391             aCtxImpl.GetHtAssociationRequestFrame().SetRMBit();
       
   392             aCtxImpl.GetReassociationRequestFrame().SetRMBit();
       
   393             aCtxImpl.GetHtReassociationRequestFrame().SetRMBit();                
       
   394             }
       
   395         else
       
   396             {
       
   397             OsTracePrint (KInfoLevel, (TUint8 *)("UMAC: Radio measurements disabled"));
       
   398             aCtxImpl.GetAssociationRequestFrame().ClearRMBit();
       
   399             aCtxImpl.GetHtAssociationRequestFrame().ClearRMBit();
       
   400             aCtxImpl.GetReassociationRequestFrame().ClearRMBit();
       
   401             aCtxImpl.GetHtReassociationRequestFrame().ClearRMBit();                
       
   402             }        
       
   403         return ETrue;
       
   404         }
       
   405     
       
   406     return EFalse;
       
   407     }
       
   408 
       
   409 // -----------------------------------------------------------------------------
       
   410 // 
       
   411 // -----------------------------------------------------------------------------
       
   412 //
       
   413 TBool WlanDot11State::AreSupportedRatesMet(
       
   414     WlanContextImpl& aCtxImpl, 
       
   415     TBool aCheckAlsoExtendedRates )
       
   416     {   
       
   417     OsTracePrint( KWarningLevel, 
       
   418         (TUint8*)("UMAC: WlanDot11State::AreSupportedRatesMet") );
       
   419 
       
   420     // make sure these critters are zeroed at the beginning
       
   421 
       
   422     aCtxImpl.GetMinBasicRate() = 0;
       
   423     aCtxImpl.GetMaxBasicRate() = 0;
       
   424     aCtxImpl.ClearBasicRateSet();
       
   425 
       
   426     // clear our existing supported rates IE
       
   427     aCtxImpl.GetOurSupportedRatesIE().Clear();
       
   428     // ... and our existing extended supported rates IE
       
   429     aCtxImpl.GetOurExtendedSupportedRatesIE().Clear();
       
   430 
       
   431     TUint32 tx_rates( 0 );
       
   432     TUint8 nwRate( 0 );
       
   433 
       
   434     // go through all supported rate elements in the supported rates IE 
       
   435     // ( max 8 ).
       
   436     // Remenber that basic rates are also always part of supported rates 
       
   437     // when building supported rates bitmask
       
   438     for ( TUint32 outer_idx = 0 
       
   439         // loop until element count in the IE is reached
       
   440         ; ( outer_idx != aCtxImpl.GetApSupportedRatesIE().GetElementLength() )
       
   441         // OR maximum length allowed for the IE is reached
       
   442         // NOTE! The 802.11 standard specifies that the max length of the 
       
   443         // information part of this IE is eight rates (eight bytes).
       
   444         // However at least some APs seem to put all their supported rates
       
   445         // into this element. In order to be able to associate with those
       
   446         // APs we have allocated enough space for all 802.11b/g rates in this
       
   447         // IE and hence the following constant in the loop end condition
       
   448         && outer_idx < KMaxNumberOfDot11bAndgRates
       
   449         ; ++outer_idx )
       
   450         {
       
   451         nwRate = (aCtxImpl.GetApSupportedRatesIE())[outer_idx];
       
   452         
       
   453         if ( !ProcessSingleSupportedRateElement( aCtxImpl, nwRate, tx_rates ) )
       
   454             {
       
   455             // unknown supported rates element encountered
       
   456             if ( nwRate & KBasicRateMask )
       
   457                 {
       
   458                 // it is part of BSS Basic Rate Set 
       
   459                 if ( aCtxImpl.BssMembershipFeatureSupported( nwRate ) )
       
   460                     {
       
   461                     // it is a WLAN feature which we support, 
       
   462                     // so we can continue. No action required here
       
   463                     }
       
   464                  else
       
   465                     {
       
   466                     // we can't cope with it and shall abort
       
   467 
       
   468                     OsTracePrint( KWarningLevel, (TUint8*)
       
   469                         ("UMAC: WlanDot11State::AreSupportedRatesMet: network has unsupported mandatory rate/feature -> abort") );
       
   470                     OsTracePrint( KWarningLevel, (TUint8*)
       
   471                         ("UMAC: WlanDot11State::AreSupportedRatesMet: rate: 0x%02x"), 
       
   472                         nwRate);                    
       
   473 
       
   474                     return EFalse;
       
   475                     }
       
   476                 }
       
   477             else
       
   478                 {
       
   479                 // unknown element is not part of BSS Basic Rate Set
       
   480                 // we can cope with that 
       
   481                 OsTracePrint( KWarningLevel, (TUint8*)
       
   482                     ("UMAC: WlanDot11State::AreSupportedRatesMet: init network connect") );
       
   483                 OsTracePrint( KWarningLevel, (TUint8*)
       
   484                     ("UMAC: WlanDot11State::AreSupportedRatesMet: network has unsupported supported rate -> continue") );
       
   485                 OsTracePrint( KWarningLevel, (TUint8*)
       
   486                     ("UMAC: WlanDot11State::AreSupportedRatesMet: rate: 0x%02x"), 
       
   487                     nwRate);
       
   488                 }
       
   489             }
       
   490         } // end outer for
       
   491 
       
   492     if ( aCheckAlsoExtendedRates )
       
   493         {
       
   494         // go through all supported rate elements in the extended supported 
       
   495         // rates IE ( max 255 ).
       
   496         // Remember that basic rates are also always part of supported rates 
       
   497         // when building supported rates bitmask
       
   498         for ( TUint32 outer_idx = 0; 
       
   499               // loop until max element count in the IE is reached
       
   500               ( outer_idx != aCtxImpl.GetApExtendedSupportedRatesIE().GetElementLength() )
       
   501               // OR maximum length allowed for the IE is reached
       
   502               && outer_idx < KMaxNumberOfExtendedRates; 
       
   503               ++outer_idx )
       
   504             {
       
   505             nwRate = (aCtxImpl.GetApExtendedSupportedRatesIE())[outer_idx];        
       
   506 
       
   507             if ( !ProcessSingleSupportedRateElement( 
       
   508                     aCtxImpl, 
       
   509                     nwRate, 
       
   510                     tx_rates ) )
       
   511                 {
       
   512                 // unknown supported rates element encountered
       
   513                 
       
   514                 if ( nwRate & KBasicRateMask )
       
   515                     {
       
   516                     // it is part of BSS Basic Rate Set 
       
   517                     
       
   518                     if ( aCtxImpl.BssMembershipFeatureSupported( nwRate ) )
       
   519                         {
       
   520                         // it is a WLAN feature which we support, 
       
   521                         // so we can continue. No action required here
       
   522                         }
       
   523                      else
       
   524                         {
       
   525                         // we can't cope with it and shall abort
       
   526 
       
   527                         OsTracePrint( KWarningLevel, (TUint8*)
       
   528                             ("UMAC: WlanDot11State::AreSupportedRatesMet: network has unsupported mandatory rate/feature -> abort") );
       
   529                         OsTracePrint( KWarningLevel, (TUint8*)
       
   530                             ("UMAC: WlanDot11State::AreSupportedRatesMet: rate: 0x%02x"), 
       
   531                             nwRate);                    
       
   532 
       
   533                         return EFalse;
       
   534                         }
       
   535                     }
       
   536                 else
       
   537                     {
       
   538                     // unknown element is not part of BSS Basic Rate Set
       
   539                     // we can cope with that 
       
   540                     OsTracePrint( KWarningLevel, (TUint8*)
       
   541                         ("UMAC: WlanDot11State::AreSupportedRatesMet: init network connect") );
       
   542                     OsTracePrint( KWarningLevel, (TUint8*)
       
   543                         ("UMAC: WlanDot11State::AreSupportedRatesMet: network has unsupported supported rate -> continue") );
       
   544                     OsTracePrint( KWarningLevel, (TUint8*)
       
   545                         ("UMAC: WlanDot11State::AreSupportedRatesMet: rate: 0x%02x"), 
       
   546                         nwRate);
       
   547                     }
       
   548                 }
       
   549             } // for
       
   550         } // if
       
   551 
       
   552     if ( tx_rates )
       
   553         {
       
   554         // store common rates (between us & the nw) in our connection context
       
   555         aCtxImpl.RateBitMask( tx_rates );
       
   556     
       
   557         return ETrue;
       
   558         }
       
   559     else
       
   560         {
       
   561         // we ended up with an empty rate mask, i.e. the intersection
       
   562         // of network's supported rates and our supported rates is empty.
       
   563         // We are not able to join the network under these circumstances 
       
   564         return EFalse;
       
   565         }
       
   566     }
       
   567 
       
   568 // -----------------------------------------------------------------------------
       
   569 // 
       
   570 // -----------------------------------------------------------------------------
       
   571 //
       
   572 TBool WlanDot11State::ProcessSingleSupportedRateElement(
       
   573     WlanContextImpl& aCtxImpl,
       
   574     const TUint8 aApRate,
       
   575     TUint32& aRateBitmask )
       
   576     {
       
   577     OsTracePrint( KUmacDetails, 
       
   578         (TUint8*)("UMAC: WlanDot11State::ProcessSingleSupportedRateElement: processing AP rate: 0x%02x"), aApRate);
       
   579 
       
   580     // match 4 elements in our rates lookup table
       
   581     const TUint num_of_elems = 
       
   582         sizeof(aCtxImpl.iSupportedRatesLookUpTable) 
       
   583         / sizeof(WlanContextImpl::SupportedRateLookUp);
       
   584 
       
   585     for ( TUint32 inner_idx = 0; 
       
   586           inner_idx != ( num_of_elems + 1 ); 
       
   587           ++inner_idx )
       
   588         {
       
   589         if ( inner_idx == num_of_elems)
       
   590             {
       
   591             // if this block is reached it means that we have encountered
       
   592             // a supported rates element that is not in our lookup table
       
   593             OsTracePrint( KWarningLevel | KUmacDetails , (TUint8*)
       
   594                 ("UMAC: unknown AP rate element found: 0x%02x"), aApRate);
       
   595 
       
   596             return EFalse;
       
   597             }
       
   598         if ( ( aApRate & (~KBasicRateMask) ) == 
       
   599              ( aCtxImpl.iSupportedRatesLookUpTable[inner_idx].iSupportedRate & 
       
   600                ( ~KBasicRateMask ) ) )
       
   601             {
       
   602             // make a rate for the tx rate adaptation object
       
   603             aRateBitmask |=  
       
   604                 (aCtxImpl.iSupportedRatesLookUpTable[inner_idx].iWsaRate);
       
   605 
       
   606             // check if this critter is part of a mandatory rate set
       
   607             if ( aApRate & KBasicRateMask )
       
   608                 {
       
   609                 OsTracePrint( KUmacDetails, 
       
   610                     (TUint8*)("UMAC: rate is part of Basic Rate Set") );
       
   611 
       
   612                 // yes it is 
       
   613                 // construct basic rate set mask for Join NWSA command
       
   614                 aCtxImpl.BasicRateSetBitSet( 
       
   615                     aCtxImpl.iSupportedRatesLookUpTable[inner_idx].iWsaRate );
       
   616 
       
   617                 // store min basic rate
       
   618                 if ( aCtxImpl.GetMinBasicRate() == 0 )
       
   619                     {
       
   620                     aCtxImpl.GetMinBasicRate() = 
       
   621                         (aCtxImpl.iSupportedRatesLookUpTable[inner_idx]).iWsaRate;
       
   622                     }
       
   623                 // and store max basic rate
       
   624                 if ( aCtxImpl.GetMaxBasicRate() < 
       
   625                     (aCtxImpl.iSupportedRatesLookUpTable[inner_idx]).iWsaRate )
       
   626                     {
       
   627                     aCtxImpl.GetMaxBasicRate() 
       
   628                         = (aCtxImpl.iSupportedRatesLookUpTable[inner_idx])
       
   629                         .iWsaRate;
       
   630                     }
       
   631                 }
       
   632 
       
   633             // set this rate to our supported rates IE 
       
   634             // which we will send in assoc-request frame. If there's no space any 
       
   635             // more in supported rates IE use the extended supported rates IE            
       
   636             //
       
   637             if (aCtxImpl.GetOurSupportedRatesIE().GetElementLength() < KMaxNumberOfRates )
       
   638                 {
       
   639                 aCtxImpl.GetOurSupportedRatesIE().Append( aApRate );                
       
   640                 }
       
   641             else
       
   642                 {                
       
   643                 aCtxImpl.GetOurExtendedSupportedRatesIE().Append( aApRate );
       
   644                 }
       
   645 
       
   646             // break out of for loop, 
       
   647             // we got a match no need to traverse any longer
       
   648             break;
       
   649             }
       
   650         } // end for
       
   651 
       
   652     return ETrue;
       
   653     }
       
   654 
       
   655 // ---------------------------------------------------------------------------
       
   656 // 
       
   657 // ---------------------------------------------------------------------------
       
   658 //
       
   659 TBool WlanDot11State::SetArpIpAddressTableMib(
       
   660     WlanContextImpl& aCtxImpl,
       
   661     TBool aEnableFiltering,
       
   662     TIpv4Address aIpv4Address )
       
   663     {
       
   664     const TUint32 KMibLength( sizeof( WHA::SarpIpAddressTable ) );
       
   665 
       
   666     OsTracePrint( KWlmCmdDetails, (TUint8*)
       
   667         ("UMAC: WlanDot11State::SetArpIpAddressTableMib: mibLength: %d"), 
       
   668         KMibLength );        
       
   669 
       
   670     // allocate memory for the mib to write
       
   671     WHA::SarpIpAddressTable* mib 
       
   672         = static_cast<WHA::SarpIpAddressTable*>
       
   673         (os_alloc( KMibLength )); 
       
   674 
       
   675     if ( !mib )
       
   676         {
       
   677         // allocation failed
       
   678         // simulate macnotresponding error
       
   679         OsTracePrint( KWarningLevel, (TUint8*)
       
   680             ("UMAC: WlanDot11State::SetArpIpAddressTableMib: memory allocating failed") );
       
   681         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
   682         }
       
   683     
       
   684     if ( aEnableFiltering )
       
   685         {
       
   686         mib->iEnable = ETrue;
       
   687         mib->iIpV4Addr = aIpv4Address;
       
   688         
       
   689         OsTracePrint( KWlmCmdDetails, (TUint8*)
       
   690             ("UMAC: WlanDot11State::SetArpIpAddressTableMib: enable filtering using address: 0x%08x"),
       
   691             aIpv4Address );
       
   692         }
       
   693     else
       
   694         {
       
   695         mib->iEnable = EFalse;
       
   696         mib->iIpV4Addr = aIpv4Address;  // value not relevant in this case
       
   697         
       
   698         OsTracePrint( KWlmCmdDetails, (TUint8*)
       
   699             ("UMAC: WlanDot11State::SetArpIpAddressTableMib: disable filtering") );
       
   700         }
       
   701 
       
   702     WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
       
   703         
       
   704     wha_cmd.Set( 
       
   705         aCtxImpl, 
       
   706         WHA::KMibArpIpAddressTable, 
       
   707         KMibLength, 
       
   708         mib );
       
   709         
       
   710     // change global state: entry procedure triggers action
       
   711     ChangeState( aCtxImpl, 
       
   712         *this,              // prev state
       
   713         wha_cmd,            // next state
       
   714         // the ACT
       
   715         KCompleteManagementRequest
       
   716         );   
       
   717 
       
   718     os_free( mib ); // release the allocated memory
       
   719 
       
   720     // signal caller that a state transition occurred
       
   721     return ETrue;
       
   722     }
       
   723 
       
   724 // -----------------------------------------------------------------------------
       
   725 // 
       
   726 // -----------------------------------------------------------------------------
       
   727 //
       
   728 TBool WlanDot11State::OnDot11PwrMgmtTransitRequired( 
       
   729     WlanContextImpl& aCtxImpl )
       
   730     {
       
   731     // the specified power state will be taken into use later
       
   732     // So nothing more to do at this point than completing the oid
       
   733     OnOidComplete( aCtxImpl );
       
   734     return EFalse;
       
   735     }
       
   736 
       
   737 // -----------------------------------------------------------------------------
       
   738 // 
       
   739 // -----------------------------------------------------------------------------
       
   740 //
       
   741 WHA::TQueueId WlanDot11State::QueueId( 
       
   742     const WlanContextImpl& aCtxImpl,
       
   743     const TUint8* aDot11MacHeader ) const
       
   744     {
       
   745     // this initial value is always returned if we have a non-QoS connection
       
   746     WHA::TQueueId queue_id( WHA::ELegacy );
       
   747 
       
   748     if ( aCtxImpl.QosEnabled() )
       
   749         {
       
   750         // a QOS connection
       
   751         SQosDataMpduHeader* dot11_hdr 
       
   752             = reinterpret_cast<SQosDataMpduHeader*>(
       
   753             const_cast<TUint8*>(aDot11MacHeader));
       
   754 
       
   755         // determine frame type
       
   756         const TUint8 KFrameType( dot11_hdr->iHdr.iHdr.GetFrameControl().iType );
       
   757         
       
   758         if ( KFrameType == E802Dot11FrameTypeQosData )
       
   759             {
       
   760             // this is a QoS data frame so assign it to 
       
   761             // the correct queue according to the priority
       
   762 
       
   763             OsTracePrint( KQos, (TUint8*)
       
   764                 ("UMAC: WlanDot11State::QueueId: 802.1d priority: %d"),
       
   765                 dot11_hdr->iHdr.UserPriority() );
       
   766 
       
   767             queue_id = Queue( dot11_hdr->iHdr.UserPriority() );            
       
   768             }
       
   769         else 
       
   770             {
       
   771             // a non data type frame is put to voice queue
       
   772             queue_id = WHA::EVoice;
       
   773             }
       
   774         }
       
   775         
       
   776     OsTracePrint( KQos, (TUint8*)
       
   777         ("UMAC: WlanDot11State::QueueId: use queue: %d"),
       
   778         queue_id );
       
   779 
       
   780     return queue_id;
       
   781     }
       
   782 
       
   783 // -----------------------------------------------------------------------------
       
   784 // 
       
   785 // -----------------------------------------------------------------------------
       
   786 //
       
   787 TBool WlanDot11State::TxDeauthenticate( 
       
   788     WlanContextImpl& aCtxImpl, 
       
   789     T802Dot11ManagementReasonCode aReason,
       
   790     TBool aWaitIfIntTxBufNotFree ) const
       
   791     {
       
   792     OsTracePrint( KUmacProtocolState | KUmacAuth, 
       
   793         (TUint8*)("UMAC: WlanDot11State::TxDeauthenticate") );
       
   794             
       
   795     TBool status ( EFalse );
       
   796 
       
   797     // client doesn't have to take care of the tx buffer header space
       
   798     // as the method below does that by itself
       
   799     TUint8* start_of_frame = aCtxImpl.TxBuffer( aWaitIfIntTxBufNotFree );
       
   800 
       
   801     if ( start_of_frame )
       
   802         {
       
   803         TUint32 frameLength ( 0 );
       
   804 
       
   805         // construct deauthenticate frame
       
   806         // note that we don't have to set SA because we have already set it
       
   807         // in the initialize phase of the state machine
       
   808     
       
   809         if ( aCtxImpl.HtSupportedByNw() )
       
   810             {
       
   811             // set the BSSID   
       
   812             (aCtxImpl.GetHtDeauthenticateFrame()).iHeader.iBSSID = aCtxImpl.GetBssId();
       
   813             // set the DA
       
   814             (aCtxImpl.GetHtDeauthenticateFrame()).iHeader.iDA = aCtxImpl.GetBssId();
       
   815             // set the reason code
       
   816             (aCtxImpl.GetHtDeauthenticateFrame()).iReasonCode.SetReasonCode(
       
   817                 aReason );
       
   818             
       
   819             frameLength = sizeof( SHtDeauthenticateFrame );
       
   820             
       
   821             // copy deauthentication frame to tx-buffer to correct offset
       
   822             os_memcpy( 
       
   823                 start_of_frame,
       
   824                 &(aCtxImpl.GetHtDeauthenticateFrame()), 
       
   825                 frameLength );            
       
   826             }
       
   827         else
       
   828             {
       
   829             // set the BSSID   
       
   830             (aCtxImpl.GetDeauthenticateFrame()).iHeader.iBSSID = aCtxImpl.GetBssId();
       
   831             // set the DA
       
   832             (aCtxImpl.GetDeauthenticateFrame()).iHeader.iDA = aCtxImpl.GetBssId();
       
   833             // set the reason code
       
   834             (aCtxImpl.GetDeauthenticateFrame()).iReasonCode.SetReasonCode(
       
   835                 aReason );
       
   836     
       
   837             frameLength = sizeof( SDeauthenticateFrame );
       
   838             
       
   839             // copy deauthentication frame to tx-buffer to correct offset
       
   840             os_memcpy( 
       
   841                 start_of_frame,
       
   842                 &(aCtxImpl.GetDeauthenticateFrame()), 
       
   843                 frameLength );
       
   844             }
       
   845     
       
   846         const WHA::TQueueId queue_id( QueueId( aCtxImpl, start_of_frame ) );
       
   847     
       
   848         // send deauthentication frame by pushing it to the packet scheduler
       
   849         status = aCtxImpl.PushPacketToPacketScheduler( 
       
   850                     start_of_frame, 
       
   851                     frameLength, 
       
   852                     queue_id,
       
   853                     E802Dot11FrameTypeDeauthentication,
       
   854                     NULL,
       
   855                     EFalse,
       
   856                     EFalse,
       
   857                     ETrue );
       
   858         }
       
   859     else
       
   860         {
       
   861         // we didn't get a Tx buffer => frame not sent. EFalse will be returned
       
   862         // to indicate that
       
   863 
       
   864         OsTracePrint( KUmacProtocolState | KUmacAuth, (TUint8*)
       
   865             ("UMAC: no free internal tx buf => frame not sent") );
       
   866         }
       
   867 
       
   868     return status;
       
   869     }
       
   870 
       
   871 // -----------------------------------------------------------------------------
       
   872 // 
       
   873 // -----------------------------------------------------------------------------
       
   874 //
       
   875 TBool WlanDot11State::TxDisassociate(
       
   876     WlanContextImpl& aCtxImpl, 
       
   877     T802Dot11ManagementReasonCode aReason,
       
   878     TBool aWaitIfIntTxBufNotFree ) const
       
   879     {
       
   880     OsTracePrint( KUmacProtocolState | KUmacAssoc, 
       
   881         (TUint8*)("UMAC: WlanDot11State::TxDisassociate") );
       
   882 
       
   883     TBool status ( EFalse );
       
   884 
       
   885     // client doesn't have to take care of the tx buffer header space
       
   886     // as the method below does that by itself
       
   887     TUint8* start_of_frame = aCtxImpl.TxBuffer( aWaitIfIntTxBufNotFree );
       
   888 
       
   889     if ( start_of_frame )
       
   890         {
       
   891         TUint32 frameLength ( 0 );
       
   892 
       
   893         // NOTE: We don't set the address fields to frame here like 
       
   894         // in the case of dot11-deauthenticate frame, because in the case of
       
   895         // roaming we would use that BSS's information where we are roaming 
       
   896         // to - instead of the existing one 
       
   897     
       
   898         if ( aCtxImpl.HtSupportedByNw() )
       
   899             {
       
   900             (aCtxImpl.GetHtDisassociationFrame()).iReasonCode.SetReasonCode(
       
   901                 aReason );    
       
   902             
       
   903             frameLength = sizeof( SHtDisassociateFrame );
       
   904             
       
   905             // copy disassociation frame to tx-buffer to correct offset
       
   906             os_memcpy( 
       
   907                 start_of_frame,
       
   908                 &(aCtxImpl.GetHtDisassociationFrame()), 
       
   909                 frameLength );            
       
   910             }
       
   911         else
       
   912             {
       
   913             (aCtxImpl.GetDisassociationFrame()).iReasonCode.SetReasonCode(
       
   914                 aReason );    
       
   915             
       
   916             frameLength = sizeof( SDisassociateFrame );
       
   917             
       
   918             // copy disassociation frame to tx-buffer to correct offset
       
   919             os_memcpy( 
       
   920                 start_of_frame,
       
   921                 &(aCtxImpl.GetDisassociationFrame()), 
       
   922                 frameLength );
       
   923             }
       
   924     
       
   925         const WHA::TQueueId queue_id 
       
   926             = QueueId( aCtxImpl, start_of_frame );
       
   927     
       
   928         // send disassociation frame to the current AP by pushing it to the packet
       
   929         // scheduler
       
   930         status = aCtxImpl.PushPacketToPacketScheduler( 
       
   931                     start_of_frame, 
       
   932                     frameLength, 
       
   933                     queue_id,
       
   934                     E802Dot11FrameTypeDisassociation,
       
   935                     NULL,
       
   936                     EFalse,
       
   937                     EFalse,
       
   938                     ETrue );
       
   939         }
       
   940     else
       
   941         {
       
   942         // we didn't get a Tx buffer => frame not sent. EFalse will be returned
       
   943         // to indicate that
       
   944 
       
   945         OsTracePrint( KUmacProtocolState | KUmacAuth, (TUint8*)
       
   946             ("UMAC: no free internal tx buf => frame not sent") );
       
   947         }
       
   948 
       
   949     return status;
       
   950     }
       
   951 
       
   952 // -----------------------------------------------------------------------------
       
   953 // 
       
   954 // -----------------------------------------------------------------------------
       
   955 //
       
   956 WHA::SAesPairwiseKey* WlanDot11State::CreateAesPtkCtx( 
       
   957     WlanContextImpl& aCtxImpl,
       
   958     WlanWsaAddKey& aWhaAddKey,
       
   959     const TUint8* aData, 
       
   960     const TMacAddress& aMacAddr )
       
   961     {
       
   962     // store info of AES PTK insertion
       
   963     aCtxImpl.PairWiseKeyType( WHA::EAesPairWiseKey );
       
   964 
       
   965     // allocate memory for the key structure
       
   966     WHA::SAesPairwiseKey* key = static_cast<WHA::SAesPairwiseKey*>
       
   967         ( os_alloc( sizeof( WHA::SAesPairwiseKey ) ) ); 
       
   968 
       
   969     if ( key )
       
   970         {
       
   971         os_memcpy( 
       
   972             key->iMacAddr.iMacAddress, 
       
   973             aMacAddr.iMacAddress,
       
   974             WHA::TMacAddress::KMacAddressLength );
       
   975         os_memcpy( key->iAesKey, aData, WHA::KAesKeyLength );
       
   976         
       
   977         aWhaAddKey.Set( 
       
   978             aCtxImpl, 
       
   979             WHA::EAesPairWiseKey,
       
   980             key,
       
   981             WlanWsaKeyIndexMapper::Extract( WHA::EAesPairWiseKey ) );
       
   982         }
       
   983     else
       
   984         {
       
   985         // left intentionally empty
       
   986         }
       
   987 
       
   988     return key;
       
   989     }
       
   990 
       
   991 // -----------------------------------------------------------------------------
       
   992 // 
       
   993 // -----------------------------------------------------------------------------
       
   994 //
       
   995 WHA::STkipPairwiseKey* WlanDot11State::CreateTkipPtkCtx( 
       
   996     WlanContextImpl& aCtxImpl,
       
   997     WlanWsaAddKey& aWhaAddKey,
       
   998     const TUint8* aData, 
       
   999     T802Dot11WepKeyId aKeyIndex, 
       
  1000     const TMacAddress& aMacAddr )
       
  1001     {
       
  1002     // store info of TKIP PTK insertion
       
  1003     aCtxImpl.PairWiseKeyType( WHA::ETkipPairWiseKey );
       
  1004 
       
  1005     // allocate memory for the key structure
       
  1006     // the caller of this method will deallocate the memory
       
  1007     WHA::STkipPairwiseKey* key = static_cast<WHA::STkipPairwiseKey*>
       
  1008         (os_alloc( sizeof( WHA::STkipPairwiseKey ) )); 
       
  1009 
       
  1010     if ( key )
       
  1011         {
       
  1012         os_memcpy( 
       
  1013             key->iMacAddr.iMacAddress, 
       
  1014             aMacAddr.iMacAddress,
       
  1015             WHA::TMacAddress::KMacAddressLength );
       
  1016         os_memcpy( key->iTkipKey, aData, WHA::KTKIPKeyLength );
       
  1017         os_memcpy( 
       
  1018             key->iRxMicKey, 
       
  1019             aData + WHA::KTKIPKeyLength, 
       
  1020             WHA::KMicLength );
       
  1021         os_memcpy( 
       
  1022             key->iTxMicKey, 
       
  1023             aData + WHA::KTKIPKeyLength + WHA::KMicLength, 
       
  1024             WHA::KMicLength);
       
  1025         key->iKeyId =  static_cast<WHA::TPrivacyKeyId>(aKeyIndex);
       
  1026         
       
  1027         aWhaAddKey.Set( aCtxImpl, 
       
  1028             WHA::ETkipPairWiseKey,
       
  1029             key,
       
  1030             WlanWsaKeyIndexMapper::Extract( WHA::ETkipPairWiseKey ) );
       
  1031         }
       
  1032     else
       
  1033         {
       
  1034         // left intentionally empty
       
  1035         }
       
  1036     
       
  1037     return key;
       
  1038     }
       
  1039 
       
  1040 // -----------------------------------------------------------------------------
       
  1041 // 
       
  1042 // -----------------------------------------------------------------------------
       
  1043 //
       
  1044 WHA::SWepPairwiseKey* WlanDot11State::CreateUnicastWepKeyCtx(
       
  1045     WlanContextImpl& aCtxImpl,
       
  1046     WlanWsaAddKey& aWhaAddKey,
       
  1047     const TMacAddress& aMacAddr,
       
  1048     TUint32 aKeyLength,                      
       
  1049     const TUint8* aKey )
       
  1050     {
       
  1051     // store info of WEP PTK insertion
       
  1052     aCtxImpl.PairWiseKeyType( WHA::EWepPairWiseKey );
       
  1053 
       
  1054     // allocate memory for the key structure
       
  1055     WHA::SWepPairwiseKey* key = static_cast<WHA::SWepPairwiseKey*>
       
  1056         (os_alloc( WHA::SWepPairwiseKey::KHeaderSize + aKeyLength )); 
       
  1057 
       
  1058     if ( key )
       
  1059         {
       
  1060         os_memcpy( 
       
  1061             &(key->iMacAddr), 
       
  1062             aMacAddr.iMacAddress,
       
  1063             sizeof(key->iMacAddr) );
       
  1064         key->iKeyLengthInBytes = static_cast<TUint8>(aKeyLength);
       
  1065         os_memcpy( key->iKey, aKey, key->iKeyLengthInBytes );
       
  1066     
       
  1067         aWhaAddKey.Set( aCtxImpl, 
       
  1068             WHA::EWepPairWiseKey,
       
  1069             key,
       
  1070             WlanWsaKeyIndexMapper::Extract( WHA::EWepPairWiseKey ) );
       
  1071         }
       
  1072     else
       
  1073         {
       
  1074         // intentionally left empty
       
  1075         }
       
  1076     
       
  1077     return key;    
       
  1078     }
       
  1079 
       
  1080 // -----------------------------------------------------------------------------
       
  1081 // 
       
  1082 // -----------------------------------------------------------------------------
       
  1083 //
       
  1084 WHA::SWapiPairwiseKey* WlanDot11State::CreateWapiPtkCtx( 
       
  1085     WlanContextImpl& aCtxImpl,
       
  1086     WlanWsaAddKey& aWhaAddKey,
       
  1087     const TUint8* aData, 
       
  1088     T802Dot11WepKeyId aKeyIndex, 
       
  1089     const TMacAddress& aMacAddr )
       
  1090     {
       
  1091     // store info of WAPI pairwise key insertion
       
  1092     aCtxImpl.PairWiseKeyType( WHA::EWapiPairWiseKey );
       
  1093 
       
  1094     // allocate memory for the key structure
       
  1095     // the caller of this method will deallocate the memory
       
  1096     WHA::SWapiPairwiseKey* key = static_cast<WHA::SWapiPairwiseKey*>
       
  1097         (os_alloc( sizeof( WHA::SWapiPairwiseKey ) )); 
       
  1098 
       
  1099     if ( key )
       
  1100         {
       
  1101         os_memcpy( 
       
  1102             key->iMacAddr.iMacAddress, 
       
  1103             aMacAddr.iMacAddress,
       
  1104             WHA::TMacAddress::KMacAddressLength );
       
  1105 
       
  1106         key->iKeyId =  static_cast<WHA::TPrivacyKeyId>(aKeyIndex);
       
  1107 
       
  1108         os_memcpy( key->iWapiKey, aData, WHA::KWapiKeyLength );
       
  1109 
       
  1110         os_memcpy( 
       
  1111             key->iMicKey, 
       
  1112             aData + WHA::KWapiKeyLength, 
       
  1113             WHA::KWapiMicKeyLength );
       
  1114         
       
  1115         aWhaAddKey.Set( aCtxImpl, 
       
  1116             WHA::EWapiPairWiseKey,
       
  1117             key,
       
  1118             WlanWsaKeyIndexMapper::Extract( WHA::EWapiPairWiseKey ) );
       
  1119         }
       
  1120     else
       
  1121         {
       
  1122         // left intentionally empty
       
  1123         }
       
  1124     
       
  1125     return key;
       
  1126     }
       
  1127 
       
  1128 // -----------------------------------------------------------------------------
       
  1129 // 
       
  1130 // -----------------------------------------------------------------------------
       
  1131 //
       
  1132 WHA::TRate WlanDot11State::InitialSpecialFrameTxRate( 
       
  1133     const WlanContextImpl& aCtxImpl ) const
       
  1134     {
       
  1135     WHA::TRate rateToUse ( WHA::KRate1Mbits );
       
  1136     
       
  1137     const TUint32 basicRateSet = aCtxImpl.BasicRateSet();
       
  1138     
       
  1139     if ( basicRateSet )
       
  1140         {
       
  1141         // there is at least one supported basic rate (which is the way things
       
  1142         // are supposed to be if the network is correctly configured)
       
  1143         
       
  1144         if ( basicRateSet & WHA::KRate1Mbits )
       
  1145             {
       
  1146             rateToUse = WHA::KRate1Mbits;
       
  1147             }
       
  1148         else if ( basicRateSet & WHA::KRate6Mbits )
       
  1149             {
       
  1150             rateToUse = WHA::KRate6Mbits;
       
  1151             }
       
  1152         else if ( basicRateSet & WHA::KRate2Mbits )
       
  1153             {
       
  1154             rateToUse = WHA::KRate2Mbits;
       
  1155             }
       
  1156         else if ( basicRateSet & WHA::KRate9Mbits )
       
  1157             {
       
  1158             rateToUse = WHA::KRate9Mbits;
       
  1159             }
       
  1160         else
       
  1161             {
       
  1162             // none of the rates above is a supported basic rate, which is 
       
  1163             // rather odd.
       
  1164             // Anyhow, figure out the lowest supported basic rate and use that
       
  1165 
       
  1166             WHA::TRate rateCandidate = WHA::KRate1Mbits;
       
  1167 
       
  1168             do            
       
  1169                 {
       
  1170                 if ( basicRateSet & rateCandidate )
       
  1171                     {
       
  1172                     rateToUse = rateCandidate;
       
  1173                     // break the loop as we found what we are looking for
       
  1174                     break;
       
  1175                     }
       
  1176                 else
       
  1177                     {
       
  1178                     rateCandidate <<= 1;
       
  1179                     }                
       
  1180                 
       
  1181                 } while ( rateCandidate <= WHA::KRate54Mbits );
       
  1182             }                
       
  1183         }
       
  1184     else
       
  1185         {
       
  1186         // there are no supported basic rates; which is actually a network 
       
  1187         // configuration error. 
       
  1188         OsTracePrint( KWarningLevel, 
       
  1189             (TUint8*)("UMAC: WlanDot11State::InitialSpecialFrameTxRate: Warning: no basic rates configured in nw"));
       
  1190         
       
  1191         // But as we don't absolutely have to find a 
       
  1192         // basic rate here, just stay with 1Mbps (set above)
       
  1193         }    
       
  1194         
       
  1195     OsTracePrint( KWsaTxDetails, 
       
  1196         (TUint8*)("UMAC: WlanDot11State::InitialSpecialFrameTxRate: use rate: 0x%08x"), 
       
  1197         rateToUse );
       
  1198 
       
  1199     return rateToUse;
       
  1200     }
       
  1201 
       
  1202 // -----------------------------------------------------------------------------
       
  1203 // 
       
  1204 // -----------------------------------------------------------------------------
       
  1205 //
       
  1206 TBool WlanDot11State::DoErrorIndication( 
       
  1207     WlanContextImpl& aCtxImpl, 
       
  1208     WHA::TStatus /*aStatus*/ )
       
  1209     {
       
  1210     OsTracePrint( KWarningLevel, 
       
  1211         (TUint8*)("UMAC * handle an error indication!") );
       
  1212 
       
  1213     // this is the one and only global error handler
       
  1214     ChangeState( aCtxImpl, *this, aCtxImpl.iStates.iMacError );
       
  1215 
       
  1216     // signal with return value that a state transition occurred
       
  1217     return ETrue;
       
  1218     }
       
  1219 
       
  1220 // -----------------------------------------------------------------------------
       
  1221 // 
       
  1222 // -----------------------------------------------------------------------------
       
  1223 //
       
  1224 void WlanDot11State::DoConsecutiveBeaconsLostIndication( 
       
  1225     WlanContextImpl& /*aCtxImpl*/ )
       
  1226     {
       
  1227     // not supported in default handler
       
  1228     }
       
  1229 
       
  1230 // -----------------------------------------------------------------------------
       
  1231 // 
       
  1232 // -----------------------------------------------------------------------------
       
  1233 //
       
  1234 void WlanDot11State::DoRegainedBSSIndication( 
       
  1235     WlanContextImpl& /*aCtxImpl*/ )
       
  1236     {
       
  1237     // not supported in default handler
       
  1238     }
       
  1239 
       
  1240 // -----------------------------------------------------------------------------
       
  1241 // 
       
  1242 // -----------------------------------------------------------------------------
       
  1243 //
       
  1244 void WlanDot11State::DoRadarIndication( 
       
  1245     WlanContextImpl& /*aCtxImpl*/ )
       
  1246     {
       
  1247     // not supported in default handler
       
  1248     }
       
  1249 
       
  1250 // -----------------------------------------------------------------------------
       
  1251 // 
       
  1252 // -----------------------------------------------------------------------------
       
  1253 //
       
  1254 void WlanDot11State::DoRcpiIndication( 
       
  1255     WlanContextImpl& /*aCtxImpl*/,
       
  1256     WHA::TRcpi /*aRcpi*/ )
       
  1257     {
       
  1258     // not supported in default handler
       
  1259     }
       
  1260 
       
  1261 // ---------------------------------------------------------------------------
       
  1262 // 
       
  1263 // ---------------------------------------------------------------------------
       
  1264 //
       
  1265 void WlanDot11State::DoPsModeErrorIndication( 
       
  1266     WlanContextImpl& /*aCtxImpl*/ )
       
  1267     {
       
  1268     // not supported in default handler
       
  1269     }
       
  1270 
       
  1271 // -----------------------------------------------------------------------------
       
  1272 // 
       
  1273 // -----------------------------------------------------------------------------
       
  1274 //
       
  1275 TBool WlanDot11State::TxData( 
       
  1276     WlanContextImpl& aCtxImpl,
       
  1277     TDataBuffer& aDataBuffer,
       
  1278     TBool /*aMore*/ )
       
  1279     {
       
  1280     OsTracePrint( KErrorLevel, (TUint8*)
       
  1281         ("UMAC: Tx attempted when it's not allowed; frame ignored") );
       
  1282     
       
  1283     aCtxImpl.iUmac.OnTxProtocolStackDataComplete( 
       
  1284         KErrNone,
       
  1285         &aDataBuffer );        
       
  1286 
       
  1287     // no state change occurred
       
  1288     return EFalse;
       
  1289     }
       
  1290 
       
  1291 // -----------------------------------------------------------------------------
       
  1292 // 
       
  1293 // -----------------------------------------------------------------------------
       
  1294 //
       
  1295 void WlanDot11State::TxMgmtData( 
       
  1296     WlanContextImpl& aCtxImpl,
       
  1297     TDataBuffer& /*aDataBuffer*/ )
       
  1298     {
       
  1299     // as we are not connected to network, this frame cannot be sent.
       
  1300     // Just complete the frame send request without error status; as
       
  1301     // the WLAN Mgmt Client doesn't care about the status
       
  1302     OnMgmtPathWriteComplete( aCtxImpl );
       
  1303     }
       
  1304 
       
  1305 // -----------------------------------------------------------------------------
       
  1306 // 
       
  1307 // -----------------------------------------------------------------------------
       
  1308 //
       
  1309 TAny* WlanDot11State::RequestForBuffer( 
       
  1310     WlanContextImpl& /*aCtxImpl*/,             
       
  1311     TUint16 /*aLength*/ )
       
  1312     {
       
  1313     // no functionality in default handler
       
  1314     return NULL;
       
  1315     }
       
  1316 
       
  1317 // -----------------------------------------------------------------------------
       
  1318 // 
       
  1319 // -----------------------------------------------------------------------------
       
  1320 //
       
  1321 void WlanDot11State::ReceivePacket( 
       
  1322     WlanContextImpl& aCtxImpl, 
       
  1323     WHA::TStatus /*aStatus*/,
       
  1324     const void* /*aFrame*/,
       
  1325     TUint16 /*aLength*/,
       
  1326     WHA::TRate /*aRate*/,
       
  1327     WHA::TRcpi /*aRcpi*/,
       
  1328     WHA::TChannelNumber /*aChannel*/,
       
  1329     TUint8* aBuffer,
       
  1330     TUint32 /*aFlags*/ )
       
  1331     {
       
  1332     // release the Rx buffer
       
  1333     aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
  1334     }
       
  1335 
       
  1336 // -----------------------------------------------------------------------------
       
  1337 // 
       
  1338 // -----------------------------------------------------------------------------
       
  1339 //
       
  1340 void WlanDot11State::OnWhaCommandResponse( 
       
  1341     WlanContextImpl& aCtxImpl, 
       
  1342     WHA::TCommandId aCommandId, 
       
  1343     WHA::TStatus /*aStatus*/,
       
  1344     const WHA::UCommandResponseParams& aCommandResponseParams,
       
  1345     TUint32 aAct )
       
  1346     {
       
  1347     // this command response method is supposed to be called
       
  1348     // when a concrete dot11 state object does not care about 
       
  1349     // the command response parameters
       
  1350 
       
  1351     if ( aAct == KCompleteManagementRequest )
       
  1352         {
       
  1353         // this must be a response to a command that was generated 
       
  1354         // by this this dot11 state object default layer
       
  1355         if ( aCommandId != WHA::EReadMIBResponse )
       
  1356             {
       
  1357             OnOidComplete( aCtxImpl );        
       
  1358             }
       
  1359         else
       
  1360             {
       
  1361             // as this is a MIB read request, we must supply the
       
  1362             // response to the Mgmt Client
       
  1363             if ( aCommandResponseParams.iReadMibResponse.iMib 
       
  1364                 == WHA::KMibStatisticsTable )
       
  1365                 {
       
  1366                 // convert to a 32bit value before forwarding
       
  1367                 TInt32 rcpi = reinterpret_cast
       
  1368                     <const WHA::SstatisticsTable*>
       
  1369                     (aCommandResponseParams.iReadMibResponse.iData)->iRcpi;
       
  1370 
       
  1371                 OsTracePrint( 
       
  1372                     KUmacDetails, 
       
  1373                     (TUint8*)
       
  1374                     ("UMAC: WlanDot11State::OnWhaCommandResponse(): last rcpi: %d"), 
       
  1375                     rcpi );
       
  1376 
       
  1377                 OnOidComplete( aCtxImpl, 
       
  1378                                KErrNone, 
       
  1379                                reinterpret_cast<const TAny*>(&rcpi),
       
  1380                                sizeof(rcpi) );        
       
  1381                 }
       
  1382             else if ( aCommandResponseParams.iReadMibResponse.iMib 
       
  1383                 == WHA::KMibCountersTable )
       
  1384                 {
       
  1385                 const WHA::ScountersTable* countersTable = reinterpret_cast
       
  1386                     <const WHA::ScountersTable*>
       
  1387                     (aCommandResponseParams.iReadMibResponse.iData);
       
  1388 
       
  1389                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1390                     ("UMAC: WlanDot11State::OnWhaCommandResponse: countersTableMib: nbr of FCS errors in received MPDUs: %d"), 
       
  1391                     countersTable->iFcsError );
       
  1392 
       
  1393                 aCtxImpl.StoreFcsErrorCount( countersTable->iFcsError );
       
  1394                 
       
  1395                 // as we are about to report the frame statistics results,
       
  1396                 // it's the time to perform also the necessary calculations
       
  1397                 
       
  1398                 aCtxImpl.CalculateAverageTxMediaDelays();                
       
  1399                 aCtxImpl.CalculateAverageTotalTxDelays();
       
  1400              
       
  1401                 const TStatisticsResponse& frameStatistics ( aCtxImpl.FrameStatistics() );
       
  1402                    
       
  1403 #ifndef NDEBUG                
       
  1404                 // trace frame statistics
       
  1405 
       
  1406                 OsTracePrint( 
       
  1407                     KUmacDetails, (TUint8*)
       
  1408                     ("UMAC: WlanDot11State::OnWhaCommandResponse: *** reported frame statistics ***:") );
       
  1409 
       
  1410                 for ( TUint i = 0; i < EQueueIdMax; ++i )
       
  1411                     {
       
  1412                     OsTracePrint( 
       
  1413                         KUmacDetails, (TUint8*)
       
  1414                         ("UMAC: WlanDot11State::OnWhaCommandResponse: * Access Category: %d *"),
       
  1415                         i );
       
  1416 
       
  1417                     OsTracePrint( 
       
  1418                         KUmacDetails, (TUint8*)
       
  1419                         ("UMAC: WlanDot11State::OnWhaCommandResponse: successfully received unicast data frames: %d"), 
       
  1420                          frameStatistics.acSpecific[i].rxUnicastDataFrameCount );
       
  1421 
       
  1422                     OsTracePrint( 
       
  1423                         KUmacDetails, (TUint8*)
       
  1424                         ("UMAC: WlanDot11State::OnWhaCommandResponse: successfully transmitted unicast data frames: %d"), 
       
  1425                          frameStatistics.acSpecific[i].txUnicastDataFrameCount );
       
  1426 
       
  1427                     OsTracePrint( 
       
  1428                         KUmacDetails, (TUint8*)
       
  1429                         ("UMAC: WlanDot11State::OnWhaCommandResponse: successfully received multicast data frames: %d"), 
       
  1430                          frameStatistics.acSpecific[i].rxMulticastDataFrameCount );
       
  1431                     
       
  1432                     OsTracePrint( 
       
  1433                         KUmacDetails, (TUint8*)
       
  1434                         ("UMAC: WlanDot11State::OnWhaCommandResponse: successfully transmitted multicast data frames: %d"), 
       
  1435                          frameStatistics.acSpecific[i].txMulticastDataFrameCount );
       
  1436 
       
  1437                     OsTracePrint( 
       
  1438                         KUmacDetails, (TUint8*)
       
  1439                         ("UMAC: WlanDot11State::OnWhaCommandResponse: nbr of data frame transmit retries: %d"), 
       
  1440                          frameStatistics.acSpecific[i].txRetryCount );
       
  1441 
       
  1442                     OsTracePrint( 
       
  1443                         KUmacDetails, (TUint8*)
       
  1444                         ("UMAC: WlanDot11State::OnWhaCommandResponse: nbr of data frame WLAN delivery failures: %d"), 
       
  1445                          frameStatistics.acSpecific[i].txErrorCount );                    
       
  1446 
       
  1447                     OsTracePrint( 
       
  1448                         KUmacDetails, (TUint8*)
       
  1449                         ("UMAC: WlanDot11State::OnWhaCommandResponse: average data frame Tx media delay in microsecs: %d"), 
       
  1450                          frameStatistics.acSpecific[i].txMediaDelay );                    
       
  1451 
       
  1452                     OsTracePrint( 
       
  1453                         KUmacDetails, (TUint8*)
       
  1454                         ("UMAC: WlanDot11State::OnWhaCommandResponse: average data frame total Tx delay in microsecs: %d"), 
       
  1455                          frameStatistics.acSpecific[i].totalTxDelay );    
       
  1456                          
       
  1457                     OsTracePrint( 
       
  1458                         KUmacDetails, (TUint8*)
       
  1459                         ("UMAC: WlanDot11State::OnWhaCommandResponse: data frame total Tx delay bin 0 count: %d"), 
       
  1460                          frameStatistics.acSpecific[i].totalTxDelayBin0 );
       
  1461 
       
  1462                     OsTracePrint( 
       
  1463                         KUmacDetails, (TUint8*)
       
  1464                         ("UMAC: WlanDot11State::OnWhaCommandResponse: data frame total Tx delay bin 1 count: %d"), 
       
  1465                          frameStatistics.acSpecific[i].totalTxDelayBin1 );
       
  1466 
       
  1467                     OsTracePrint( 
       
  1468                         KUmacDetails, (TUint8*)
       
  1469                         ("UMAC: WlanDot11State::OnWhaCommandResponse: data frame total Tx delay bin 2 count: %d"), 
       
  1470                          frameStatistics.acSpecific[i].totalTxDelayBin2 );
       
  1471 
       
  1472                     OsTracePrint( 
       
  1473                         KUmacDetails, (TUint8*)
       
  1474                         ("UMAC: WlanDot11State::OnWhaCommandResponse: data frame total Tx delay bin 3 count: %d"), 
       
  1475                          frameStatistics.acSpecific[i].totalTxDelayBin3 );
       
  1476                     }
       
  1477 
       
  1478                 OsTracePrint( 
       
  1479                     KUmacDetails, (TUint8*)
       
  1480                     ("UMAC: WlanDot11State::OnWhaCommandResponse: all ACs: nbr of FCS errors in received MPDUs: %d"), 
       
  1481                      frameStatistics.fcsErrorCount );
       
  1482 
       
  1483 #endif
       
  1484 
       
  1485                 OnOidComplete( aCtxImpl, 
       
  1486                                KErrNone, 
       
  1487                                reinterpret_cast<const TAny*>(&frameStatistics),
       
  1488                                sizeof( frameStatistics ) );
       
  1489 
       
  1490                 // the statistics are cleared after reporting them. It is safe
       
  1491                 // to do it here as the information has already been copied
       
  1492                 aCtxImpl.ResetFrameStatistics();
       
  1493                 }
       
  1494             // -- == WHA::KMibStatisticsTable --
       
  1495             else
       
  1496                 {
       
  1497                 // this thing should never happen as we are not reading any 
       
  1498                 // other MIBs; an implementation error
       
  1499                 OsAssert( (TUint8*)("UMAC: panic"),(TUint8*)(WLAN_FILE), __LINE__ );                
       
  1500                 // well exclusion to this is the dot11stationId MIB that 
       
  1501                 // is read by dot11initphase object, but it overrides this
       
  1502                 // method so this code is not executed in that case.
       
  1503                 }
       
  1504             }
       
  1505         }   
       
  1506     // -- aAct == KCompleteManagementRequest --
       
  1507     else
       
  1508         {
       
  1509         // this is not a response to a command that was generated by this
       
  1510         // dot11 state object.
       
  1511         // which means that the originator of this command does not care
       
  1512         // about the response parameters.
       
  1513         }
       
  1514     }
       
  1515 
       
  1516 // -----------------------------------------------------------------------------
       
  1517 // 
       
  1518 // -----------------------------------------------------------------------------
       
  1519 //
       
  1520 TBool WlanDot11State::OnWlanWakeUpIntervalChange( 
       
  1521     WlanContextImpl& aCtxImpl )
       
  1522     {
       
  1523     OnOidComplete( aCtxImpl );
       
  1524     return EFalse;
       
  1525     }
       
  1526 
       
  1527 // -----------------------------------------------------------------------------
       
  1528 // 
       
  1529 // -----------------------------------------------------------------------------
       
  1530 //
       
  1531 WHA::TQueueId WlanDot11State::Queue( TUint8 aPriority )
       
  1532     {
       
  1533     // Mapping of 802.1d priorities to WMM Access Categories, and hence to
       
  1534     // WHA queue (id)s, as specified in WiFi WMM Specification v1.1
       
  1535     const WHA::TQueueId K802Dot1dPriority2WhaQueueTable[] = 
       
  1536         { WHA::ELegacy,     // for priority 0
       
  1537           WHA::EBackGround, // for priority 1
       
  1538           WHA::EBackGround, // for priority 2
       
  1539           WHA::ELegacy,     // for priority 3
       
  1540           WHA::EVideo,      // for priority 4
       
  1541           WHA::EVideo,      // for priority 5
       
  1542           WHA::EVoice,      // for priority 6
       
  1543           WHA::EVoice };    // for priority 7
       
  1544           
       
  1545     return ( aPriority > 7 ) ? 
       
  1546         WHA::ELegacy :  
       
  1547         K802Dot1dPriority2WhaQueueTable[aPriority];    
       
  1548     }
       
  1549 
       
  1550 // -----------------------------------------------------------------------------
       
  1551 // 
       
  1552 // -----------------------------------------------------------------------------
       
  1553 //
       
  1554 TBool WlanDot11State::UapsdEnabledInNetwork( const SRxWmmIeData& aRxWmmIE )
       
  1555     {
       
  1556     return ( aRxWmmIE.IsUapsdBitSet() );
       
  1557     }
       
  1558     
       
  1559 // -----------------------------------------------------------------------------
       
  1560 // 
       
  1561 // -----------------------------------------------------------------------------
       
  1562 //
       
  1563 TBool WlanDot11State::UapsdEnabledInNetwork( const SWmmParamElemData& aWmmParamElem )
       
  1564     {
       
  1565     return ( aWmmParamElem.IsUapsdBitSet() );
       
  1566     }
       
  1567 
       
  1568 // -----------------------------------------------------------------------------
       
  1569 // 
       
  1570 // -----------------------------------------------------------------------------
       
  1571 //
       
  1572 void WlanDot11State::EnableQos( WlanContextImpl& aCtxImpl, 
       
  1573     TBool aUapsdEnabledInNw )
       
  1574     {
       
  1575     // enable QoS
       
  1576     aCtxImpl.QosEnabled( ETrue );
       
  1577 
       
  1578     // first clear our WMM IE so that U-APSD flags will be set only when 
       
  1579     // they are supposed to be set
       
  1580     aCtxImpl.OurWmmIe().Clear();                    
       
  1581 
       
  1582     if ( aUapsdEnabledInNw )
       
  1583         {
       
  1584         OsTracePrint( 
       
  1585             KQos, (TUint8*)
       
  1586             ("UMAC: WlanDot11State::EnableQos(): u-apsd is supported by nw"));
       
  1587         
       
  1588         // make a note that U-APSD is supported/enabled in the nw
       
  1589         aCtxImpl.UapsdEnabled( ETrue );
       
  1590         
       
  1591         // make a WMM AC both trigger & delivery enabled 
       
  1592         // if U-APSD is supported by the nw (this we already know to be true)
       
  1593         // and
       
  1594         // if U-APSD usage has been requested by WLAN mgmt client for the AC 
       
  1595         // in question
       
  1596         aCtxImpl.OurWmmIe().SetUapsdFlags( static_cast<TQosInfoUapsdFlag>(
       
  1597             ( aCtxImpl.UapsdRequestedForVoice() ? EAcVoUapsdFlag : 0 ) |
       
  1598             ( aCtxImpl.UapsdRequestedForVideo() ? EAcViUapsdFlag : 0 ) |
       
  1599             ( aCtxImpl.UapsdRequestedForBackground() ? EAcBkUapsdFlag : 0 ) |
       
  1600             ( aCtxImpl.UapsdRequestedForBestEffort() ? EAcBeUapsdFlag : 0 )) );
       
  1601                                            
       
  1602         // set max service period length for the ACs as requested by WLAN 
       
  1603         // mgmt client
       
  1604         aCtxImpl.OurWmmIe().SetMaxSpLen( aCtxImpl.UapsdMaxSpLen() );        
       
  1605         }
       
  1606     else
       
  1607         {
       
  1608         OsTracePrint( 
       
  1609             KQos, (TUint8*)
       
  1610             ("UMAC: WlanDot11State::EnableQos(): u-apsd not supported in nw"));
       
  1611         
       
  1612         aCtxImpl.UapsdEnabled( EFalse );        
       
  1613         }
       
  1614     }
       
  1615 
       
  1616 // -----------------------------------------------------------------------------
       
  1617 // 
       
  1618 // -----------------------------------------------------------------------------
       
  1619 //
       
  1620 void WlanDot11State::DetermineAcUapsdUsage( WlanContextImpl& aCtxImpl )
       
  1621     {
       
  1622     if ( aCtxImpl.UapsdEnabled() )
       
  1623         {
       
  1624         if ( aCtxImpl.UapsdRequestedForVoice() )
       
  1625             {
       
  1626             OsTracePrint( KQos, (TUint8*)
       
  1627                 ("UMAC: WlanDot11State::DetermineAcUapsdUsage: u-apsd used for Voice"));
       
  1628             aCtxImpl.UapsdUsedForVoice( ETrue );
       
  1629             }
       
  1630         else
       
  1631             {
       
  1632             OsTracePrint( KQos, (TUint8*)
       
  1633                 ("UMAC: WlanDot11State::DetermineAcUapsdUsage: u-apsd NOT used for Voice"));
       
  1634             aCtxImpl.UapsdUsedForVoice( EFalse );            
       
  1635             }            
       
  1636 
       
  1637         if ( aCtxImpl.UapsdRequestedForVideo() )
       
  1638             {
       
  1639             OsTracePrint( KQos, (TUint8*)
       
  1640                 ("UMAC: WlanDot11State::DetermineAcUapsdUsage: u-apsd used for Video"));
       
  1641             aCtxImpl.UapsdUsedForVideo( ETrue );    
       
  1642             }
       
  1643         else
       
  1644             {
       
  1645             OsTracePrint( KQos, (TUint8*)
       
  1646                 ("UMAC: WlanDot11State::DetermineAcUapsdUsage: u-apsd NOT used for Video"));
       
  1647             aCtxImpl.UapsdUsedForVideo( EFalse );            
       
  1648             }            
       
  1649 
       
  1650         if ( aCtxImpl.UapsdRequestedForBestEffort() )
       
  1651             {
       
  1652             OsTracePrint( KQos, (TUint8*)
       
  1653                 ("UMAC: WlanDot11State::DetermineAcUapsdUsage: u-apsd used for Best Effort"));
       
  1654             aCtxImpl.UapsdUsedForBestEffort( ETrue );
       
  1655             }
       
  1656         else
       
  1657             {
       
  1658             OsTracePrint( KQos, (TUint8*)
       
  1659                 ("UMAC: WlanDot11State::DetermineAcUapsdUsage: u-apsd NOT used for Best Effort"));
       
  1660             aCtxImpl.UapsdUsedForBestEffort( EFalse );            
       
  1661             }            
       
  1662 
       
  1663         if ( aCtxImpl.UapsdRequestedForBackground() )
       
  1664             {
       
  1665             OsTracePrint( KQos, (TUint8*)
       
  1666                 ("UMAC: WlanDot11State::DetermineAcUapsdUsage: u-apsd used for Background"));
       
  1667             aCtxImpl.UapsdUsedForBackground( ETrue );
       
  1668             }
       
  1669         else
       
  1670             {
       
  1671             OsTracePrint( KQos, (TUint8*)
       
  1672                 ("UMAC: WlanDot11State::DetermineAcUapsdUsage: u-apsd NOT used for Background"));
       
  1673             aCtxImpl.UapsdUsedForBackground( EFalse );            
       
  1674             }            
       
  1675         }
       
  1676     else
       
  1677         {
       
  1678         OsTracePrint( KQos, (TUint8*)
       
  1679             ("UMAC: WlanDot11State::DetermineAcUapsdUsage: u-apsd NOT used for any AC"));
       
  1680         aCtxImpl.UapsdUsedForVoice( EFalse );
       
  1681         aCtxImpl.UapsdUsedForVideo( EFalse );
       
  1682         aCtxImpl.UapsdUsedForBestEffort( EFalse );
       
  1683         aCtxImpl.UapsdUsedForBackground( EFalse );        
       
  1684         }
       
  1685 
       
  1686     // now when U-APSD usage per AC has been determined, freeze the dynamic 
       
  1687     // power mode mgmt traffic override/ignoration settings
       
  1688     aCtxImpl.FreezePwrModeMgmtTrafficOverride();
       
  1689     }
       
  1690 
       
  1691 // -----------------------------------------------------------------------------
       
  1692 // 
       
  1693 // -----------------------------------------------------------------------------
       
  1694 //
       
  1695 void WlanDot11State::ResetAcParameters( 
       
  1696     WlanContextImpl& aCtxImpl,
       
  1697     WHA::TQueueId aAccessCategory,
       
  1698     TBool aUseAandGvalues )
       
  1699     {
       
  1700     OsTracePrint( KUmacDetails, (TUint8*)
       
  1701         ("UMAC: WlanDot11State::ResetAcParameters: Reset parameters of AC: %d"),
       
  1702         aAccessCategory );        
       
  1703     OsTracePrint( KUmacDetails, (TUint8*)
       
  1704         ("UMAC: WlanDot11State::ResetAcParameters: aUseAandGvalues: %d"),
       
  1705         aUseAandGvalues );        
       
  1706 
       
  1707     switch ( aAccessCategory )
       
  1708         {
       
  1709         case WHA::ELegacy:
       
  1710             aCtxImpl.CwMinVector()[WHA::ELegacy] = 
       
  1711                 aUseAandGvalues ? KDot11BeCwMinAandG : KDot11BeCwMinB;            
       
  1712             aCtxImpl.CwMaxVector()[WHA::ELegacy] = KDot11BeCwMax;
       
  1713             aCtxImpl.AifsVector()[WHA::ELegacy] = KDot11BeAifsn;
       
  1714             aCtxImpl.TxOplimitVector()[WHA::ELegacy] = KDot11BeTxopLimit;        
       
  1715             break;
       
  1716         case WHA::EBackGround:
       
  1717             aCtxImpl.CwMinVector()[WHA::EBackGround] = 
       
  1718                 aUseAandGvalues ? KDot11BgCwMinAandG : KDot11BgCwMinB;
       
  1719             aCtxImpl.CwMaxVector()[WHA::EBackGround] = KDot11BgCwMax;
       
  1720             aCtxImpl.AifsVector()[WHA::EBackGround] = KDot11BgAifsn;
       
  1721             aCtxImpl.TxOplimitVector()[WHA::EBackGround] = KDot11BgTxopLimit;        
       
  1722             break;
       
  1723         case WHA::EVideo:
       
  1724             aCtxImpl.CwMinVector()[WHA::EVideo] = 
       
  1725                 aUseAandGvalues ? KDot11ViCwMinAandG : KDot11ViCwMinB;            
       
  1726             aCtxImpl.CwMaxVector()[WHA::EVideo] = 
       
  1727                 aUseAandGvalues ? KDot11ViCwMaxAandG : KDot11ViCwMaxB;        
       
  1728             aCtxImpl.AifsVector()[WHA::EVideo] = KDot11ViAifsn;
       
  1729             aCtxImpl.TxOplimitVector()[WHA::EVideo] = 
       
  1730                 aUseAandGvalues ? KDot11ViTxopLimitAandG : KDot11ViTxopLimitB;        
       
  1731             break;
       
  1732         case WHA::EVoice:
       
  1733             aCtxImpl.CwMinVector()[WHA::EVoice] = 
       
  1734                 aUseAandGvalues ? KDot11VoCwMinAandG : KDot11VoCwMinB;            
       
  1735             aCtxImpl.CwMaxVector()[WHA::EVoice] = 
       
  1736                 aUseAandGvalues ? KDot11VoCwMaxAandG : KDot11VoCwMaxB;        
       
  1737             aCtxImpl.AifsVector()[WHA::EVoice] = KDot11VoAifsn;
       
  1738             aCtxImpl.TxOplimitVector()[WHA::EVoice] = 
       
  1739                 aUseAandGvalues ? KDot11VoTxopLimitAandG : KDot11VoTxopLimitB;        
       
  1740             break;        
       
  1741         default:
       
  1742             {
       
  1743             // catch implementation error
       
  1744 
       
  1745             OsTracePrint( KErrorLevel, 
       
  1746                 (TUint8*)("UMAC: WlanDot11State::ResetAcParameters: unsupported access category: %d"), 
       
  1747                 aAccessCategory );        
       
  1748             OsAssert( (TUint8*)("UMAC: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
  1749             }        
       
  1750         }
       
  1751     }
       
  1752     
       
  1753 // -----------------------------------------------------------------------------
       
  1754 // 
       
  1755 // -----------------------------------------------------------------------------
       
  1756 //
       
  1757 void WlanDot11State::ResetAcParameters( 
       
  1758     WlanContextImpl& aCtxImpl, 
       
  1759     TBool aUseAandGvalues )
       
  1760     {
       
  1761     OsTracePrint( KUmacDetails, (TUint8*)
       
  1762         ("UMAC: WlanDot11State::ResetAcParameters: Reset parameters of all ACs. aUseAandGvalues: %d"),
       
  1763         aUseAandGvalues );        
       
  1764     
       
  1765     // Set the default values for a QoS connection for every AC
       
  1766 
       
  1767     ResetAcParameters( aCtxImpl, WHA::ELegacy, aUseAandGvalues );
       
  1768     ResetAcParameters( aCtxImpl, WHA::EBackGround, aUseAandGvalues );
       
  1769     ResetAcParameters( aCtxImpl, WHA::EVideo, aUseAandGvalues );
       
  1770     ResetAcParameters( aCtxImpl, WHA::EVoice, aUseAandGvalues );
       
  1771     
       
  1772     // reset also the WMM Parameter Set Count to initial (not defined) value
       
  1773     aCtxImpl.WmmParameterSetCount( KWmmParamSetNotDefined );            
       
  1774     }    
       
  1775 
       
  1776 // -----------------------------------------------------------------------------
       
  1777 // 
       
  1778 // -----------------------------------------------------------------------------
       
  1779 //
       
  1780 TBool WlanDot11State::AcParametersValid( 
       
  1781     WlanContextImpl& aCtxImpl,
       
  1782     WHA::TQueueId aAccessCategory )
       
  1783     {
       
  1784     TBool status ( ETrue );
       
  1785     
       
  1786     if ( aAccessCategory < WHA::EHcca )
       
  1787         {
       
  1788         if ( // AIFSN validity per the WMM specification
       
  1789              (aCtxImpl.AifsVector())[aAccessCategory] < KDot11AifsnMin ||
       
  1790              // CwMin & CwMax sanity check 
       
  1791              (aCtxImpl.CwMinVector())[aAccessCategory] >=
       
  1792              (aCtxImpl.CwMaxVector())[aAccessCategory] )
       
  1793             {
       
  1794             status = EFalse;
       
  1795             }
       
  1796         else
       
  1797             {
       
  1798             // parameters are reasonable. No action needed
       
  1799             }
       
  1800         }
       
  1801     else
       
  1802         {
       
  1803         // catch implementation error
       
  1804 
       
  1805         OsTracePrint( KErrorLevel, 
       
  1806             (TUint8*)("UMAC: WlanDot11State::AcParametersValid: unsupported aAccessCategory: %d"), 
       
  1807             aAccessCategory );        
       
  1808         OsAssert( (TUint8*)("UMAC: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
  1809         }
       
  1810 
       
  1811     return status;
       
  1812     }
       
  1813     
       
  1814 // -----------------------------------------------------------------------------
       
  1815 // 
       
  1816 // -----------------------------------------------------------------------------
       
  1817 //
       
  1818 void WlanDot11State::ParseAcParameters( 
       
  1819     WlanContextImpl& aCtxImpl, 
       
  1820     const SWmmParamElemData& aWmmParamElem )
       
  1821     {
       
  1822     for( TUint8 i = 0; i < KNumOfWmmACs; i++ )
       
  1823         {
       
  1824         switch ( aWmmParamElem.iAcParams[i].AccessCategory() )
       
  1825             {
       
  1826             case EAcBestEffort:
       
  1827                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1828                     ("UMAC: WlanDot11State::ParseAcParameters: parsing best effort AC parameters"));
       
  1829                 (aCtxImpl.CwMinVector())[WHA::ELegacy] = 
       
  1830                     aWmmParamElem.iAcParams[i].CwMin();
       
  1831                 (aCtxImpl.CwMaxVector())[WHA::ELegacy] = 
       
  1832                     aWmmParamElem.iAcParams[i].CwMax();
       
  1833                 (aCtxImpl.AifsVector())[WHA::ELegacy] = 
       
  1834                     aWmmParamElem.iAcParams[i].Aifsn();
       
  1835                 (aCtxImpl.TxOplimitVector())[WHA::ELegacy] = 
       
  1836                     aWmmParamElem.iAcParams[i].TxOpLimit();
       
  1837                 (aCtxImpl.AcmVector())[WHA::ELegacy] = 
       
  1838                     ( aWmmParamElem.iAcParams[i].AdmissionControlMandatory() )? 
       
  1839                         ETrue : EFalse;
       
  1840 
       
  1841                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1842                     ("UMAC: aCntrl mandatory: %d"), 
       
  1843                     aWmmParamElem.iAcParams[i].AdmissionControlMandatory());
       
  1844                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1845                     ("UMAC: cwmin: %d"), (aCtxImpl.CwMinVector())[WHA::ELegacy]);
       
  1846                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1847                     ("UMAC: cwmax: %d"), (aCtxImpl.CwMaxVector())[WHA::ELegacy]);
       
  1848                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1849                     ("UMAC: aifsn: %d"), (aCtxImpl.AifsVector())[WHA::ELegacy]);
       
  1850                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1851                     ("UMAC: txOpLimit: %d"), (aCtxImpl.TxOplimitVector())[WHA::ELegacy]);
       
  1852                     
       
  1853                 if ( !AcParametersValid( aCtxImpl, WHA::ELegacy ) )
       
  1854                     {
       
  1855                     OsTracePrint( KUmacDetails, (TUint8*)
       
  1856                         ("UMAC: WlanDot11State::ParseAcParameters: BE parameters not reasonble. Resetting to defaults") );
       
  1857                     ResetAcParameters( 
       
  1858                         aCtxImpl, 
       
  1859                         WHA::ELegacy, 
       
  1860                         aCtxImpl.ErpIePresent() );
       
  1861                     }                    
       
  1862                 break;
       
  1863             case EAcBackground:
       
  1864                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1865                     ("UMAC: WlanDot11State::ParseAcParameters: parsing background AC parameters"));
       
  1866                 (aCtxImpl.CwMinVector())[WHA::EBackGround] = 
       
  1867                     aWmmParamElem.iAcParams[i].CwMin();
       
  1868                 (aCtxImpl.CwMaxVector())[WHA::EBackGround] = 
       
  1869                     aWmmParamElem.iAcParams[i].CwMax();
       
  1870                 (aCtxImpl.AifsVector())[WHA::EBackGround] = 
       
  1871                     aWmmParamElem.iAcParams[i].Aifsn();
       
  1872                 (aCtxImpl.TxOplimitVector())[WHA::EBackGround] = 
       
  1873                     aWmmParamElem.iAcParams[i].TxOpLimit();
       
  1874                 (aCtxImpl.AcmVector())[WHA::EBackGround] = 
       
  1875                     ( aWmmParamElem.iAcParams[i].AdmissionControlMandatory() )? 
       
  1876                         ETrue : EFalse;
       
  1877 
       
  1878                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1879                     ("UMAC: aCntrl mandatory: %d"), 
       
  1880                     aWmmParamElem.iAcParams[i].AdmissionControlMandatory());
       
  1881                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1882                     ("UMAC: cwmin: %d"), (aCtxImpl.CwMinVector())[WHA::EBackGround]);
       
  1883                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1884                     ("UMAC: cwmax: %d"), (aCtxImpl.CwMaxVector())[WHA::EBackGround]);
       
  1885                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1886                     ("UMAC: aifsn: %d"), (aCtxImpl.AifsVector())[WHA::EBackGround]);
       
  1887                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1888                     ("UMAC: txOpLimit: %d"), (aCtxImpl.TxOplimitVector())[WHA::EBackGround]);    
       
  1889                     
       
  1890                 if ( !AcParametersValid( aCtxImpl, WHA::EBackGround ) )
       
  1891                     {
       
  1892                     OsTracePrint( KUmacDetails, (TUint8*)
       
  1893                         ("UMAC: WlanDot11State::ParseAcParameters: BG parameters not reasonble. Resetting to defaults") );
       
  1894                     ResetAcParameters( 
       
  1895                         aCtxImpl, 
       
  1896                         WHA::EBackGround, 
       
  1897                         aCtxImpl.ErpIePresent() );
       
  1898                     }
       
  1899                 break;
       
  1900             case EAcVideo:
       
  1901                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1902                     ("UMAC: WlanDot11State::ParseAcParameters: parsing video AC parameters"));
       
  1903                 (aCtxImpl.CwMinVector())[WHA::EVideo] = 
       
  1904                     aWmmParamElem.iAcParams[i].CwMin();
       
  1905                 (aCtxImpl.CwMaxVector())[WHA::EVideo] = 
       
  1906                     aWmmParamElem.iAcParams[i].CwMax();
       
  1907                 (aCtxImpl.AifsVector())[WHA::EVideo] = 
       
  1908                     aWmmParamElem.iAcParams[i].Aifsn();
       
  1909                 (aCtxImpl.TxOplimitVector())[WHA::EVideo] = 
       
  1910                     aWmmParamElem.iAcParams[i].TxOpLimit();
       
  1911                 (aCtxImpl.AcmVector())[WHA::EVideo] = 
       
  1912                     ( aWmmParamElem.iAcParams[i].AdmissionControlMandatory() )? 
       
  1913                         ETrue : EFalse;
       
  1914                 
       
  1915                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1916                     ("UMAC: aCntrl mandatory: %d"), 
       
  1917                     aWmmParamElem.iAcParams[i].AdmissionControlMandatory());
       
  1918                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1919                     ("UMAC: cwmin: %d"), (aCtxImpl.CwMinVector())[WHA::EVideo]);
       
  1920                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1921                     ("UMAC: cwmax: %d"), (aCtxImpl.CwMaxVector())[WHA::EVideo]);
       
  1922                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1923                     ("UMAC: aifsn: %d"), (aCtxImpl.AifsVector())[WHA::EVideo]);
       
  1924                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1925                     ("UMAC: txOpLimit: %d"), (aCtxImpl.TxOplimitVector())[WHA::EVideo]);    
       
  1926                     
       
  1927                 if ( !AcParametersValid( aCtxImpl, WHA::EVideo ) )
       
  1928                     {
       
  1929                     OsTracePrint( KUmacDetails, (TUint8*)
       
  1930                         ("UMAC: WlanDot11State::ParseAcParameters: VI parameters not reasonble. Resetting to defaults") );
       
  1931                     ResetAcParameters( 
       
  1932                         aCtxImpl, 
       
  1933                         WHA::EVideo, 
       
  1934                         aCtxImpl.ErpIePresent() );
       
  1935                     }
       
  1936                 break;
       
  1937             case EAcVoice:
       
  1938                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1939                     ("UMAC: WlanDot11State::ParseAcParameters: parsing voice AC parameters"));
       
  1940                 (aCtxImpl.CwMinVector())[WHA::EVoice] = 
       
  1941                     aWmmParamElem.iAcParams[i].CwMin();
       
  1942                 (aCtxImpl.CwMaxVector())[WHA::EVoice] = 
       
  1943                     aWmmParamElem.iAcParams[i].CwMax();
       
  1944                 (aCtxImpl.AifsVector())[WHA::EVoice] = 
       
  1945                     aWmmParamElem.iAcParams[i].Aifsn();
       
  1946                 (aCtxImpl.TxOplimitVector())[WHA::EVoice] = 
       
  1947                     aWmmParamElem.iAcParams[i].TxOpLimit();
       
  1948                 (aCtxImpl.AcmVector())[WHA::EVoice] = 
       
  1949                     ( aWmmParamElem.iAcParams[i].AdmissionControlMandatory() )? 
       
  1950                         ETrue : EFalse;
       
  1951                     
       
  1952                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1953                     ("UMAC: aCntrl mandatory: %d"), 
       
  1954                     aWmmParamElem.iAcParams[i].AdmissionControlMandatory());
       
  1955                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1956                     ("UMAC: cwmin: %d"), (aCtxImpl.CwMinVector())[WHA::EVoice]);
       
  1957                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1958                     ("UMAC: cwmax: %d"), (aCtxImpl.CwMaxVector())[WHA::EVoice]);
       
  1959                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1960                     ("UMAC: aifsn: %d"), (aCtxImpl.AifsVector())[WHA::EVoice]);
       
  1961                 OsTracePrint( KUmacDetails, (TUint8*)
       
  1962                     ("UMAC: txOpLimit: %d"), (aCtxImpl.TxOplimitVector())[WHA::EVoice]);    
       
  1963                     
       
  1964                 if ( !AcParametersValid( aCtxImpl, WHA::EVoice ) )
       
  1965                     {
       
  1966                     OsTracePrint( KUmacDetails, (TUint8*)
       
  1967                         ("UMAC: WlanDot11State::ParseAcParameters: VO parameters not reasonble. Resetting to defaults") );
       
  1968                     ResetAcParameters( 
       
  1969                         aCtxImpl, 
       
  1970                         WHA::EVoice, 
       
  1971                         aCtxImpl.ErpIePresent() );
       
  1972                     }
       
  1973                 break;
       
  1974             default:
       
  1975                 OsTracePrint( KWarningLevel, 
       
  1976                     (TUint8*)("UMAC: WARNING: Unknown AC: %d => parameters ignored"), 
       
  1977                     aWmmParamElem.iAcParams[i].AccessCategory() );        
       
  1978             }        
       
  1979         }
       
  1980         
       
  1981     // store the current Parameter Set Count. 
       
  1982     aCtxImpl.WmmParameterSetCount( aWmmParamElem.ParameterSetCount() );
       
  1983     OsTracePrint( KUmacDetails, (TUint8*)
       
  1984         ("UMAC: WlanDot11State::ParseAcParameters: param set cnt: %d"), 
       
  1985         aCtxImpl.WmmParameterSetCount() );    
       
  1986     }
       
  1987     
       
  1988 // -----------------------------------------------------------------------------
       
  1989 // 
       
  1990 // -----------------------------------------------------------------------------
       
  1991 //
       
  1992 TBool WlanDot11State::AddTkIPKey( 
       
  1993     WlanContextImpl& aCtxImpl,
       
  1994     const TUint8* aData, 
       
  1995     TUint32 /*aLength*/,
       
  1996     T802Dot11WepKeyId aKeyIndex, 
       
  1997     const TMacAddress& aMacAddr )
       
  1998     {    
       
  1999     TBool ret( EFalse );
       
  2000     WlanWsaAddKey& wsa_cmd( aCtxImpl.WsaAddKey() );    
       
  2001     WHA::STkipPairwiseKey* key( CreateTkipPtkCtx( 
       
  2002         aCtxImpl, 
       
  2003         wsa_cmd,
       
  2004         aData, 
       
  2005         aKeyIndex, 
       
  2006         aMacAddr ) 
       
  2007         );
       
  2008 
       
  2009     if ( key )
       
  2010         {
       
  2011         ret = ETrue;       
       
  2012         // change global state: entry procedure triggers action
       
  2013         ChangeState( aCtxImpl, 
       
  2014             *this,              // prev state
       
  2015             wsa_cmd,            // next state
       
  2016             // the ACT
       
  2017             KCompleteManagementRequest
       
  2018             );   
       
  2019 
       
  2020         os_free( key ); // allways remember to release the memory
       
  2021         }
       
  2022     else
       
  2023         {
       
  2024         // allocation failed
       
  2025         // simulate macnotresponding error
       
  2026         OsTracePrint( KWarningLevel, (TUint8*)
       
  2027             ("UMAC: WlanDot11State::AddTkIPKey(): memory allocation failed") );
       
  2028         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  2029         }
       
  2030 
       
  2031     return ret;
       
  2032     }
       
  2033 
       
  2034 // -----------------------------------------------------------------------------
       
  2035 // 
       
  2036 // -----------------------------------------------------------------------------
       
  2037 //
       
  2038 void WlanDot11State::StoreTxRatePolicyInfo( 
       
  2039     WlanContextImpl& aCtxImpl,
       
  2040     const TTxRatePolicy& aRatePolicy,
       
  2041     const TQueue2RateClass& aQueue2RateClass,
       
  2042     const TInitialMaxTxRate4RateClass& aInitialMaxTxRate4RateClass,
       
  2043     const TTxAutoRatePolicy& aAutoRatePolicy,
       
  2044     const THtMcsPolicy& aHtMcsPolicy )
       
  2045     {
       
  2046     OsTracePrint( KTxRateAdapt, (TUint8*)
       
  2047         ("UMAC: WlanDot11State::StoreTxRatePolicyInfo: store provided Tx rate policy configuration data for later use"));
       
  2048 
       
  2049     TTxRatePolicy& ratePolicy = aCtxImpl.RatePolicy();
       
  2050     os_memcpy( &ratePolicy, &aRatePolicy, sizeof( TTxRatePolicy ) );
       
  2051 
       
  2052     TQueue2RateClass& queue2RateClass = aCtxImpl.Queue2RateClass();
       
  2053     os_memcpy( &queue2RateClass, &aQueue2RateClass, sizeof( TQueue2RateClass ) );
       
  2054 
       
  2055     TInitialMaxTxRate4RateClass& initialMaxTxRate4RateClass = 
       
  2056         aCtxImpl.InitialMaxTxRate4RateClass();
       
  2057     os_memcpy( 
       
  2058         &initialMaxTxRate4RateClass, 
       
  2059         &aInitialMaxTxRate4RateClass, 
       
  2060         sizeof( TInitialMaxTxRate4RateClass ) );    
       
  2061 
       
  2062     TTxAutoRatePolicy& autoRatePolicy = aCtxImpl.AutoRatePolicy();
       
  2063     os_memcpy( &autoRatePolicy, &aAutoRatePolicy, sizeof( TTxAutoRatePolicy ) );
       
  2064     
       
  2065     THtMcsPolicy& htMcsPolicy = aCtxImpl.HtMcsPolicy();
       
  2066     os_memcpy( &htMcsPolicy, &aHtMcsPolicy, sizeof( THtMcsPolicy ) );    
       
  2067     }
       
  2068 
       
  2069 // -----------------------------------------------------------------------------
       
  2070 // 
       
  2071 // -----------------------------------------------------------------------------
       
  2072 //
       
  2073 TBool WlanDot11State::ConfigureTxRatePolicies( 
       
  2074     WlanContextImpl& aCtxImpl, 
       
  2075     TBool aCompleteMgmtRequest )
       
  2076     {
       
  2077     OsTracePrint( KTxRateAdapt, (TUint8*)
       
  2078         ("UMAC: WlanDot11State::ConfigureTxRatePolicies: rate bitmask (intersection of AP and our supported rates): 0x%08x"),
       
  2079         aCtxImpl.RateBitMask() );
       
  2080     OsTracePrint( KTxRateAdapt, (TUint8*)
       
  2081         ("UMAC: WlanDot11State::ConfigureTxRatePolicies: aCompleteMgmtRequest: %d"),
       
  2082         aCompleteMgmtRequest );
       
  2083 
       
  2084     TBool status ( ETrue );
       
  2085     // retrieve reference to the stored rate policy
       
  2086     TTxRatePolicy& ratePolicy ( aCtxImpl.RatePolicy() );
       
  2087     // retrieve reference to the stored Tx queue 2 Rate Class mapping
       
  2088     TQueue2RateClass& queue2RateClass ( aCtxImpl.Queue2RateClass() );
       
  2089     // retrieve reference to the stored initial max Tx rate per rate class -
       
  2090     // information
       
  2091     TInitialMaxTxRate4RateClass& initialMaxTxRate4RateClass( 
       
  2092         aCtxImpl.InitialMaxTxRate4RateClass() );
       
  2093     // retrieve reference to the stored auto rate policy
       
  2094     TTxAutoRatePolicy& autoRatePolicy ( aCtxImpl.AutoRatePolicy() );
       
  2095     // retrieve reference to the stored HT MCS policy
       
  2096     THtMcsPolicy& htMcsPolicy ( aCtxImpl.HtMcsPolicy() );
       
  2097 
       
  2098     if ( aCtxImpl.WHASettings().iNumOfTxRateClasses < 
       
  2099          ratePolicy.numOfPolicyObjects )
       
  2100         {
       
  2101         // WHA layer doesn't support as many rate classes as has been
       
  2102         // provided to us. 
       
  2103         
       
  2104         ResortToSingleTxRatePolicy(
       
  2105             aCtxImpl,
       
  2106             ratePolicy,
       
  2107             queue2RateClass );
       
  2108         }
       
  2109 
       
  2110     TWhaRateMasks rateMasks;
       
  2111     os_memset( rateMasks, 0, sizeof( rateMasks ) );
       
  2112  
       
  2113     FinalizeTxRatePolicy(
       
  2114         aCtxImpl,
       
  2115         ratePolicy,
       
  2116         rateMasks,
       
  2117         initialMaxTxRate4RateClass );
       
  2118 
       
  2119     if ( aCtxImpl.WHASettings().iCapability & 
       
  2120          WHA::SSettings::KAutonomousRateAdapt )
       
  2121         {
       
  2122         //=====================================================================
       
  2123         // lower layer supports autonomous rate adaptation so we will let it
       
  2124         // handle the rate adaptation. 
       
  2125         //=====================================================================
       
  2126         
       
  2127         FinalizeTxAutoratePolicy(
       
  2128             aCtxImpl,
       
  2129             ratePolicy,
       
  2130             autoRatePolicy );
       
  2131  
       
  2132         SpecialTxAutoratePolicy(
       
  2133             aCtxImpl,
       
  2134             ratePolicy,
       
  2135             autoRatePolicy,
       
  2136             htMcsPolicy );
       
  2137 
       
  2138         ConfigureForTxAutoratePolicy(
       
  2139             aCtxImpl,
       
  2140             ratePolicy,
       
  2141             queue2RateClass,
       
  2142             htMcsPolicy,
       
  2143             aCompleteMgmtRequest );
       
  2144         }
       
  2145     else
       
  2146         {
       
  2147         //=====================================================================
       
  2148         // WHA layer doesn't support autonomous rate adaptation so we need to
       
  2149         // take care of rate adaption. Perform the relevant configuration
       
  2150         //=====================================================================
       
  2151         
       
  2152         status = ConfigureForTxRatePolicy(
       
  2153             aCtxImpl,
       
  2154             ratePolicy,
       
  2155             rateMasks,
       
  2156             queue2RateClass,
       
  2157             initialMaxTxRate4RateClass,
       
  2158             aCompleteMgmtRequest );
       
  2159         } // else
       
  2160 
       
  2161     return status;
       
  2162     }
       
  2163 
       
  2164 // -----------------------------------------------------------------------------
       
  2165 // 
       
  2166 // -----------------------------------------------------------------------------
       
  2167 //
       
  2168 TBool WlanDot11State::DifferenceInPsModeWakeupSettings(
       
  2169     const WlanContextImpl& aCtxImpl ) const
       
  2170     {
       
  2171     TBool difference( EFalse );
       
  2172     
       
  2173     // 1st determine the current PS mode wake-up setting
       
  2174 
       
  2175     const WHA::TWlanWakeUpInterval currentWakeupMode ( 
       
  2176         aCtxImpl.iWlanMib.iWlanWakeupInterval );
       
  2177     const TUint8 currentListenInterval ( 
       
  2178         aCtxImpl.iWlanMib.iWlanListenInterval );
       
  2179     
       
  2180     // and the desired wake-up setting
       
  2181     const TDot11PsModeWakeupSetting KDesiredPsModeConfig (
       
  2182         aCtxImpl.DesiredPsModeConfig() );
       
  2183     
       
  2184     if ( currentWakeupMode != 
       
  2185          static_cast<WHA::TWlanWakeUpInterval>(
       
  2186              KDesiredPsModeConfig.iWakeupMode) )
       
  2187         {
       
  2188         // difference in wake-up mode
       
  2189         difference = ETrue;
       
  2190 
       
  2191         OsTracePrint( KPwrStateTransition, (TUint8*)
       
  2192             ("UMAC: WlanDot11State::DifferenceInPsModeWakeupSettings: difference in wake-up mode") );
       
  2193         }
       
  2194     else
       
  2195         {
       
  2196         // wake-up mode is unchanged
       
  2197         
       
  2198         if ( KDesiredPsModeConfig.iWakeupMode 
       
  2199              == EWakeUpIntervalEveryNthBeacon || 
       
  2200              KDesiredPsModeConfig.iWakeupMode 
       
  2201              == EWakeUpIntervalEveryNthDtim )
       
  2202             {
       
  2203             // for these wake-up modes there can be a
       
  2204             // difference in the listen interval. Check that
       
  2205             if ( currentListenInterval != KDesiredPsModeConfig.iListenInterval )
       
  2206                 {
       
  2207                 difference = ETrue;
       
  2208 
       
  2209                 OsTracePrint( KPwrStateTransition, (TUint8*)
       
  2210                     ("UMAC: WlanDot11State::DifferenceInPsModeWakeupSettings: difference in listen interval") );
       
  2211                 }
       
  2212             else
       
  2213                 {
       
  2214                 // no difference in listen interval either
       
  2215                 // (return value is already correct)
       
  2216                 }
       
  2217             }
       
  2218         else
       
  2219             {
       
  2220             // for these wake-up modes a possible difference in listen
       
  2221             // interval is not meaningful => no difference (return 
       
  2222             // value is already correct)
       
  2223             }
       
  2224         }
       
  2225 
       
  2226     OsTracePrint( KPwrStateTransition, (TUint8*)
       
  2227         ("UMAC: WlanDot11State::DifferenceInPsModeWakeupSettings: difference: %d"),
       
  2228         difference );
       
  2229         
       
  2230     return difference;
       
  2231     }
       
  2232 
       
  2233 // -----------------------------------------------------------------------------
       
  2234 // 
       
  2235 // -----------------------------------------------------------------------------
       
  2236 //
       
  2237 TBool WlanDot11State::ConfigureHtCapabilities( 
       
  2238     WlanContextImpl& aCtxImpl )
       
  2239     {
       
  2240     OsTracePrint( KUmacDetails, (TUint8*)
       
  2241         ("UMAC: WlanDot11State::ConfigureHtCapabilities") );
       
  2242 
       
  2243     // allocate memory for the mib to write
       
  2244     WHA::ShtCapabilities* mib 
       
  2245         = static_cast<WHA::ShtCapabilities*>
       
  2246         (os_alloc( sizeof( WHA::ShtCapabilities ) )); 
       
  2247 
       
  2248     if ( !mib )
       
  2249         {
       
  2250         // allocation failed
       
  2251         // simulate macnotresponding error
       
  2252         OsTracePrint( KWarningLevel, (TUint8*)
       
  2253             ("UMAC: WlanDot11State::ConfigureHtCapabilities: abort") );
       
  2254         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  2255         }
       
  2256 
       
  2257     // reset MIB before starting to set the values
       
  2258     os_memset( mib, 0, sizeof( WHA::ShtCapabilities ) );
       
  2259 
       
  2260     //=====================
       
  2261     // Set the MIB contents
       
  2262     //=====================
       
  2263     
       
  2264     mib->iHtSupport = aCtxImpl.HtSupportedByNw();
       
  2265 
       
  2266     // currently HT is supported only in infrastructure networks
       
  2267     mib->iPeerMac = WHA::KBroadcastMacAddr;
       
  2268 
       
  2269     mib->iRxStbc = aCtxImpl.GetNwHtCapabilitiesIe().iData.StbcRx();
       
  2270 
       
  2271     mib->iMaxAmpduLength = 
       
  2272         aCtxImpl.GetNwHtCapabilitiesIe().iData.MaxAmpduLenExponent();
       
  2273 
       
  2274     // if a feature is supported by the nw, set it in the capabilities bit
       
  2275     // mask. Otherwise it is left unset
       
  2276     
       
  2277     if ( aCtxImpl.GetNwHtCapabilitiesIe().iData.LdpcRx() )
       
  2278         {
       
  2279         mib->iPeerFeatures |= WHA::KLdpcRx;
       
  2280         }    
       
  2281     if ( aCtxImpl.GetNwHtCapabilitiesIe().iData.FortyMhzOperation() )
       
  2282         {
       
  2283         mib->iPeerFeatures |= WHA::K40MhzChannel;
       
  2284         }
       
  2285     if ( aCtxImpl.GetNwHtCapabilitiesIe().iData.GreenfieldFormat() )
       
  2286         {
       
  2287         mib->iPeerFeatures |= WHA::KGreenfieldFormat;
       
  2288         }
       
  2289     if ( aCtxImpl.GetNwHtCapabilitiesIe().iData.ShortGiFor20Mhz() )
       
  2290         {
       
  2291         mib->iPeerFeatures |= WHA::KShortGiFor20Mhz;
       
  2292         }
       
  2293     if ( aCtxImpl.GetNwHtCapabilitiesIe().iData.ShortGiFor40Mhz() )
       
  2294         {
       
  2295         mib->iPeerFeatures |= WHA::KShortGiFor40Mhz;
       
  2296         }
       
  2297     if ( aCtxImpl.GetNwHtCapabilitiesIe().iData.StbcTx() )
       
  2298         {
       
  2299         mib->iPeerFeatures |= WHA::KStbcTx;
       
  2300         }
       
  2301     if ( aCtxImpl.GetNwHtCapabilitiesIe().iData.DelayedBlockAck() )
       
  2302         {
       
  2303         mib->iPeerFeatures |= WHA::KDelayedBlockAck;
       
  2304         }
       
  2305     if ( aCtxImpl.GetNwHtCapabilitiesIe().iData.DsssCckIn40Mhz() )
       
  2306         {
       
  2307         mib->iPeerFeatures |= WHA::KDsssCckIn40Mhz;
       
  2308         }
       
  2309     if ( aCtxImpl.GetNwHtCapabilitiesIe().iData.Psmp() )
       
  2310         {
       
  2311         mib->iPeerFeatures |= WHA::KPsmp;
       
  2312         }
       
  2313     if ( aCtxImpl.GetNwHtCapabilitiesIe().iData.LsigTxopProtection() )
       
  2314         {
       
  2315         mib->iPeerFeatures |= WHA::KLsigTxopProtection;
       
  2316         }
       
  2317     if ( aCtxImpl.GetNwHtCapabilitiesIe().iData.Pco() )
       
  2318         {
       
  2319         mib->iPeerFeatures |= WHA::KPco;
       
  2320         }
       
  2321     if ( aCtxImpl.GetNwHtCapabilitiesIe().iData.Htc() )
       
  2322         {
       
  2323         mib->iPeerFeatures |= WHA::KHtcField;
       
  2324         }
       
  2325     if ( aCtxImpl.GetNwHtCapabilitiesIe().iData.RdResponder() )
       
  2326         {
       
  2327         mib->iPeerFeatures |= WHA::KReverseDirectionResp;
       
  2328         }
       
  2329 
       
  2330     os_memcpy( 
       
  2331         mib->iMcsSet, 
       
  2332         aCtxImpl.GetNwHtCapabilitiesIe().iData.iRxMcsBitmask,
       
  2333         sizeof( mib->iMcsSet ) );
       
  2334 
       
  2335     mib->iAmpduSpacing = 
       
  2336         aCtxImpl.GetNwHtCapabilitiesIe().iData.MinMpduStartSpacing();
       
  2337 
       
  2338     mib->iMcsFeedback = aCtxImpl.GetNwHtCapabilitiesIe().iData.McsFeedback();
       
  2339 
       
  2340     mib->iTxBeamFormingCapab = 
       
  2341         aCtxImpl.GetNwHtCapabilitiesIe().iData.TransmitBeamformingCapabilities();
       
  2342 
       
  2343     mib->iAntennaSelCapab = 
       
  2344         aCtxImpl.GetNwHtCapabilitiesIe().iData.AselCapabilities();
       
  2345 
       
  2346     WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
       
  2347         
       
  2348     wha_cmd.Set( 
       
  2349         aCtxImpl, 
       
  2350         WHA::KMibHtCapabilities, 
       
  2351         sizeof(*mib), mib );
       
  2352         
       
  2353     // change global state: entry procedure triggers action
       
  2354     ChangeState( aCtxImpl, 
       
  2355         *this,              // prev state
       
  2356         wha_cmd             // next state
       
  2357         );   
       
  2358 
       
  2359     os_free( mib ); // release the memory
       
  2360 
       
  2361     // signal caller that a state transition occurred
       
  2362     return ETrue;    
       
  2363     }
       
  2364 
       
  2365 // ---------------------------------------------------------
       
  2366 // 
       
  2367 // ---------------------------------------------------------
       
  2368 //
       
  2369 void WlanDot11State::ResetHtCapabilitiesMib( 
       
  2370     WlanContextImpl& aCtxImpl )
       
  2371     {
       
  2372     OsTracePrint( KUmacDetails, (TUint8*)
       
  2373         ("UMAC: WlanDot11State::ResetHtCapabilitiesMib") );
       
  2374 
       
  2375     // allocate memory for the mib to write
       
  2376     WHA::ShtCapabilities* mib 
       
  2377         = static_cast<WHA::ShtCapabilities*>
       
  2378         (os_alloc( sizeof( WHA::ShtCapabilities ) )); 
       
  2379 
       
  2380     if ( !mib )
       
  2381         {
       
  2382         // allocation failed
       
  2383         // simulate macnotresponding error
       
  2384         OsTracePrint( KWarningLevel, (TUint8*)
       
  2385             ("UMAC: WlanDot11State::ResetHtCapabilitiesMib: abort") );
       
  2386         DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  2387         }
       
  2388 
       
  2389     // reset the MIB to its default value
       
  2390     *mib = WHA::KHtCapabilitiesMibDefault;
       
  2391         
       
  2392     WlanWsaWriteMib& wsa_cmd = aCtxImpl.WsaWriteMib();
       
  2393         
       
  2394     wsa_cmd.Set( 
       
  2395         aCtxImpl, WHA::KMibHtCapabilities, sizeof( *mib ), mib );
       
  2396         
       
  2397     // change global state: entry procedure triggers action
       
  2398     ChangeState( aCtxImpl, 
       
  2399         *this,              // prev state
       
  2400         wsa_cmd             // next state
       
  2401         );
       
  2402     
       
  2403     os_free( mib ); // release the memory
       
  2404     }
       
  2405 
       
  2406 // ---------------------------------------------------------
       
  2407 // 
       
  2408 // ---------------------------------------------------------
       
  2409 //
       
  2410 void WlanDot11State::ResetHtBlockAckConfigureMib( 
       
  2411     WlanContextImpl& aCtxImpl )
       
  2412     {
       
  2413     OsTracePrint( KUmacDetails, (TUint8*)
       
  2414         ("UMAC: WlanDot11State::ResetHtBlockAckConfigureMib") );
       
  2415 
       
  2416     // allocate memory for the mib to write
       
  2417     WHA::ShtBlockAckConfigure* mib 
       
  2418         = static_cast<WHA::ShtBlockAckConfigure*>
       
  2419         (os_alloc( sizeof( WHA::ShtBlockAckConfigure ) )); 
       
  2420 
       
  2421     if ( !mib )
       
  2422         {
       
  2423         // allocation failed
       
  2424         // simulate macnotresponding error
       
  2425         OsTracePrint( KWarningLevel, (TUint8*)
       
  2426             ("UMAC: WlanDot11State::ResetHtBlockAckConfigureMib: abort") );
       
  2427         DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  2428         }
       
  2429     
       
  2430     // reset the MIB to its default value
       
  2431     *mib = WHA::KHtBlockAckConfigureMibDefault;
       
  2432         
       
  2433     WlanWsaWriteMib& wsa_cmd = aCtxImpl.WsaWriteMib();
       
  2434         
       
  2435     wsa_cmd.Set( 
       
  2436         aCtxImpl, WHA::KMibHtBlockAckConfigure, sizeof( *mib ), mib );
       
  2437         
       
  2438     // change global state: entry procedure triggers action
       
  2439     ChangeState( aCtxImpl, 
       
  2440         *this,              // prev state
       
  2441         wsa_cmd             // next state
       
  2442         );
       
  2443 
       
  2444     os_free( mib ); // release the memory
       
  2445     }
       
  2446 
       
  2447 // -----------------------------------------------------------------------------
       
  2448 // 
       
  2449 // -----------------------------------------------------------------------------
       
  2450 //
       
  2451 TBool WlanDot11State::ConfigureHtBssOperation( 
       
  2452     WlanContextImpl& aCtxImpl )
       
  2453     {
       
  2454     OsTracePrint( KUmacDetails, (TUint8*)
       
  2455         ("UMAC: WlanDot11State::ConfigureHtBssOperation") );
       
  2456 
       
  2457     // allocate memory for the mib to write
       
  2458     WHA::ShtBssOperation* mib 
       
  2459         = static_cast<WHA::ShtBssOperation*>
       
  2460         (os_alloc( sizeof( WHA::ShtBssOperation ) )); 
       
  2461 
       
  2462     if ( !mib )
       
  2463         {
       
  2464         // allocation failed
       
  2465         // simulate macnotresponding error
       
  2466         OsTracePrint( KWarningLevel, (TUint8*)
       
  2467             ("UMAC: WlanDot11State::ConfigureHtBssOperation: abort") );
       
  2468         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  2469         }
       
  2470 
       
  2471     // reset MIB before starting to set the values
       
  2472     os_memset( mib, 0, sizeof( WHA::ShtBssOperation ) );
       
  2473 
       
  2474     //=====================
       
  2475     // Set the MIB contents
       
  2476     //=====================
       
  2477     
       
  2478     if ( aCtxImpl.GetNwHtOperationIe().iData.NonGreenfieldPresent() )
       
  2479         {
       
  2480         mib->iInfo |= WHA::ShtBssOperation::KNonGreenfieldPresent;
       
  2481         }
       
  2482     if ( aCtxImpl.GetNwHtOperationIe().iData.PcoActive() )
       
  2483         {
       
  2484         mib->iInfo |= WHA::ShtBssOperation::KPcoActive;
       
  2485         }
       
  2486     if ( aCtxImpl.GetNwHtOperationIe().iData.RifsMode() )
       
  2487         {
       
  2488         mib->iInfo |= WHA::ShtBssOperation::KRifsPermitted;
       
  2489         }
       
  2490     if ( aCtxImpl.GetNwHtOperationIe().iData.DualCtsProtection() )
       
  2491         {
       
  2492         mib->iInfo |= WHA::ShtBssOperation::KDualCtsProtReq;
       
  2493         }
       
  2494     if ( aCtxImpl.GetNwHtOperationIe().iData.DualBeacon() )
       
  2495         {
       
  2496         mib->iInfo |= WHA::ShtBssOperation::KSecondaryBeaconTx;
       
  2497         }
       
  2498     if ( aCtxImpl.GetNwHtOperationIe().iData.LsigTxopProtection() )
       
  2499         {
       
  2500         mib->iInfo |= WHA::ShtBssOperation::KLsigTxopProtection;
       
  2501         }
       
  2502 
       
  2503     os_memcpy( 
       
  2504         mib->iMcsSet, 
       
  2505         aCtxImpl.GetNwHtOperationIe().iData.iBasicMcsSet,
       
  2506         sizeof( mib->iMcsSet ) );
       
  2507 
       
  2508     mib->iOpMode = 
       
  2509         aCtxImpl.GetNwHtOperationIe().iData.HtProtection();
       
  2510 
       
  2511     mib->iSecChOffset = 
       
  2512         aCtxImpl.GetNwHtOperationIe().iData.SecondaryChOffset();
       
  2513 
       
  2514     mib->iApChWidth = 
       
  2515         aCtxImpl.GetNwHtOperationIe().iData.ChWidth();    
       
  2516 
       
  2517     WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
       
  2518         
       
  2519     wha_cmd.Set( 
       
  2520         aCtxImpl, 
       
  2521         WHA::KMibHtBssOperation, 
       
  2522         sizeof(*mib), mib );
       
  2523         
       
  2524     // change global state: entry procedure triggers action
       
  2525     ChangeState( aCtxImpl, 
       
  2526         *this,              // prev state
       
  2527         wha_cmd             // next state
       
  2528         );   
       
  2529 
       
  2530     os_free( mib ); // release the memory
       
  2531 
       
  2532     // signal caller that a state transition occurred
       
  2533     return ETrue;    
       
  2534     }
       
  2535 
       
  2536 // -----------------------------------------------------------------------------
       
  2537 // 
       
  2538 // -----------------------------------------------------------------------------
       
  2539 //
       
  2540 TBool WlanDot11State::HtcFieldPresent(
       
  2541     WlanContextImpl& aCtxImpl,
       
  2542     const TAny* aFrame,
       
  2543     TUint32 aFlags )
       
  2544     {
       
  2545     TBool status ( EFalse );
       
  2546     
       
  2547     if ( aCtxImpl.WHASettings().iCapability & WHA::SSettings::KHtOperation )
       
  2548         {
       
  2549         // we can interpret the frame to have this header even if it would
       
  2550         // be a 802.11 mgmt frame as the header content that is relevant in
       
  2551         // this method is the same
       
  2552         const SDataFrameHeader* frameHdr 
       
  2553             = reinterpret_cast<const SDataFrameHeader*>(aFrame);
       
  2554      
       
  2555         if ( aFlags & WHA::KHtPacket && frameHdr->IsOrderBitSet() )
       
  2556             {
       
  2557             status = ETrue;
       
  2558             OsTracePrint( KRxFrame, (TUint8*)
       
  2559                 ("UMAC: WlanDot11State::HtcFieldPresent: yes") );
       
  2560             }
       
  2561         }
       
  2562     
       
  2563     return status;
       
  2564     }
       
  2565 
       
  2566 // -----------------------------------------------------------------------------
       
  2567 // 
       
  2568 // -----------------------------------------------------------------------------
       
  2569 //
       
  2570 TBool WlanDot11State::OutgoingMulticastDataFrame( 
       
  2571     const SDataFrameHeader* aDataFrameHdr )
       
  2572     {
       
  2573     if ( aDataFrameHdr->IsToDsBitSet() )
       
  2574         {
       
  2575         // frame to infrastructure nw. Address 3 == DA
       
  2576         
       
  2577         return IsGroupBitSet( aDataFrameHdr->iAddress3 );
       
  2578         }
       
  2579     else
       
  2580         {
       
  2581         // frame to IBSS. Address 1 == DA
       
  2582         
       
  2583         return IsGroupBitSet( aDataFrameHdr->iAddress1 );
       
  2584         }
       
  2585     }
       
  2586 
       
  2587 // -----------------------------------------------------------------------------
       
  2588 // 
       
  2589 // -----------------------------------------------------------------------------
       
  2590 //
       
  2591 void WlanDot11State::UpdateTxDataFrameStatistics( 
       
  2592     WlanContextImpl& aCtxImpl,
       
  2593     WHA::TQueueId aAccessCategory,
       
  2594     WHA::TStatus aStatus,
       
  2595     TBool aMulticastData, 
       
  2596     TUint aAckFailures,
       
  2597     TUint32 aMediaDelay,
       
  2598     TUint aTotalTxDelay )
       
  2599     {
       
  2600     OsTracePrint( KWsaTxDetails, (TUint8*)
       
  2601         ("UMAC: WlanDot11State::UpdateTxDataFrameStatistics: aAccessCategory: %d"),
       
  2602         aAccessCategory );
       
  2603 
       
  2604     if ( aStatus == WHA::KSuccess )
       
  2605         {
       
  2606         if ( aMulticastData )
       
  2607             {
       
  2608             OsTracePrint( KWsaTxDetails, (TUint8*)
       
  2609                 ("UMAC: WlanDot11State::UpdateTxDataFrameStatistics: inc tx mcast cnt") );
       
  2610 
       
  2611             aCtxImpl.IncrementTxMulticastDataFrameCount( aAccessCategory );
       
  2612             }
       
  2613         else
       
  2614             {
       
  2615             OsTracePrint( KWsaTxDetails, (TUint8*)
       
  2616                 ("UMAC: WlanDot11State::UpdateTxDataFrameStatistics: inc tx unicast cnt") );
       
  2617 
       
  2618             aCtxImpl.IncrementTxUnicastDataFrameCount( aAccessCategory );
       
  2619             }
       
  2620             
       
  2621         OsTracePrint( KWsaTxDetails, (TUint8*)
       
  2622             ("UMAC: WlanDot11State::UpdateTxDataFrameStatistics: ack failures: %d"),
       
  2623             aAckFailures );
       
  2624 
       
  2625         aCtxImpl.IncrementTxRetryCount( aAccessCategory, aAckFailures );
       
  2626         
       
  2627         OsTracePrint( KWsaTxDetails, (TUint8*)
       
  2628             ("UMAC: WlanDot11State::UpdateTxDataFrameStatistics: aMediaDelay: %d"),
       
  2629             aMediaDelay );
       
  2630 
       
  2631         aCtxImpl.IncrementTxMediaDelay( aAccessCategory, aMediaDelay );
       
  2632         
       
  2633         OsTracePrint( KWsaTxDetails, (TUint8*)
       
  2634             ("UMAC: WlanDot11State::UpdateTxDataFrameStatistics: aTotalTxDelay: %d"),
       
  2635             aTotalTxDelay );
       
  2636 
       
  2637         aCtxImpl.IncrementTotalTxDelay( aAccessCategory, aTotalTxDelay );
       
  2638         
       
  2639         aCtxImpl.UpdateTotalTxDelayHistogram( aAccessCategory, aTotalTxDelay );
       
  2640         }
       
  2641     else
       
  2642         {
       
  2643         OsTracePrint( KWsaTxDetails, (TUint8*)
       
  2644             ("UMAC: WlanDot11State::UpdateTxDataFrameStatistics: inc tx error cnt") );
       
  2645         aCtxImpl.IncrementTxErrorCount( aAccessCategory );
       
  2646         }
       
  2647     }
       
  2648 
       
  2649 // -----------------------------------------------------------------------------
       
  2650 // 
       
  2651 // -----------------------------------------------------------------------------
       
  2652 //
       
  2653 TBool WlanDot11State::XferDot11FrameToMgmtClient( 
       
  2654     WlanContextImpl& aCtxImpl,
       
  2655     const void* aFrame,
       
  2656     TUint32 aLength,
       
  2657     const WHA::TRcpi aRcpi,
       
  2658     TUint8* aBuffer ) const
       
  2659     {
       
  2660     OsTracePrint( KRxFrame, (TUint8*)
       
  2661         ("UMAC: WlanDot11State::XferDot11FrameToMgmtClient: aRcpi: %d"), 
       
  2662         aRcpi);
       
  2663 
       
  2664     TBool status ( ETrue );
       
  2665     
       
  2666     TDataBuffer* metaHdr ( aCtxImpl.GetRxFrameMetaHeader() );
       
  2667     
       
  2668     if ( metaHdr )
       
  2669         {
       
  2670         // set frame length 
       
  2671         metaHdr->KeSetLength( aLength );
       
  2672 
       
  2673         // set frame type
       
  2674         metaHdr->FrameType( TDataBuffer::KDot11Frame );
       
  2675 
       
  2676         // set RCPI for every frame transferred to the mgmt client
       
  2677         metaHdr->KeSetRcpi( aRcpi );
       
  2678 
       
  2679         // set the offset to the beginning of the Rx buffer from the beginning
       
  2680         // of the meta header. Note that this may be also negative
       
  2681         metaHdr->KeSetBufferOffset(
       
  2682             aBuffer
       
  2683             - reinterpret_cast<TUint8*>(metaHdr) );
       
  2684         
       
  2685         // set the offset to the beginning of the actual frame within the
       
  2686         // Rx buffer
       
  2687         metaHdr->KeSetOffsetToFrameBeginning( 
       
  2688             reinterpret_cast<const TUint8*>(aFrame)   // frame beginning
       
  2689             - aBuffer );                              // buffer beginning
       
  2690                     
       
  2691         // complete
       
  2692         const TDataBuffer* KMetaHdr ( metaHdr );
       
  2693         aCtxImpl.iUmac.MgmtDataReceiveComplete( KMetaHdr, 1 );
       
  2694         }
       
  2695     else
       
  2696         {
       
  2697         // no memory available for the meta header. In this case we have no
       
  2698         // other choice than to discard the received frame. 
       
  2699         aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
  2700         // inform the caller about the situation
       
  2701         status = EFalse;
       
  2702         OsTracePrint( KWarningLevel | KRxFrame, (TUint8*)
       
  2703             ("UMAC: WlanDot11State::XferDot11FrameToMgmtClient: WARNING: no memory for meta hdr => abort rx") );
       
  2704         }
       
  2705         
       
  2706     return status;
       
  2707     }
       
  2708 
       
  2709 // -----------------------------------------------------------------------------
       
  2710 // 
       
  2711 // -----------------------------------------------------------------------------
       
  2712 //
       
  2713 TBool WlanDot11State::AddMulticastTKIPKey( 
       
  2714     WlanContextImpl& aCtxImpl,
       
  2715     T802Dot11WepKeyId aKeyIndex,
       
  2716     TUint32 /*aLength*/,
       
  2717     const TUint8* aData )
       
  2718     {        
       
  2719     // store info of TKIP GTK insertion
       
  2720     aCtxImpl.GroupKeyType( WHA::ETkipGroupKey );
       
  2721 
       
  2722     // allocate memory for the key structure
       
  2723     WHA::STkipGroupKey* key = static_cast<WHA::STkipGroupKey*>
       
  2724         (os_alloc( sizeof(WHA::STkipGroupKey) )); 
       
  2725 
       
  2726     if ( !key )
       
  2727         {
       
  2728         // allocation failed
       
  2729         // simulate macnotresponding error
       
  2730         OsTracePrint( KWarningLevel, 
       
  2731             (TUint8*)("UMAC: WlanDot11State::AddMulticastTKIPKey: memory allocation failed") );
       
  2732         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  2733         }
       
  2734 
       
  2735     os_memcpy( key->iTkipKey, aData, WHA::KTKIPKeyLength );
       
  2736     os_memcpy( key->iRxMicKey, aData + WHA::KTKIPKeyLength, KMicLength );
       
  2737     key->iKeyId =  static_cast<WHA::TPrivacyKeyId>(aKeyIndex);
       
  2738     // for now we fill this field with zeroes
       
  2739     os_memset( key->iRxSequenceCounter, 0, WHA::KRxSequenceCounterLength );
       
  2740     
       
  2741     WlanWsaAddKey& wsa_cmd = aCtxImpl.WsaAddKey();   
       
  2742     
       
  2743     wsa_cmd.Set( aCtxImpl, 
       
  2744         WHA::ETkipGroupKey,
       
  2745         key,
       
  2746         WlanWsaKeyIndexMapper::Extract( WHA::ETkipGroupKey ) );
       
  2747     
       
  2748     // change global state: entry procedure triggers action
       
  2749     ChangeState( aCtxImpl, 
       
  2750         *this,              // prev state
       
  2751         wsa_cmd,            // next state
       
  2752         // the ACT
       
  2753         KCompleteManagementRequest
       
  2754         );                           
       
  2755 
       
  2756     os_free( key ); // allways remember to release the memory
       
  2757 
       
  2758     // signal caller that a state transition occurred
       
  2759     return ETrue;
       
  2760     }
       
  2761 
       
  2762 // -----------------------------------------------------------------------------
       
  2763 // 
       
  2764 // -----------------------------------------------------------------------------
       
  2765 //
       
  2766 TBool WlanDot11State::AddAesKey( 
       
  2767     WlanContextImpl& aCtxImpl,
       
  2768     const TUint8* aData, 
       
  2769     TUint32 /*aLength*/,
       
  2770     const TMacAddress& aMacAddr )
       
  2771     {     
       
  2772     TBool ret( EFalse );
       
  2773     WlanWsaAddKey& wsa_cmd( aCtxImpl.WsaAddKey() );    
       
  2774     WHA::SAesPairwiseKey* key( CreateAesPtkCtx( 
       
  2775         aCtxImpl, 
       
  2776         wsa_cmd,
       
  2777         aData, 
       
  2778         aMacAddr ) 
       
  2779         );
       
  2780 
       
  2781     if ( key )
       
  2782         {
       
  2783         ret = ETrue;       
       
  2784         // change global state: entry procedure triggers action
       
  2785         ChangeState( aCtxImpl, 
       
  2786             *this,              // prev state
       
  2787             wsa_cmd,            // next state
       
  2788             // the ACT
       
  2789             KCompleteManagementRequest
       
  2790             );   
       
  2791 
       
  2792         os_free( key ); // allways remember to release the memory
       
  2793         }
       
  2794     else
       
  2795         {
       
  2796         // allocation failed
       
  2797         // simulate macnotresponding error
       
  2798         OsTracePrint( KWarningLevel, (TUint8*)
       
  2799             ("UMAC: WlanDot11State::AddAesKey(): memory allocation failed") );
       
  2800         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  2801         }
       
  2802 
       
  2803     return ret;
       
  2804     }
       
  2805 
       
  2806 // -----------------------------------------------------------------------------
       
  2807 // 
       
  2808 // -----------------------------------------------------------------------------
       
  2809 //
       
  2810 TBool WlanDot11State::AddMulticastAesKey( 
       
  2811     WlanContextImpl& aCtxImpl,
       
  2812     T802Dot11WepKeyId aKeyIndex,
       
  2813     TUint32 /*aLength*/,
       
  2814     const TUint8* aData )
       
  2815     {    
       
  2816     // store info of AES GTK insertion
       
  2817     aCtxImpl.GroupKeyType( WHA::EAesGroupKey );
       
  2818 
       
  2819     // allocate memory for the key structure
       
  2820     WHA::SAesGroupKey* key = static_cast<WHA::SAesGroupKey*>
       
  2821         ( os_alloc( sizeof( WHA::SAesGroupKey ) ) ); 
       
  2822 
       
  2823     if ( !key )
       
  2824         {
       
  2825         // allocation failed
       
  2826         // simulate macnotresponding error
       
  2827         OsTracePrint( KWarningLevel, (TUint8*)
       
  2828             ("UMAC: WlanDot11State::AddMulticastAesKey(): memory allocation failed") );
       
  2829         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  2830         }
       
  2831     
       
  2832     os_memcpy( key->iAesKey, aData, WHA::KAesKeyLength );
       
  2833     key->iKeyId =  static_cast<WHA::TPrivacyKeyId>(aKeyIndex);
       
  2834     // for now we fill this field with zeroes
       
  2835     os_memset( key->iRxSequenceCounter, 0, WHA::KRxSequenceCounterLength );
       
  2836     
       
  2837     WlanWsaAddKey& wsa_cmd = aCtxImpl.WsaAddKey();    
       
  2838     
       
  2839     wsa_cmd.Set( aCtxImpl, 
       
  2840         WHA::EAesGroupKey,
       
  2841         key,
       
  2842         WlanWsaKeyIndexMapper::Extract( WHA::EAesGroupKey ) );
       
  2843     
       
  2844     // change global state: entry procedure triggers action
       
  2845     ChangeState( aCtxImpl, 
       
  2846         *this,              // prev state
       
  2847         wsa_cmd,            // next state
       
  2848         // the ACT
       
  2849         KCompleteManagementRequest
       
  2850         );   
       
  2851 
       
  2852     os_free( key ); // allways remember to release the memory
       
  2853     
       
  2854     // signal caller that a state transition occurred
       
  2855     return ETrue;
       
  2856     }
       
  2857 
       
  2858 // -----------------------------------------------------------------------------
       
  2859 // 
       
  2860 // -----------------------------------------------------------------------------
       
  2861 //
       
  2862 TBool WlanDot11State::AddUnicastWepKey(
       
  2863     WlanContextImpl& aCtxImpl,
       
  2864     const TMacAddress& aMacAddr,
       
  2865     TUint32 aKeyLength,                      
       
  2866     const TUint8 aKey[KMaxWEPKeyLength])
       
  2867     {
       
  2868     // store info of WEP PTK insertion
       
  2869     aCtxImpl.PairWiseKeyType( WHA::EWepPairWiseKey );
       
  2870 
       
  2871     // allocate memory for the key structure
       
  2872     WHA::SWepPairwiseKey* key = static_cast<WHA::SWepPairwiseKey*>
       
  2873         (os_alloc( WHA::SWepPairwiseKey::KHeaderSize + aKeyLength )); 
       
  2874 
       
  2875     if ( !key )
       
  2876         {
       
  2877         // allocation failed
       
  2878         // simulate macnotresponding error
       
  2879         OsTracePrint( KWarningLevel, (TUint8*)
       
  2880             ("UMAC: WlanDot11State::AddUnicastWepKey(): memory allocation failed") );
       
  2881         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  2882         }
       
  2883 
       
  2884     os_memcpy( 
       
  2885         &(key->iMacAddr), 
       
  2886         aMacAddr.iMacAddress,
       
  2887         sizeof(key->iMacAddr) );
       
  2888     key->iKeyLengthInBytes = static_cast<TUint8>(aKeyLength);
       
  2889     os_memcpy( key->iKey, aKey, key->iKeyLengthInBytes );
       
  2890     
       
  2891     WlanWsaAddKey& wsa_cmd = aCtxImpl.WsaAddKey();    
       
  2892     wsa_cmd.Set( aCtxImpl, 
       
  2893         WHA::EWepPairWiseKey,
       
  2894         key,
       
  2895         WlanWsaKeyIndexMapper::Extract( WHA::EWepPairWiseKey ) );
       
  2896     
       
  2897     // change global state: entry procedure triggers action
       
  2898     ChangeState( aCtxImpl, 
       
  2899         *this,              // prev state
       
  2900         wsa_cmd,            // next state
       
  2901         // the ACT
       
  2902         KCompleteManagementRequest
       
  2903         );                           
       
  2904     
       
  2905     os_free( key ); // allways remember to release the memory
       
  2906 
       
  2907     // signal caller that a state transition occurred
       
  2908     return ETrue;
       
  2909     }
       
  2910 
       
  2911 // -----------------------------------------------------------------------------
       
  2912 // 
       
  2913 // -----------------------------------------------------------------------------
       
  2914 //
       
  2915 TBool WlanDot11State::OnAddBroadcastWepKey(
       
  2916     WlanContextImpl& aCtxImpl,
       
  2917     TUint32 aKeyIndex,             
       
  2918     TBool aUseAsDefaulKey,                
       
  2919     TBool aUseAsPairwiseKey,
       
  2920     TUint32 aKeyLength,                      
       
  2921     const TUint8 aKey[KMaxWEPKeyLength],
       
  2922     const TMacAddress& aMac )
       
  2923     { 
       
  2924     WlanAddBroadcastWepKey& complex_wha_cmd( 
       
  2925         aCtxImpl.AddBroadcastWepKey() );
       
  2926 
       
  2927     complex_wha_cmd.Set( aMac, aKeyIndex, aUseAsDefaulKey, 
       
  2928         aUseAsPairwiseKey, aKeyLength, aKey );
       
  2929             
       
  2930     // change global state: entry procedure triggers action
       
  2931     ChangeState( aCtxImpl, 
       
  2932         *this,              // prev state
       
  2933         complex_wha_cmd     // next state
       
  2934         ); 
       
  2935 
       
  2936     // signal caller that a state transition occurred
       
  2937     return ETrue;
       
  2938     }
       
  2939 
       
  2940 // -----------------------------------------------------------------------------
       
  2941 // 
       
  2942 // -----------------------------------------------------------------------------
       
  2943 //
       
  2944 TBool WlanDot11State::AddMulticastWapiKey( 
       
  2945     WlanContextImpl& aCtxImpl,
       
  2946     T802Dot11WepKeyId aKeyIndex,
       
  2947     TUint32 /*aLength*/,
       
  2948     const TUint8* aData )
       
  2949     {
       
  2950     if ( !(aCtxImpl.WHASettings().iCapability & WHA::SSettings::KWapi) )
       
  2951         {
       
  2952         // WAPI not supported by wlanpdd => abort key setting
       
  2953         
       
  2954         OsTracePrint( KWarningLevel, (TUint8*)
       
  2955             ("UMAC: WlanDot11State::AddMulticastWapiKey: WAPI not supported by wlanpdd -> abort") );
       
  2956 
       
  2957         OnOidComplete( aCtxImpl, KErrNotSupported );            
       
  2958         return EFalse;        
       
  2959         }
       
  2960 
       
  2961     // store info of WAPI group key insertion
       
  2962     aCtxImpl.GroupKeyType( WHA::EWapiGroupKey );
       
  2963 
       
  2964     // allocate memory for the key structure
       
  2965     WHA::SWapiGroupKey* key = static_cast<WHA::SWapiGroupKey*>
       
  2966         (os_alloc( sizeof(WHA::SWapiGroupKey) )); 
       
  2967 
       
  2968     if ( !key )
       
  2969         {
       
  2970         // allocation failed
       
  2971         // simulate macnotresponding error
       
  2972         OsTracePrint( KWarningLevel, 
       
  2973             (TUint8*)("UMAC: WlanDot11State::AddMulticastWapiKey: memory allocation failed") );
       
  2974         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  2975         }
       
  2976 
       
  2977     os_memcpy( key->iWapiKey, aData, WHA::KWapiKeyLength );
       
  2978 
       
  2979     os_memcpy( 
       
  2980         key->iMicKey, 
       
  2981         aData + WHA::KWapiKeyLength, 
       
  2982         WHA::KWapiMicKeyLength );
       
  2983 
       
  2984     key->iKeyId =  static_cast<WHA::TPrivacyKeyId>(aKeyIndex);
       
  2985     
       
  2986     WlanWsaAddKey& wsa_cmd = aCtxImpl.WsaAddKey();   
       
  2987     
       
  2988     wsa_cmd.Set( aCtxImpl, 
       
  2989         WHA::EWapiGroupKey,
       
  2990         key,
       
  2991         WlanWsaKeyIndexMapper::Extract( WHA::EWapiGroupKey ) );
       
  2992     
       
  2993     // change global state: entry procedure triggers action
       
  2994     ChangeState( aCtxImpl, 
       
  2995         *this,              // prev state
       
  2996         wsa_cmd,            // next state
       
  2997         // the ACT
       
  2998         KCompleteManagementRequest
       
  2999         );                           
       
  3000 
       
  3001     os_free( key ); // release the memory
       
  3002 
       
  3003     // signal caller that a state transition occurred
       
  3004     return ETrue;
       
  3005     }
       
  3006 
       
  3007 // -----------------------------------------------------------------------------
       
  3008 // 
       
  3009 // -----------------------------------------------------------------------------
       
  3010 //
       
  3011 TBool WlanDot11State::AddUnicastWapiKey( 
       
  3012     WlanContextImpl& aCtxImpl,
       
  3013     const TUint8* aData,
       
  3014     TUint32 /*aLength*/,
       
  3015     T802Dot11WepKeyId aKeyIndex,
       
  3016     const TMacAddress& aMacAddr )
       
  3017     {
       
  3018     TBool ret( EFalse );
       
  3019 
       
  3020     if ( !(aCtxImpl.WHASettings().iCapability & WHA::SSettings::KWapi) )
       
  3021         {
       
  3022         // WAPI not supported by wlanpdd => abort key setting
       
  3023         
       
  3024         OsTracePrint( KWarningLevel, (TUint8*)
       
  3025             ("UMAC: WlanDot11State::AddUnicastWapiKey: WAPI not supported by wlanpdd -> abort") );
       
  3026 
       
  3027         OnOidComplete( aCtxImpl, KErrNotSupported );            
       
  3028         return ret;        
       
  3029         }
       
  3030 
       
  3031     WlanWsaAddKey& wsa_cmd( aCtxImpl.WsaAddKey() );    
       
  3032 
       
  3033     WHA::SWapiPairwiseKey* key( CreateWapiPtkCtx( 
       
  3034         aCtxImpl, 
       
  3035         wsa_cmd,
       
  3036         aData, 
       
  3037         aKeyIndex, 
       
  3038         aMacAddr ) 
       
  3039         );
       
  3040 
       
  3041     if ( key )
       
  3042         {
       
  3043         ret = ETrue;       
       
  3044         // change global state: entry procedure triggers action
       
  3045         ChangeState( aCtxImpl, 
       
  3046             *this,              // prev state
       
  3047             wsa_cmd,            // next state
       
  3048             // the ACT
       
  3049             KCompleteManagementRequest
       
  3050             );   
       
  3051 
       
  3052         os_free( key ); // release the memory
       
  3053         }
       
  3054     else
       
  3055         {
       
  3056         // allocation failed
       
  3057         // simulate macnotresponding error
       
  3058         OsTracePrint( KWarningLevel, (TUint8*)
       
  3059             ("UMAC: WlanDot11State::AddUnicastWapiKey: memory allocation failed") );
       
  3060         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  3061         }
       
  3062 
       
  3063     return ret;
       
  3064     }
       
  3065 
       
  3066 // -----------------------------------------------------------------------------
       
  3067 // 
       
  3068 // -----------------------------------------------------------------------------
       
  3069 //
       
  3070 TBool WlanDot11State::InitNetworkConnect( 
       
  3071     WlanContextImpl& aCtxImpl,
       
  3072     TUint16 aScanResponseFrameBodyLength,
       
  3073     const TUint8* aScanResponseFrameBody ) const
       
  3074     {
       
  3075     OsTracePrint( KUmacDetails, 
       
  3076         (TUint8*)("UMAC: WlanDot11State::InitNetworkConnect") );
       
  3077 
       
  3078     const SScanResponseFixedFields* scanResponseFixedFields = 
       
  3079         reinterpret_cast<const SScanResponseFixedFields*>( 
       
  3080             aScanResponseFrameBody );
       
  3081 
       
  3082     // store capability info from scan response frame body to our context
       
  3083     aCtxImpl.GetCapabilityInformation() 
       
  3084         = scanResponseFixedFields->iCapability.CapabilityInformationField();
       
  3085 
       
  3086     // and set it also as the initial value to our association request frame 
       
  3087     // templates
       
  3088     aCtxImpl.GetAssociationRequestFrame().iFixedFields.iCapabilityInfo 
       
  3089         = aCtxImpl.GetCapabilityInformation();    
       
  3090     aCtxImpl.GetHtAssociationRequestFrame().iFixedFields.iCapabilityInfo 
       
  3091         = aCtxImpl.GetCapabilityInformation();    
       
  3092 
       
  3093     // ... and to to our reassociation request frame templates
       
  3094     aCtxImpl.GetReassociationRequestFrame().iFixedFields.iCapabilityInfo 
       
  3095         = aCtxImpl.GetCapabilityInformation();    
       
  3096     aCtxImpl.GetHtReassociationRequestFrame().iFixedFields.iCapabilityInfo 
       
  3097         = aCtxImpl.GetCapabilityInformation();        
       
  3098     
       
  3099     // use short slot time if supported by the network
       
  3100     aCtxImpl.UseShortSlotTime( 
       
  3101         aCtxImpl.GetCapabilityInformation().IsShortSlotTimeBitSet() );
       
  3102 
       
  3103     //=============================================
       
  3104     // check for WAPI
       
  3105     //=============================================
       
  3106     if ( aCtxImpl.EncryptionStatus() == EEncryptionWAPI && 
       
  3107          !(aCtxImpl.WHASettings().iCapability & WHA::SSettings::KWapi) )
       
  3108         {
       
  3109         OsTracePrint( KWarningLevel, (TUint8*)
       
  3110             ("UMAC: WlanDot11State::InitNetworkConnect: WAPI requested but not supported by wlanpdd -> abort") );
       
  3111         
       
  3112         return EFalse;
       
  3113         }
       
  3114         
       
  3115     //=============================================
       
  3116     // do we meet network capability requirements
       
  3117     //=============================================
       
  3118     
       
  3119     if ( !NetworkCapabilityInformationMet( aCtxImpl ) )
       
  3120         {
       
  3121         // requirements not met
       
  3122 
       
  3123         OsTracePrint( KWarningLevel, (TUint8*)
       
  3124             ("UMAC: WlanDot11State::InitNetworkConnect: network capabilities not met -> abort") );
       
  3125 
       
  3126         return EFalse;
       
  3127         }
       
  3128 
       
  3129     // network capabilities are met -> proceed
       
  3130 
       
  3131 
       
  3132     // initialize element locator for locating IEs from the scan response 
       
  3133     // frame body
       
  3134     WlanElementLocator elementLocator( 
       
  3135         reinterpret_cast<const TUint8*>( scanResponseFixedFields + 1 ), 
       
  3136         aScanResponseFrameBodyLength - 
       
  3137         sizeof( SScanResponseFixedFields ) );
       
  3138 
       
  3139     TUint8 elementDatalength( 0 );
       
  3140     const TUint8* elementData( NULL );
       
  3141     
       
  3142     //=============================================
       
  3143     // do we meet mandatory network rates
       
  3144     //=============================================
       
  3145 
       
  3146     // locate supported rates IE
       
  3147     if ( elementLocator.InformationElement( 
       
  3148         E802Dot11SupportedRatesIE,
       
  3149         elementDatalength, 
       
  3150         &elementData ) == WlanElementLocator::EWlanLocateOk )
       
  3151         {
       
  3152         // ...and store it to our context
       
  3153         aCtxImpl.GetApSupportedRatesIE().SetIeData( 
       
  3154             elementData, 
       
  3155             elementDatalength );        
       
  3156         }
       
  3157     else
       
  3158         {
       
  3159         OsTracePrint( KWarningLevel, (TUint8*)
       
  3160             ("UMAC: WlanDot11State::InitNetworkConnect: supported rates IE not found -> abort") );
       
  3161 
       
  3162         return EFalse;
       
  3163         }
       
  3164 
       
  3165     // locate extended supported rates information element
       
  3166     if ( elementLocator.InformationElement( 
       
  3167         E802Dot11ExtendedRatesIE,
       
  3168         elementDatalength, 
       
  3169         &elementData ) == WlanElementLocator::EWlanLocateOk )
       
  3170         {
       
  3171         OsTracePrint( KInfoLevel, (TUint8*)
       
  3172             ("UMAC: WlanDot11State::InitNetworkConnect: E802Dot11ExtendedRatesIE present") );
       
  3173 
       
  3174         // ...and store it to our context
       
  3175         aCtxImpl.GetApExtendedSupportedRatesIE().SetIeData( elementData, elementDatalength );
       
  3176 
       
  3177         // check if we meet mandatory rates; in this case check also extended supported rates
       
  3178         if ( !AreSupportedRatesMet( aCtxImpl, ETrue ) )
       
  3179             {
       
  3180             OsTracePrint( KWarningLevel, (TUint8*)
       
  3181                 ("UMAC: WlanDot11State::InitNetworkConnect: rates not met -> abort") );
       
  3182 
       
  3183             return EFalse;
       
  3184             }
       
  3185         }
       
  3186     else
       
  3187         {
       
  3188         OsTracePrint( KInfoLevel, (TUint8*)
       
  3189             ("UMAC: WlanDot11State::InitNetworkConnect: E802Dot11ExtendedRatesIE not present") );
       
  3190 
       
  3191         // check if we meet mandatory rates; in this case extended supported rates 
       
  3192         // don't need to be checked
       
  3193         if ( !AreSupportedRatesMet( aCtxImpl, EFalse ) )
       
  3194             {
       
  3195             OsTracePrint( KWarningLevel, 
       
  3196                 (TUint8*)("UMAC: WlanDot11State::InitNetworkConnect: rates not met -> abort") );
       
  3197 
       
  3198             return EFalse;
       
  3199             }            
       
  3200         }
       
  3201 
       
  3202     // mandatory network rates are met -> proceed
       
  3203     
       
  3204     //=============================================
       
  3205     // determine the channel of the network
       
  3206     //=============================================
       
  3207 
       
  3208     // locate DS parameter set information element
       
  3209     if ( elementLocator.InformationElement( 
       
  3210         E802Dot11DsParameterSetIE,
       
  3211         elementDatalength, 
       
  3212         &elementData ) == WlanElementLocator::EWlanLocateOk )
       
  3213         {
       
  3214         // ...and store it to our context
       
  3215         aCtxImpl.NetworkChannelNumeber( *elementData );
       
  3216         }
       
  3217     else
       
  3218         {
       
  3219         OsTracePrint( KWarningLevel, (TUint8*)
       
  3220             ("UMAC: WlanDot11State::InitNetworkConnect: 802Dot11DsParameterSetIE not found -> abort") );
       
  3221 
       
  3222         return EFalse;
       
  3223         }
       
  3224 
       
  3225     //=============================================
       
  3226     // determine the beacon interval of the network
       
  3227     //=============================================
       
  3228 
       
  3229     const TUint32 beacon_interval = scanResponseFixedFields->BeaconInterval();
       
  3230 
       
  3231     if ( beacon_interval )
       
  3232         {        
       
  3233         // ...and store it to our context
       
  3234         aCtxImpl.NetworkBeaconInterval( beacon_interval );
       
  3235         }
       
  3236     else
       
  3237         {
       
  3238         OsTracePrint( KWarningLevel, 
       
  3239             (TUint8*)("UMAC: WlanDot11State::InitNetworkConnect: zero beacon interval -> abort") );
       
  3240 
       
  3241         return EFalse;        
       
  3242         }
       
  3243 
       
  3244     //=============================================
       
  3245     // determine the need to use protection
       
  3246     //=============================================
       
  3247 
       
  3248     // locate ERP information element
       
  3249     if ( elementLocator.InformationElement( 
       
  3250         E802Dot11ErpInformationIE,
       
  3251         elementDatalength, 
       
  3252         &elementData ) == WlanElementLocator::EWlanLocateOk )
       
  3253         {
       
  3254         // ERP IE present -> set the protection level according to the Use
       
  3255         // Protection bit
       
  3256         aCtxImpl.ProtectionBitSet( *elementData & KUseProtectionMask );
       
  3257         // make also a note of ERP IE presence, which means that the nw in 
       
  3258         // question is a 802.11a/g nw (instead of a 802.11b nw)
       
  3259         aCtxImpl.ErpIePresent( ETrue );
       
  3260         } 
       
  3261     else
       
  3262         {
       
  3263         // ERP IE not present 
       
  3264         aCtxImpl.ProtectionBitSet( EFalse );
       
  3265         }
       
  3266     
       
  3267     if ( aCtxImpl.NetworkOperationMode() == WHA::EBSS )
       
  3268         {
       
  3269         //=============================================
       
  3270         //
       
  3271         // only for infrastructure mode connections
       
  3272         //
       
  3273         //=============================================
       
  3274 
       
  3275         //=============================================
       
  3276         // determine WMM / QoS information
       
  3277         //=============================================
       
  3278         
       
  3279         // locate WMM information element
       
  3280         if ( elementLocator.InformationElement( 
       
  3281             E802Dot11VendorSpecificIE,
       
  3282             KWmmElemOui,
       
  3283             KWmmElemOuiType,
       
  3284             KWmmInfoElemOuiSubType,
       
  3285             elementDatalength,
       
  3286             &elementData ) == WlanElementLocator::EWlanLocateOk )
       
  3287             {        
       
  3288             // WMM IE present
       
  3289             OsTracePrint( KUmacDetails, (TUint8*)
       
  3290                 ("UMAC: WlanDot11State::InitNetworkConnect: WMM IE present"));
       
  3291                 
       
  3292             EnableQos( aCtxImpl, UapsdEnabledInNetwork( 
       
  3293                 reinterpret_cast<const SRxWmmIeData&>( *elementData ) ) );
       
  3294                 
       
  3295             // as there are no WMM parameter values available in the WMM IE
       
  3296             // use the default AC parameter values until we get the values
       
  3297             // in (re)association response
       
  3298             ResetAcParameters( aCtxImpl, aCtxImpl.ErpIePresent() );                
       
  3299             } 
       
  3300         else
       
  3301             {
       
  3302             // WMM IE not present. Check if WMM Parameter Element exists instead
       
  3303             if ( elementLocator.InformationElement( 
       
  3304                 E802Dot11VendorSpecificIE,
       
  3305                 KWmmElemOui,
       
  3306                 KWmmElemOuiType,
       
  3307                 KWmmParamElemOuiSubtype,
       
  3308                 elementDatalength,
       
  3309                 &elementData ) == WlanElementLocator::EWlanLocateOk )
       
  3310                 {        
       
  3311                 // WMM Parameter Element present
       
  3312                 OsTracePrint( KUmacDetails, (TUint8*)
       
  3313                     ("UMAC: WlanDot11State::InitNetworkConnect: WMM param elem present"));
       
  3314                     
       
  3315                 EnableQos( aCtxImpl, UapsdEnabledInNetwork( 
       
  3316                     reinterpret_cast<const SWmmParamElemData&>( *elementData ) ) );
       
  3317                 
       
  3318                 // as the parameter element is present, use the opportunity to
       
  3319                 // parse the AC (QoS) parameters. 
       
  3320                 // However, reset them 1st to their default values in case 
       
  3321                 // the nw would provide values for some AC multiple times and 
       
  3322                 // leave the parameters for some AC unspecified
       
  3323                 //
       
  3324                 ResetAcParameters( aCtxImpl, aCtxImpl.ErpIePresent() );
       
  3325                 ParseAcParameters( aCtxImpl,
       
  3326                     reinterpret_cast<const SWmmParamElemData&>( *elementData ) );
       
  3327                 } 
       
  3328             else
       
  3329                 {
       
  3330                 // WMM Parameter Element not present either => no QoS, no U-APSD
       
  3331                 OsTracePrint( KUmacDetails, (TUint8*)
       
  3332                     ("UMAC: WlanDot11State::InitNetworkConnect: neither WMM IE nor WMM param elem present"));
       
  3333                     
       
  3334                 aCtxImpl.QosEnabled( EFalse );
       
  3335                 aCtxImpl.UapsdEnabled( EFalse );
       
  3336                 }
       
  3337             }
       
  3338         
       
  3339         //=================================================================
       
  3340         // perform 802.11n related actions & checks if lower layer supports
       
  3341         // HT operation
       
  3342         //=================================================================
       
  3343     
       
  3344         if ( aCtxImpl.WHASettings().iCapability & WHA::SSettings::KHtOperation )
       
  3345             {
       
  3346             if ( !HandleDot11n( aCtxImpl,elementLocator ) )
       
  3347                 {
       
  3348                 OsTracePrint( KWarningLevel, (TUint8*)
       
  3349                     ("UMAC: WlanDot11State::InitNetworkConnect: Nw's 802.11n requirements not met -> abort") );
       
  3350         
       
  3351                 return EFalse;
       
  3352                 }
       
  3353             }
       
  3354         else
       
  3355             {
       
  3356             // lower layer doesn't support HT, so we must handle the network
       
  3357             // as a non-HT network
       
  3358             aCtxImpl.HtSupportedByNw( EFalse );
       
  3359             }
       
  3360         }
       
  3361     else        
       
  3362         {
       
  3363         //=============================================
       
  3364         //
       
  3365         // only for IBSS mode connections
       
  3366         //
       
  3367         // ============================================
       
  3368         
       
  3369         //=============================================
       
  3370         // determine ATIM window
       
  3371         //=============================================
       
  3372 
       
  3373         // locate IBSS Parameter Set element
       
  3374         if ( elementLocator.InformationElement( 
       
  3375             E802Dot11IbssParameterSetIE,
       
  3376             elementDatalength, 
       
  3377             &elementData ) == WlanElementLocator::EWlanLocateOk )
       
  3378             {
       
  3379             // store it to our context
       
  3380 
       
  3381             // note that elementData points to the IE data and not the
       
  3382             // preceding IE header. That's why we need to back up the pointer
       
  3383             // by SInformationElementHeader length before doing the cast
       
  3384             aCtxImpl.AtimWindow( 
       
  3385                 ( reinterpret_cast<const SIbssParameterSetIE*>(
       
  3386                     elementData - sizeof( SInformationElementHeader ) ) 
       
  3387                 )->AtimWindow() );
       
  3388             }                                                
       
  3389         else
       
  3390             {
       
  3391             OsTracePrint( KUmacDetails, (TUint8*)
       
  3392                 ("UMAC: WlanDot11State::InitNetworkConnect: atim not present, PS not used"));
       
  3393 
       
  3394             // as IBSS Parameter Set element is not present, power saving
       
  3395             // is not used in the IBSS network we are going to join. So we 
       
  3396             // will set the ATIM window to zero (to denote that PS is not used)
       
  3397             aCtxImpl.AtimWindow( 0 );
       
  3398             }
       
  3399         }
       
  3400 
       
  3401     //=============================================
       
  3402     // determine U-APSD usage for the ACs/Tx queues
       
  3403     //=============================================
       
  3404     DetermineAcUapsdUsage( aCtxImpl );
       
  3405     
       
  3406     return ETrue;
       
  3407     }
       
  3408 
       
  3409 // -----------------------------------------------------------------------------
       
  3410 // 
       
  3411 // -----------------------------------------------------------------------------
       
  3412 //
       
  3413 TBool WlanDot11State::SetTxPowerLevel(
       
  3414     WlanContextImpl& aCtxImpl,
       
  3415     TUint32 aLevel)
       
  3416     {
       
  3417     OsTracePrint( 
       
  3418         KUmacDetails, 
       
  3419         (TUint8*)
       
  3420         ("UMAC: WlanDot11State::SetTxPowerLevel(): aLevel: %d"), 
       
  3421         aLevel );
       
  3422 
       
  3423     // allocate memory for the mib to write
       
  3424     WHA::Sdot11CurrentTxPowerLevel* mib 
       
  3425         = static_cast<WHA::Sdot11CurrentTxPowerLevel*>
       
  3426         (os_alloc( sizeof(WHA::Sdot11CurrentTxPowerLevel) )); 
       
  3427 
       
  3428     if ( !mib )
       
  3429         {
       
  3430         // allocation failed
       
  3431         // simulate macnotresponding error
       
  3432         OsTracePrint( KWarningLevel, 
       
  3433             (TUint8*)("UMAC * SetRcpiTriggerLevel * abort") );
       
  3434         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  3435         }
       
  3436     
       
  3437     mib->iDot11CurrentTxPowerLevel = aLevel;
       
  3438         
       
  3439     WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
       
  3440         
       
  3441     wha_cmd.Set( 
       
  3442         aCtxImpl, 
       
  3443         WHA::KMibDot11CurrentTxPowerLevel, 
       
  3444         sizeof(*mib), mib );
       
  3445         
       
  3446     // change global state: entry procedure triggers action
       
  3447     ChangeState( aCtxImpl, 
       
  3448         *this,              // prev state
       
  3449         wha_cmd,            // next state
       
  3450         // the ACT
       
  3451         KCompleteManagementRequest
       
  3452         );   
       
  3453 
       
  3454     os_free( mib ); // always remember to release the memory
       
  3455 
       
  3456     // store the new power level also to our soft mib
       
  3457     aCtxImpl.iWlanMib.dot11CurrentTxPowerLevel = aLevel;
       
  3458     
       
  3459     // signal caller that a state transition occurred
       
  3460     return ETrue;
       
  3461     }
       
  3462     
       
  3463 // -----------------------------------------------------------------------------
       
  3464 // 
       
  3465 // -----------------------------------------------------------------------------
       
  3466 //
       
  3467 TBool WlanDot11State::GetLastRcpi(
       
  3468     WlanContextImpl& aCtxImpl )
       
  3469     {
       
  3470     TBool statechange ( EFalse );
       
  3471     WHA::TRcpi whaRcpi( 0 );
       
  3472     
       
  3473     if ( aCtxImpl.GetLatestMedianRcpiFromPredictor( os_systemTime(), whaRcpi ) )
       
  3474         {
       
  3475         // we have a median filtered RCPI value available so we can return that
       
  3476         // directly to WLAN Mgmt Client
       
  3477 
       
  3478         // convert to a 32bit value before returning
       
  3479         const TInt32 rcpi ( whaRcpi );
       
  3480 
       
  3481         OnOidComplete( aCtxImpl, 
       
  3482                        KErrNone, 
       
  3483                        reinterpret_cast<const TAny*>(&rcpi),
       
  3484                        sizeof( rcpi ) );        
       
  3485         }
       
  3486     else
       
  3487         {
       
  3488         // we need to get the RCPI from lower layers
       
  3489         
       
  3490         WlanWsaReadMib& wha_cmd = aCtxImpl.WsaReadMib();
       
  3491         wha_cmd.Set( aCtxImpl, WHA::KMibStatisticsTable );
       
  3492         
       
  3493         // change global state: entry procedure triggers action
       
  3494         ChangeState( aCtxImpl, 
       
  3495             *this,                  // previous state
       
  3496             wha_cmd,                // next state
       
  3497             // the ACT
       
  3498             KCompleteManagementRequest
       
  3499             );                       
       
  3500 
       
  3501         // signal caller that a state transition occurred
       
  3502         statechange = ETrue;
       
  3503         }
       
  3504 
       
  3505     return statechange;
       
  3506     }
       
  3507         
       
  3508 // -----------------------------------------------------------------------------
       
  3509 // 
       
  3510 // -----------------------------------------------------------------------------
       
  3511 //
       
  3512 void WlanDot11State::OnPacketTransferComplete( 
       
  3513     WlanContextImpl& aCtxImpl, 
       
  3514     TUint32 aPacketId,
       
  3515     TDataBuffer* aMetaHeader )
       
  3516     {
       
  3517     // complete the transfer
       
  3518     if ( aPacketId == E802Dot11FrameTypeData )
       
  3519         {
       
  3520         OnTxProtocolStackDataComplete( aCtxImpl, aMetaHeader );
       
  3521         }
       
  3522     else if ( aPacketId == E802Dot11FrameTypeDataEapol || 
       
  3523               aPacketId == E802Dot11FrameTypeManagementAction || 
       
  3524               aPacketId == E802Dot11FrameTypeTestFrame )
       
  3525         {
       
  3526         OnMgmtPathWriteComplete( aCtxImpl );
       
  3527         
       
  3528         aCtxImpl.iUmac.OnOtherTxDataComplete();
       
  3529         }
       
  3530     else
       
  3531         {
       
  3532         // this frame Tx request didn't come from above us (i.e. neither 
       
  3533         // through the user data nor the management data API) but is
       
  3534         // related to a frame Tx we have done internally. So, we need to 
       
  3535         // mark the internal Tx buffer free again
       
  3536         aCtxImpl.MarkInternalTxBufFree();
       
  3537         
       
  3538         aCtxImpl.iUmac.OnOtherTxDataComplete();
       
  3539         }
       
  3540     }
       
  3541 
       
  3542 // -----------------------------------------------------------------------------
       
  3543 // 
       
  3544 // -----------------------------------------------------------------------------
       
  3545 //
       
  3546 void WlanDot11State::OnPacketSendComplete(
       
  3547     WlanContextImpl& aCtxImpl, 
       
  3548     WHA::TStatus aStatus,
       
  3549     TUint32 /*aPacketId*/,
       
  3550     WHA::TRate aRate,
       
  3551     TUint32 /*aPacketQueueDelay*/,
       
  3552     TUint32 /*aMediaDelay*/,
       
  3553     TUint /*aTotalTxDelay*/,
       
  3554     TUint8 /*aAckFailures*/,
       
  3555     WHA::TQueueId aQueueId,
       
  3556     WHA::TRate aRequestedRate,
       
  3557     TBool /*aMulticastData*/ )
       
  3558     {
       
  3559     aCtxImpl.OnTxCompleted( aRate, 
       
  3560         static_cast<TBool>(aStatus == WHA::KSuccess), 
       
  3561         aQueueId,
       
  3562         aRequestedRate );    
       
  3563     }
       
  3564 
       
  3565 // -----------------------------------------------------------------------------
       
  3566 // 
       
  3567 // -----------------------------------------------------------------------------
       
  3568 //
       
  3569 void WlanDot11State::CallPacketSchedule( 
       
  3570     WlanContextImpl& aCtxImpl,
       
  3571     TBool aMore )
       
  3572     {
       
  3573     aCtxImpl.SchedulePackets( aMore );
       
  3574     }
       
  3575 
       
  3576 // -----------------------------------------------------------------------------
       
  3577 // 
       
  3578 // -----------------------------------------------------------------------------
       
  3579 //
       
  3580 void WlanDot11State::OnPacketFlushEvent(
       
  3581     WlanContextImpl& aCtxImpl, 
       
  3582     TUint32 aPacketId,
       
  3583     TDataBuffer* aMetaHeader )
       
  3584     {
       
  3585     if ( aPacketId == E802Dot11FrameTypeData )
       
  3586         {
       
  3587         OnTxProtocolStackDataComplete( aCtxImpl, aMetaHeader );
       
  3588         }
       
  3589     else if ( aPacketId == E802Dot11FrameTypeDataEapol ||
       
  3590               aPacketId == E802Dot11FrameTypeManagementAction || 
       
  3591               aPacketId == E802Dot11FrameTypeTestFrame )
       
  3592         {
       
  3593         // complete with an error code if WLAN Mgmt Client frame
       
  3594         // transmit fails
       
  3595         OnMgmtPathWriteComplete( aCtxImpl, KErrGeneral );
       
  3596         }
       
  3597     else
       
  3598         {
       
  3599         // this frame Tx request didn't come from above us (i.e. neither 
       
  3600         // through the user data nor the management data API) but is
       
  3601         // related to a frame Tx we have done internally. So there's
       
  3602         // nothing to complete upwards. But we need to mark the internal
       
  3603         // Tx buffer free again
       
  3604         aCtxImpl.MarkInternalTxBufFree();
       
  3605         }
       
  3606     }
       
  3607 
       
  3608 // -----------------------------------------------------------------------------
       
  3609 // 
       
  3610 // -----------------------------------------------------------------------------
       
  3611 //
       
  3612 void WlanDot11State::OnPacketPushPossible( 
       
  3613     WlanContextImpl& /*aCtxImpl*/ )
       
  3614     {
       
  3615     // intentionally left empty
       
  3616     }
       
  3617 
       
  3618 // -----------------------------------------------------------------------------
       
  3619 // 
       
  3620 // -----------------------------------------------------------------------------
       
  3621 //
       
  3622 void WlanDot11State::Indication( 
       
  3623     WlanContextImpl& aCtxImpl, 
       
  3624     WHA::TIndicationId aIndicationId,
       
  3625     const WHA::UIndicationParams& aIndicationParams )
       
  3626     {
       
  3627     switch ( aIndicationId )
       
  3628         {
       
  3629         case WHA::EError:
       
  3630             OsTracePrint( KWarningLevel, 
       
  3631                 (TUint8*)("UMAC: WHA error indication received!") );
       
  3632             DoErrorIndication( aCtxImpl, aIndicationParams.iError.iStatus );
       
  3633             break;
       
  3634         case WHA::EBssLost:
       
  3635             DoConsecutiveBeaconsLostIndication( aCtxImpl );
       
  3636             break;
       
  3637         case WHA::EBSSRegained:
       
  3638             DoRegainedBSSIndication( aCtxImpl );
       
  3639             break;
       
  3640         case WHA::ERadar:
       
  3641             DoRadarIndication( aCtxImpl );
       
  3642             break;
       
  3643         case WHA::ERcpi:
       
  3644             DoRcpiIndication( aCtxImpl, aIndicationParams.iRcpi.iRcpi );
       
  3645             break;
       
  3646         case WHA::EPsModeError:
       
  3647             DoPsModeErrorIndication( aCtxImpl );
       
  3648             break;
       
  3649         default:
       
  3650             // implementation error
       
  3651             OsTracePrint( KErrorLevel, 
       
  3652                 (TUint8*)("UMAC: aIndicationId: %d"), aIndicationId );
       
  3653             OsAssert( (TUint8*)("UMAC: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
  3654             break;
       
  3655         }
       
  3656     }
       
  3657     
       
  3658 // -----------------------------------------------------------------------------
       
  3659 // 
       
  3660 // -----------------------------------------------------------------------------
       
  3661 //
       
  3662 TBool WlanDot11State::ConfigureTxQueue( 
       
  3663     WlanContextImpl& aCtxImpl,
       
  3664     WHA::TQueueId aQueueId,
       
  3665     TBool aCompleteManagementRequest )
       
  3666     {
       
  3667     OsTracePrint( KUmacDetails, 
       
  3668         (TUint8*)("UMAC: WlanDot11State::ConfigureTxQueue: aQueueId: %d"),
       
  3669         aQueueId );
       
  3670     OsTracePrint( KUmacDetails, (TUint8*)
       
  3671         ("UMAC: WlanDot11State::ConfigureTxQueue: aCompleteManagementRequest: %d"), 
       
  3672         aCompleteManagementRequest );
       
  3673 
       
  3674     WHA::TPsScheme psScheme( WHA::ERegularPs );
       
  3675     
       
  3676     // enable U-APSD for the AC/Queue in question when necessary. 
       
  3677     // Otherwise stick to regular PS
       
  3678     switch ( aQueueId )
       
  3679         {
       
  3680         case WHA::ELegacy:
       
  3681             if ( aCtxImpl.UapsdUsedForBestEffort() )
       
  3682                 {
       
  3683                 psScheme = WHA::EUapsd;
       
  3684                 }                
       
  3685             break;
       
  3686         case WHA::EBackGround:
       
  3687             if ( aCtxImpl.UapsdUsedForBackground() )
       
  3688                 {
       
  3689                 psScheme = WHA::EUapsd;
       
  3690                 }
       
  3691             break;
       
  3692         case WHA::EVideo:
       
  3693             if ( aCtxImpl.UapsdUsedForVideo() )
       
  3694                 {
       
  3695                 psScheme = WHA::EUapsd;
       
  3696                 }
       
  3697             break;
       
  3698         case WHA::EVoice:
       
  3699             if ( aCtxImpl.UapsdUsedForVoice() )
       
  3700                 {
       
  3701                 psScheme = WHA::EUapsd;
       
  3702                 }
       
  3703             break;
       
  3704         default:
       
  3705             // catch programming error
       
  3706             OsTracePrint( KErrorLevel, (TUint8*)
       
  3707                 ("UMAC: ERROR: unsupported queue, aQueueId: %d"), aQueueId );
       
  3708             OsAssert( (TUint8*)("UMAC: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
  3709         }
       
  3710 
       
  3711     WlanWhaConfigureQueue& wha_command = aCtxImpl.WhaConfigureQueue();
       
  3712 
       
  3713     wha_command.Set( 
       
  3714         aQueueId,
       
  3715         aCtxImpl.iWlanMib.dot11MaxTransmitMSDULifetime[aQueueId], 
       
  3716         psScheme, 
       
  3717         WHA::ENormal,
       
  3718         aCtxImpl.iWlanMib.iMediumTime[aQueueId] );
       
  3719 
       
  3720     const TUint32 KNoNeedToCompleteManagementRequest = 0;
       
  3721         
       
  3722     // change global state: entry procedure triggers action
       
  3723     ChangeState( 
       
  3724         aCtxImpl, 
       
  3725         *this,              // prev state
       
  3726         wha_command,        // next state
       
  3727         aCompleteManagementRequest ? KCompleteManagementRequest : 
       
  3728                                      KNoNeedToCompleteManagementRequest );
       
  3729 
       
  3730     // signal caller that a state transition occurred
       
  3731     return ETrue;                                     
       
  3732     }
       
  3733                      
       
  3734 // -----------------------------------------------------------------------------
       
  3735 // 
       
  3736 // -----------------------------------------------------------------------------
       
  3737 //
       
  3738 TBool WlanDot11State::ConfigureAcParams( 
       
  3739     WlanContextImpl& aCtxImpl )
       
  3740     {
       
  3741     OsTracePrint( 
       
  3742         KUmacDetails, 
       
  3743         (TUint8*)("UMAC: WlanDot11State::ConfigureAcParams") );
       
  3744 
       
  3745     WlanWhaConfigureAc& wha_command = aCtxImpl.WhaConfigureAc();
       
  3746 
       
  3747     wha_command.Set( 
       
  3748         aCtxImpl.CwMinVector(),
       
  3749         aCtxImpl.CwMaxVector(),
       
  3750         aCtxImpl.AifsVector(),
       
  3751         aCtxImpl.TxOplimitVector() );
       
  3752 
       
  3753     // change global state: entry procedure triggers action
       
  3754     ChangeState( aCtxImpl, 
       
  3755         *this,              // prev state
       
  3756         wha_command         // next state
       
  3757         );                       
       
  3758         
       
  3759     // signal caller that a state transition occurred
       
  3760     return ETrue;
       
  3761     }    
       
  3762     
       
  3763 // -----------------------------------------------------------------------------
       
  3764 // 
       
  3765 // -----------------------------------------------------------------------------
       
  3766 //
       
  3767 TBool WlanDot11State::SetCtsToSelfMib( 
       
  3768     WlanContextImpl& aCtxImpl )
       
  3769     {
       
  3770     WHA::SctsToSelf* mib 
       
  3771         = static_cast<WHA::SctsToSelf*>
       
  3772         (os_alloc( sizeof( WHA::SctsToSelf ) )); 
       
  3773 
       
  3774     if ( !mib )
       
  3775         {
       
  3776         // allocation failed
       
  3777         // simulate macnotresponding error
       
  3778         OsTracePrint( KWarningLevel, (TUint8*)
       
  3779             ("UMAC: WlanDot11State::SetCtsToSelfMib(): memory allocation failed") );
       
  3780         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  3781         }
       
  3782 
       
  3783     if ( aCtxImpl.ProtectionBitSet() )
       
  3784         {
       
  3785         OsTracePrint( 
       
  3786             KUmacDetails, 
       
  3787             (TUint8*)("UMAC: WlanDot11State::SetCtsToSelfMib(): enable CTS to self") );
       
  3788             
       
  3789         mib->iCtsToSelf = ETrue;
       
  3790         }
       
  3791     else
       
  3792         {
       
  3793         OsTracePrint( 
       
  3794             KUmacDetails, 
       
  3795             (TUint8*)("UMAC: WlanDot11State::SetCtsToSelfMib(): disable CTS to self") );
       
  3796             
       
  3797         mib->iCtsToSelf = EFalse;
       
  3798         }
       
  3799 
       
  3800     WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
       
  3801     wha_cmd.Set( 
       
  3802         aCtxImpl, WHA::KMibCtsToSelf, sizeof(*mib), mib );
       
  3803 
       
  3804     // change global state: entry procedure triggers action
       
  3805     ChangeState( aCtxImpl, 
       
  3806         *this,              // prev state
       
  3807         wha_cmd             // next state
       
  3808         );  
       
  3809     
       
  3810     // as the parameters have been supplied we can now deallocate
       
  3811     os_free( mib );
       
  3812     
       
  3813     // signal caller that a state transition occurred
       
  3814     return ETrue;    
       
  3815     }
       
  3816 
       
  3817 // -----------------------------------------------------------------------------
       
  3818 // 
       
  3819 // -----------------------------------------------------------------------------
       
  3820 //
       
  3821 TBool WlanDot11State::ConfigureBssLost( 
       
  3822     WlanContextImpl& aCtxImpl,
       
  3823     TUint32 aBeaconLostCount,
       
  3824     TUint8 aFailedTxPacketCount )
       
  3825     {
       
  3826     OsTracePrint( KUmacDetails, (TUint8*)
       
  3827         ("UMAC: WlanDot11State::ConfigureBssLost") );
       
  3828 
       
  3829     // store & take the new failed Tx packet count threshold into use
       
  3830     aCtxImpl.iWlanMib.iFailedTxPacketCountThreshold = aFailedTxPacketCount;
       
  3831     // set the beacon lost count mib    
       
  3832     return SetBeaconLostCountMib( aCtxImpl, aBeaconLostCount );
       
  3833     }
       
  3834 
       
  3835 // ---------------------------------------------------------------------------
       
  3836 // 
       
  3837 // ---------------------------------------------------------------------------
       
  3838 //
       
  3839 TBool WlanDot11State::SetTxRateAdaptParams( 
       
  3840     WlanContextImpl& aCtxImpl,
       
  3841     TUint8 aMinStepUpCheckpoint,
       
  3842     TUint8 aMaxStepUpCheckpoint,
       
  3843     TUint8 aStepUpCheckpointFactor,
       
  3844     TUint8 aStepDownCheckpoint,
       
  3845     TUint8 aMinStepUpThreshold,
       
  3846     TUint8 aMaxStepUpThreshold,
       
  3847     TUint8 aStepUpThresholdIncrement,
       
  3848     TUint8 aStepDownThreshold,
       
  3849     TBool aDisableProbeHandling )
       
  3850     {
       
  3851     aCtxImpl.SetTxRateAdaptationAlgorithmParams(
       
  3852         aMinStepUpCheckpoint,
       
  3853         aMaxStepUpCheckpoint,
       
  3854         aStepUpCheckpointFactor,
       
  3855         aStepDownCheckpoint,
       
  3856         aMinStepUpThreshold,
       
  3857         aMaxStepUpThreshold,
       
  3858         aStepUpThresholdIncrement,
       
  3859         aStepDownThreshold,
       
  3860         aDisableProbeHandling );
       
  3861 
       
  3862     OnOidComplete( aCtxImpl, KErrNone );
       
  3863 
       
  3864     // signal caller that no state transition occurred
       
  3865     return EFalse;    
       
  3866     }
       
  3867 
       
  3868 // ---------------------------------------------------------------------------
       
  3869 // At this point we only store the provided configuration data. It will be
       
  3870 // taken into use when we know the nw we are going to join - i.e. just prior
       
  3871 // actually joining that nw
       
  3872 // ---------------------------------------------------------------------------
       
  3873 //
       
  3874 TBool WlanDot11State::ConfigureTxRatePolicies( 
       
  3875     WlanContextImpl& aCtxImpl,
       
  3876     const TTxRatePolicy& aRatePolicy,
       
  3877     const TQueue2RateClass& aQueue2RateClass,
       
  3878     const TInitialMaxTxRate4RateClass& aInitialMaxTxRate4RateClass,
       
  3879     const TTxAutoRatePolicy& aAutoRatePolicy,
       
  3880     const THtMcsPolicy& aHtMcsPolicy )
       
  3881     {
       
  3882     OsTracePrint( KTxRateAdapt, (TUint8*)
       
  3883         ("UMAC: WlanDot11State::ConfigureTxRatePolicies"));
       
  3884 
       
  3885     StoreTxRatePolicyInfo( 
       
  3886         aCtxImpl,
       
  3887         aRatePolicy,
       
  3888         aQueue2RateClass,
       
  3889         aInitialMaxTxRate4RateClass,
       
  3890         aAutoRatePolicy,
       
  3891         aHtMcsPolicy );
       
  3892         
       
  3893     OnOidComplete( aCtxImpl, KErrNone );
       
  3894 
       
  3895     // signal caller that no state transition occurred
       
  3896     return EFalse;    
       
  3897     }
       
  3898 
       
  3899 // ---------------------------------------------------------------------------
       
  3900 // 
       
  3901 // ---------------------------------------------------------------------------
       
  3902 //
       
  3903 TBool WlanDot11State::SetPowerModeManagementParameters(        
       
  3904     WlanContextImpl& aCtxImpl,
       
  3905     TUint32 aToLightPsTimeout,
       
  3906     TUint16 aToLightPsFrameThreshold,
       
  3907     TUint32 aToActiveTimeout,
       
  3908     TUint16 aToActiveFrameThreshold,
       
  3909     TUint32 aToDeepPsTimeout,
       
  3910     TUint16 aToDeepPsFrameThreshold,
       
  3911     TUint16 aUapsdRxFrameLengthThreshold )
       
  3912     {
       
  3913     aCtxImpl.SetPowerModeManagementParameters(
       
  3914         aToLightPsTimeout,
       
  3915         aToLightPsFrameThreshold,
       
  3916         aToActiveTimeout,
       
  3917         aToActiveFrameThreshold,
       
  3918         aToDeepPsTimeout,
       
  3919         aToDeepPsFrameThreshold,
       
  3920         aUapsdRxFrameLengthThreshold );
       
  3921     
       
  3922     OnOidComplete( aCtxImpl, KErrNone );
       
  3923 
       
  3924     // signal caller that no state transition occurred
       
  3925     return EFalse;    
       
  3926     }
       
  3927 
       
  3928 // -----------------------------------------------------------------------------
       
  3929 // 
       
  3930 // -----------------------------------------------------------------------------
       
  3931 //
       
  3932 TBool WlanDot11State::ConfigurePwrModeMgmtTrafficOverride( 
       
  3933     WlanContextImpl& aCtxImpl,
       
  3934     TBool aStayInPsDespiteUapsdVoiceTraffic,
       
  3935     TBool aStayInPsDespiteUapsdVideoTraffic,
       
  3936     TBool aStayInPsDespiteUapsdBestEffortTraffic, 
       
  3937     TBool aStayInPsDespiteUapsdBackgroundTraffic,
       
  3938     TBool aStayInPsDespiteLegacyVoiceTraffic,
       
  3939     TBool aStayInPsDespiteLegacyVideoTraffic,
       
  3940     TBool aStayInPsDespiteLegacyBestEffortTraffic,
       
  3941     TBool aStayInPsDespiteLegacyBackgroundTraffic )
       
  3942     {
       
  3943     OsTracePrint( KUmacDetails, (TUint8*)
       
  3944         ("UMAC: WlanDot11State::ConfigurePwrModeMgmtTrafficOverride"));
       
  3945 
       
  3946     aCtxImpl.ConfigurePwrModeMgmtTrafficOverride( 
       
  3947         aStayInPsDespiteUapsdVoiceTraffic,
       
  3948         aStayInPsDespiteUapsdVideoTraffic,
       
  3949         aStayInPsDespiteUapsdBestEffortTraffic, 
       
  3950         aStayInPsDespiteUapsdBackgroundTraffic,
       
  3951         aStayInPsDespiteLegacyVoiceTraffic,
       
  3952         aStayInPsDespiteLegacyVideoTraffic,
       
  3953         aStayInPsDespiteLegacyBestEffortTraffic,
       
  3954         aStayInPsDespiteLegacyBackgroundTraffic );
       
  3955 
       
  3956     // Note, that in this case the dynamic power mode mgmt traffic 
       
  3957     // override/ignoration settings will be frozen later (during connect 
       
  3958     // operation, once we know the network capabilites) so that they become 
       
  3959     // effective
       
  3960 
       
  3961     OnOidComplete( aCtxImpl, KErrNone );
       
  3962 
       
  3963     // signal caller that no state transition occurred
       
  3964     return EFalse;    
       
  3965     }
       
  3966 
       
  3967 // -----------------------------------------------------------------------------
       
  3968 // 
       
  3969 // -----------------------------------------------------------------------------
       
  3970 //
       
  3971 TBool WlanDot11State::GetFrameStatistics( WlanContextImpl& aCtxImpl )
       
  3972     {
       
  3973     WlanWsaReadMib& wha_cmd = aCtxImpl.WsaReadMib();
       
  3974     wha_cmd.Set( aCtxImpl, WHA::KMibCountersTable );
       
  3975     
       
  3976     // change global state: entry procedure triggers action
       
  3977     ChangeState( aCtxImpl, 
       
  3978         *this,                  // previous state
       
  3979         wha_cmd,                // next state
       
  3980         // the ACT
       
  3981         KCompleteManagementRequest
       
  3982         );                       
       
  3983 
       
  3984     // signal caller that state transition occurred
       
  3985     return ETrue;
       
  3986     }
       
  3987 
       
  3988 // -----------------------------------------------------------------------------
       
  3989 // At this point we only store the values provided by WLAN mgmt client. They
       
  3990 // will be used later when we (re-)associate to an AP.
       
  3991 // -----------------------------------------------------------------------------
       
  3992 //
       
  3993 TBool WlanDot11State::ConfigureUapsd( 
       
  3994     WlanContextImpl& aCtxImpl,
       
  3995     TMaxServicePeriodLength aMaxServicePeriodLength,
       
  3996     TBool aUapsdForVoice,
       
  3997     TBool aUapsdForVideo,
       
  3998     TBool aUapsdForBestEffort,
       
  3999     TBool aUapsdForBackground )
       
  4000     {
       
  4001     // this cast is safe as the types are effectively the same
       
  4002     aCtxImpl.UapsdMaxSpLen() = 
       
  4003         static_cast<TQosInfoUapsdMaxSpLen>(aMaxServicePeriodLength);
       
  4004     
       
  4005     aCtxImpl.UapsdRequestedForVoice( aUapsdForVoice );
       
  4006     aCtxImpl.UapsdRequestedForVideo( aUapsdForVideo );
       
  4007     aCtxImpl.UapsdRequestedForBestEffort( aUapsdForBestEffort );
       
  4008     aCtxImpl.UapsdRequestedForBackground( aUapsdForBackground );    
       
  4009     
       
  4010     OnOidComplete( aCtxImpl, KErrNone );
       
  4011 
       
  4012     // signal caller that no state transition occurred
       
  4013     return EFalse;        
       
  4014     }
       
  4015 
       
  4016 // -----------------------------------------------------------------------------
       
  4017 // 
       
  4018 // -----------------------------------------------------------------------------
       
  4019 //
       
  4020 TBool WlanDot11State::GetMacAddress(
       
  4021     WlanContextImpl& aCtxImpl )
       
  4022     {
       
  4023     OsTracePrint( KUmacDetails, (TUint8*)
       
  4024         ("UMAC: WlanDot11State::GetMacAddress: mac address:"), 
       
  4025         aCtxImpl.iWlanMib.dot11StationId );
       
  4026 
       
  4027     OnOidComplete( 
       
  4028         aCtxImpl, 
       
  4029         KErrNone, 
       
  4030         &(aCtxImpl.iWlanMib.dot11StationId), 
       
  4031         sizeof(aCtxImpl.iWlanMib.dot11StationId) );
       
  4032 
       
  4033     // signal caller that no state transition occurred
       
  4034     return EFalse;    
       
  4035     }    
       
  4036 
       
  4037 // ---------------------------------------------------------------------------
       
  4038 // 
       
  4039 // ---------------------------------------------------------------------------
       
  4040 //
       
  4041 TBool WlanDot11State::ConfigureArpIpAddressFiltering(
       
  4042     WlanContextImpl& aCtxImpl,
       
  4043     TBool aEnableFiltering,
       
  4044     TIpv4Address aIpv4Address )
       
  4045     {
       
  4046     return SetArpIpAddressTableMib(
       
  4047             aCtxImpl,
       
  4048             aEnableFiltering,
       
  4049             aIpv4Address );
       
  4050     }
       
  4051 
       
  4052 // -----------------------------------------------------------------------------
       
  4053 // At this point we only store the provided configuration.
       
  4054 // It will be passed to the lower layers when connecting to a HT network
       
  4055 // -----------------------------------------------------------------------------
       
  4056 //
       
  4057 TBool WlanDot11State::ConfigureHtBlockAck(
       
  4058     WlanContextImpl& aCtxImpl, 
       
  4059     TUint8 aTxBlockAckUsage,
       
  4060     TUint8 aRxBlockAckUsage )
       
  4061     {
       
  4062     OsTracePrint( KUmacDetails, (TUint8*)
       
  4063         ("UMAC: WlanDot11State::ConfigureHtBlockAck()") );
       
  4064 
       
  4065     WHA::ShtBlockAckConfigure& blockAckConf ( 
       
  4066         aCtxImpl.GetHtBlockAckConfigure() );
       
  4067     blockAckConf.iTxBlockAckUsage = aTxBlockAckUsage;
       
  4068     blockAckConf.iRxBlockAckUsage = aRxBlockAckUsage;
       
  4069 
       
  4070     OnOidComplete( aCtxImpl, KErrNone );
       
  4071     
       
  4072     // signal caller that no state transition occurred
       
  4073     return EFalse;    
       
  4074     }
       
  4075 
       
  4076 // -----------------------------------------------------------------------------
       
  4077 // 
       
  4078 // -----------------------------------------------------------------------------
       
  4079 //
       
  4080 TBool WlanDot11State::ConfigureProprietarySnapHdr(
       
  4081     WlanContextImpl& aCtxImpl, 
       
  4082     const TSnapHeader& aSnapHeader )
       
  4083     {
       
  4084     OsTracePrint( KUmacDetails, (TUint8*)
       
  4085         ("UMAC: WlanDot11State::ConfigureProprietarySnapHdr") );
       
  4086 
       
  4087     // store the provided SNAP header for later use
       
  4088     os_memcpy( 
       
  4089         reinterpret_cast<TUint8*>(&(aCtxImpl.GetProprietarySnapHeader())),
       
  4090         reinterpret_cast<const TUint8*>(&aSnapHeader),
       
  4091         sizeof( SSnapHeader ) );
       
  4092 
       
  4093     OnOidComplete( aCtxImpl, KErrNone );
       
  4094     
       
  4095     // signal caller that no state transition occurred
       
  4096     return EFalse;    
       
  4097     }
       
  4098 
       
  4099 // -----------------------------------------------------------------------------
       
  4100 // 
       
  4101 // -----------------------------------------------------------------------------
       
  4102 //
       
  4103 TBool WlanDot11State::SetBeaconLostCountMib(
       
  4104     WlanContextImpl& aCtxImpl,
       
  4105     TUint32 aBeaconLostCount )
       
  4106     {
       
  4107     OsTracePrint( 
       
  4108         KUmacDetails, (TUint8*)
       
  4109         ("UMAC: WlanDot11State::SetBeaconLostCountMib(): aBeaconLostCount: %d"), 
       
  4110         aBeaconLostCount );
       
  4111 
       
  4112     // allocate memory for the mib to write
       
  4113     WHA::SbeaconLostCount* mib 
       
  4114         = static_cast<WHA::SbeaconLostCount*>
       
  4115         (os_alloc( sizeof( WHA::SbeaconLostCount ) )); 
       
  4116 
       
  4117     if ( !mib )
       
  4118         {
       
  4119         // allocation failed
       
  4120         // simulate macnotresponding error
       
  4121         OsTracePrint( KWarningLevel, 
       
  4122             (TUint8*)("UMAC: WlanDot11State::SetBeaconLostCountMib: abort") );
       
  4123         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  4124         }
       
  4125     
       
  4126     mib->iLostCount = aBeaconLostCount;
       
  4127         
       
  4128     WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
       
  4129         
       
  4130     wha_cmd.Set( 
       
  4131         aCtxImpl, 
       
  4132         WHA::KMibBeaconLostCount, 
       
  4133         sizeof(*mib), mib );
       
  4134         
       
  4135     // change global state: entry procedure triggers action
       
  4136     ChangeState( aCtxImpl, 
       
  4137         *this,              // prev state
       
  4138         wha_cmd,            // next state
       
  4139         // the ACT
       
  4140         KCompleteManagementRequest
       
  4141         );   
       
  4142 
       
  4143     os_free( mib ); // always remember to release the memory
       
  4144 
       
  4145     // store the new beacon lost count also to our soft mib
       
  4146     aCtxImpl.iWlanMib.iBeaconLostCount = aBeaconLostCount;
       
  4147     
       
  4148     // signal caller that a state transition occurred
       
  4149     return ETrue;    
       
  4150     }
       
  4151 
       
  4152 // -----------------------------------------------------------------------------
       
  4153 // 
       
  4154 // -----------------------------------------------------------------------------
       
  4155 //
       
  4156 void WlanDot11State::ResortToSingleTxRatePolicy(
       
  4157     WlanContextImpl& aCtxImpl,
       
  4158     TTxRatePolicy& aRatePolicy,
       
  4159     TQueue2RateClass& aQueue2RateClass ) const
       
  4160     {
       
  4161     OsTracePrint( KTxRateAdapt, (TUint8*)
       
  4162         ("UMAC: WlanDot11State::ResortToSingleTxRatePolicy: WARNING: PDD "
       
  4163          "supports only %d policy objects ... "),
       
  4164         aCtxImpl.WHASettings().iNumOfTxRateClasses );
       
  4165     OsTracePrint( KTxRateAdapt, (TUint8*)
       
  4166         ("UMAC: ... and %d objects have been provided to us"),
       
  4167         aRatePolicy.numOfPolicyObjects );
       
  4168     
       
  4169     // In this case - from the rate classes / autorate policies provided to
       
  4170     // us by WLAN Mgmt client - we will use only the rate class / autorate 
       
  4171     // policy specified for legacy Tx Queue / AC, i.e. the 1st one at index 0
       
  4172     
       
  4173     aRatePolicy.numOfPolicyObjects = 1;
       
  4174     for ( TUint queueId = ELegacy; queueId < EQueueIdMax; ++queueId )
       
  4175         {
       
  4176         aQueue2RateClass[queueId] = 0;
       
  4177         }
       
  4178     
       
  4179 #ifndef NDEBUG
       
  4180     if ( (aCtxImpl.Queue2RateClass())[ELegacy] != 0 )
       
  4181         {
       
  4182         OsTracePrint( KErrorLevel | KTxRateAdapt, (TUint8*)
       
  4183             ("UMAC: WlanDot11State::ResortToSingleTxRatePolicy: ERROR: policy "
       
  4184              "for legacy not specified as the 1st in the policy array") );
       
  4185         OsAssert( (TUint8*)("UMAC: panic"), 
       
  4186             (TUint8*)(WLAN_FILE), __LINE__ );            
       
  4187         }        
       
  4188 #endif
       
  4189     }
       
  4190 
       
  4191 // -----------------------------------------------------------------------------
       
  4192 // 
       
  4193 // -----------------------------------------------------------------------------
       
  4194 //
       
  4195 void WlanDot11State::FinalizeTxRatePolicy(
       
  4196     WlanContextImpl& aCtxImpl,
       
  4197     TTxRatePolicy& aRatePolicy,
       
  4198     TWhaRateMasks& aRateMasks,
       
  4199     TInitialMaxTxRate4RateClass& aInitialMaxTxRate4RateClass ) const
       
  4200     {
       
  4201     for ( TUint rateClassInd = 0; 
       
  4202           rateClassInd < aRatePolicy.numOfPolicyObjects; 
       
  4203           ++rateClassInd )
       
  4204         {
       
  4205         // build a rate mask as an "intersection" of
       
  4206         //   rates in the provided rate class AND
       
  4207         //   rates supported by the nw and AND
       
  4208         //   rates supported by WHA layer.
       
  4209         // Also keep the nbr of tx attempts in the rate class for a particular 
       
  4210         // rate if that rate is supported by both the nw and WHA layer. 
       
  4211         // Otherwise set the nbr of tx attemps to zero for that rate
       
  4212         
       
  4213         HandleRates( 
       
  4214             aCtxImpl, 
       
  4215             aRatePolicy.txRateClass[rateClassInd], 
       
  4216             aRateMasks[rateClassInd] );
       
  4217 
       
  4218         if ( !( aRateMasks[rateClassInd] ) )
       
  4219             {
       
  4220             // the provided rate class was such that we ended up with an empty
       
  4221             // rate mask. To recover from this situation we will update the
       
  4222             // rate class definition on the fly to contain the rates which both
       
  4223             // the WHA layer and the nw support
       
  4224             RecoverRatePolicy(
       
  4225                 aCtxImpl,
       
  4226                 aRatePolicy,
       
  4227                 rateClassInd,
       
  4228                 aRateMasks[rateClassInd] );
       
  4229             // adjust also the Max Tx Rate for this rate class so that the 
       
  4230             // highest possible rate will be used initially
       
  4231             aInitialMaxTxRate4RateClass[rateClassInd] = WHA::KRate54Mbits;
       
  4232             }        
       
  4233         } // for
       
  4234     }
       
  4235 
       
  4236 // -----------------------------------------------------------------------------
       
  4237 // 
       
  4238 // -----------------------------------------------------------------------------
       
  4239 //
       
  4240 void WlanDot11State::HandleRate(
       
  4241     WlanContextImpl& aCtxImpl,
       
  4242     WHA::TRate aRate,
       
  4243     TUint8& aTxAttempts,
       
  4244     WHA::TRate& aRateMask ) const
       
  4245     {        
       
  4246     if ( aCtxImpl.RateBitMask() & aRate )
       
  4247         {
       
  4248         // rate is supported both by us and by the nw. 
       
  4249         
       
  4250         if ( aTxAttempts )
       
  4251             {
       
  4252             // non-zero Tx attempts defined => include the rate in dynamic Tx 
       
  4253             // rate adaptation rates
       
  4254             aRateMask |= aRate;            
       
  4255             }
       
  4256         }
       
  4257     else
       
  4258         {
       
  4259         // rate is not supported either by us or by the nw. Set zero Tx attempts
       
  4260         aTxAttempts = 0;
       
  4261         }
       
  4262     }
       
  4263 
       
  4264 // -----------------------------------------------------------------------------
       
  4265 // 
       
  4266 // -----------------------------------------------------------------------------
       
  4267 //
       
  4268 void WlanDot11State::HandleRates(
       
  4269     WlanContextImpl& aCtxImpl,
       
  4270     TTxRateClass& aRateClass,
       
  4271     WHA::TRate& aRateMask ) const
       
  4272     {
       
  4273     HandleRate( aCtxImpl, WHA::KRate54Mbits, aRateClass.txPolicy54, 
       
  4274         aRateMask );
       
  4275 
       
  4276     HandleRate( aCtxImpl, WHA::KRate48Mbits, aRateClass.txPolicy48,
       
  4277         aRateMask );
       
  4278 
       
  4279     HandleRate( aCtxImpl, WHA::KRate36Mbits, aRateClass.txPolicy36,
       
  4280         aRateMask );
       
  4281 
       
  4282     HandleRate( aCtxImpl, WHA::KRate33Mbits, aRateClass.txPolicy33,
       
  4283         aRateMask );
       
  4284 
       
  4285     HandleRate( aCtxImpl, WHA::KRate24Mbits, aRateClass.txPolicy24,
       
  4286         aRateMask );
       
  4287 
       
  4288     HandleRate( aCtxImpl, WHA::KRate22Mbits, aRateClass.txPolicy22,
       
  4289         aRateMask );
       
  4290 
       
  4291     HandleRate( aCtxImpl, WHA::KRate18Mbits, aRateClass.txPolicy18,
       
  4292         aRateMask );
       
  4293 
       
  4294     HandleRate( aCtxImpl, WHA::KRate12Mbits, aRateClass.txPolicy12,
       
  4295         aRateMask );
       
  4296 
       
  4297     HandleRate( aCtxImpl, WHA::KRate11Mbits, aRateClass.txPolicy11,
       
  4298         aRateMask );
       
  4299 
       
  4300     HandleRate( aCtxImpl, WHA::KRate9Mbits, aRateClass.txPolicy9,
       
  4301         aRateMask );
       
  4302 
       
  4303     HandleRate( aCtxImpl, WHA::KRate6Mbits, aRateClass.txPolicy6,
       
  4304         aRateMask );
       
  4305 
       
  4306     HandleRate( aCtxImpl, WHA::KRate5_5Mbits, aRateClass.txPolicy5_5,
       
  4307         aRateMask );
       
  4308 
       
  4309     HandleRate( aCtxImpl, WHA::KRate2Mbits, aRateClass.txPolicy2,
       
  4310         aRateMask );
       
  4311 
       
  4312     HandleRate( aCtxImpl, WHA::KRate1Mbits, aRateClass.txPolicy1,
       
  4313         aRateMask );    
       
  4314 
       
  4315     OsTracePrint( KTxRateAdapt, (TUint8*)
       
  4316         ("UMAC: WlanDot11State::HandleRates: resulting rate mask: 0x%08x"),
       
  4317         aRateMask );
       
  4318     }
       
  4319     
       
  4320 
       
  4321 // -----------------------------------------------------------------------------
       
  4322 // 
       
  4323 // -----------------------------------------------------------------------------
       
  4324 //
       
  4325 void WlanDot11State::RecoverRatePolicy(
       
  4326     WlanContextImpl& aCtxImpl,
       
  4327     TTxRatePolicy& aRatePolicy,
       
  4328     TUint aRateClassInd,
       
  4329     WHA::TRate& aRateMask ) const
       
  4330     {
       
  4331     OsTracePrint( KTxRateAdapt, (TUint8*)
       
  4332         ("UMAC: WlanDot11State::RecoverRatePolicy: aRateClassInd: %d"),
       
  4333         aRateClassInd );
       
  4334 
       
  4335     const TUint8 KTxAttempts = 1;
       
  4336 
       
  4337     // start with Tx attempts == 1 for all Tx rates
       
  4338     os_memset( 
       
  4339         &aRatePolicy.txRateClass[aRateClassInd], 
       
  4340         KTxAttempts,
       
  4341         sizeof( TUint8 ) * KMaxNumberOfDot11bAndgRates );
       
  4342 
       
  4343     HandleRates( aCtxImpl, aRatePolicy.txRateClass[aRateClassInd], aRateMask );
       
  4344     }
       
  4345 
       
  4346 // -----------------------------------------------------------------------------
       
  4347 // 
       
  4348 // -----------------------------------------------------------------------------
       
  4349 //
       
  4350 void WlanDot11State::FinalizeTxAutoratePolicy(
       
  4351     WlanContextImpl& aCtxImpl,
       
  4352     const TTxRatePolicy& aRatePolicy,
       
  4353     TTxAutoRatePolicy& aAutoRatePolicy ) const
       
  4354     {
       
  4355     for ( TUint rateClassInd = 0; 
       
  4356           rateClassInd < aRatePolicy.numOfPolicyObjects; 
       
  4357           ++rateClassInd )
       
  4358         {
       
  4359         // build a rate mask as an "intersection" of
       
  4360         //   rates in the provided auto rate class AND
       
  4361         //   rates supported by the nw and AND
       
  4362         //   rates supported by WHA layer.
       
  4363         aAutoRatePolicy[rateClassInd] = 
       
  4364             aAutoRatePolicy[rateClassInd] & aCtxImpl.RateBitMask();
       
  4365         
       
  4366         if ( !( aAutoRatePolicy[rateClassInd] ) )
       
  4367             {
       
  4368             // the provided rate class was such that we ended up with an
       
  4369             // empty rate mask. To recover from this situation we will 
       
  4370             // update the rate class definition on the fly to contain
       
  4371             // the rates which both the WHA layer and the nw support
       
  4372             aAutoRatePolicy[rateClassInd] = aCtxImpl.RateBitMask();
       
  4373             }        
       
  4374         }
       
  4375     }
       
  4376 
       
  4377 // -----------------------------------------------------------------------------
       
  4378 // 
       
  4379 // -----------------------------------------------------------------------------
       
  4380 //
       
  4381 void WlanDot11State::SpecialTxAutoratePolicy(
       
  4382     WlanContextImpl& aCtxImpl,
       
  4383     TTxRatePolicy& aRatePolicy,
       
  4384     TTxAutoRatePolicy& aAutoRatePolicy,
       
  4385     THtMcsPolicy& aHtMcsPolicy ) const
       
  4386     {
       
  4387     if ( aRatePolicy.numOfPolicyObjects >= 
       
  4388          aCtxImpl.WHASettings().iNumOfTxRateClasses )
       
  4389         {
       
  4390         // there's no room in the lower layers for a special policy
       
  4391         // disable special policy use
       
  4392         aCtxImpl.SpecialTxAutoRatePolicy( 0 );
       
  4393         
       
  4394         OsTracePrint( KTxRateAdapt, (TUint8*)
       
  4395             ("UMAC: WlanDot11State::SpecialTxAutoratePolicy: no room") );
       
  4396         
       
  4397         return;
       
  4398         }
       
  4399     
       
  4400     const TUint KMaxNbrOfItemsToPick(1);
       
  4401     
       
  4402     // start with an empty rate mask
       
  4403     aAutoRatePolicy[aRatePolicy.numOfPolicyObjects] = 0;
       
  4404     
       
  4405     const WHA::TRate commonRates( aCtxImpl.RateBitMask() );
       
  4406 
       
  4407     // pick the 802.11b/g rate(s) for the special policy
       
  4408     
       
  4409     WHA::TRate rate( WHA::KRate1Mbits );
       
  4410     TUint cntPicked(0);
       
  4411     do
       
  4412         {
       
  4413         if ( rate & commonRates )
       
  4414             {
       
  4415             aAutoRatePolicy[aRatePolicy.numOfPolicyObjects] |= rate;
       
  4416             ++cntPicked;
       
  4417             }
       
  4418         
       
  4419         rate <<= 1;        
       
  4420         } while ( ( cntPicked < KMaxNbrOfItemsToPick ) && 
       
  4421                   ( rate <= KRate54Mbits ) );
       
  4422     
       
  4423     // start with an empty MCS set
       
  4424     for ( TUint mcsBucket = 0; 
       
  4425           mcsBucket < WHA::KHtMcsSetLength; 
       
  4426           ++mcsBucket )    
       
  4427         {
       
  4428         aHtMcsPolicy[aRatePolicy.numOfPolicyObjects][mcsBucket] = 0; 
       
  4429         }
       
  4430     
       
  4431     // pick the 802.11n MCS(s) for the special policy
       
  4432     
       
  4433     const SHtCapabilitiesIE& htCapabilitiesIe( 
       
  4434         aCtxImpl.GetNwHtCapabilitiesIe() );
       
  4435     const TUint KLastMcsBucket = WHA::KHtMcsSetLength - 1;
       
  4436     const TUint8 KMcsCountInLastBucket( 5 );
       
  4437     TUint8 mcsCount( 8 );
       
  4438 
       
  4439     cntPicked = 0;
       
  4440     TUint mcsBucket = 0;
       
  4441     do
       
  4442         {
       
  4443         if ( mcsBucket == KLastMcsBucket )
       
  4444             {
       
  4445             // there are only 5 MCSs in the last "bucket" per 802.11n std.
       
  4446             mcsCount = KMcsCountInLastBucket;
       
  4447             }
       
  4448         
       
  4449         TUint8 mcs(1);
       
  4450         TUint mcsCounter( 0 );
       
  4451         do
       
  4452             {
       
  4453             if ( mcs &
       
  4454                  ( aCtxImpl.WHASettings().iHtCapabilities.iTxMcs[mcsBucket] ) &
       
  4455                  ( htCapabilitiesIe.iData.iRxMcsBitmask[mcsBucket] ) )
       
  4456                 {
       
  4457                 aHtMcsPolicy[aRatePolicy.numOfPolicyObjects][mcsBucket] |= mcs;
       
  4458                 ++cntPicked;
       
  4459                 }
       
  4460             
       
  4461             mcs <<= 1;
       
  4462             ++mcsCounter;
       
  4463             } while ( ( cntPicked < KMaxNbrOfItemsToPick ) && 
       
  4464                       ( mcsCounter < mcsCount ) );
       
  4465                 
       
  4466         ++mcsBucket;
       
  4467         } while ( ( cntPicked < KMaxNbrOfItemsToPick ) && 
       
  4468                   ( mcsBucket < WHA::KHtMcsSetLength ) );
       
  4469     
       
  4470     // set the retry counts
       
  4471     //
       
  4472     const TUint8 KSpecialShortRetryLimit = 10;
       
  4473     const TUint8 KSpecialLongRetryLimit = 4;
       
  4474     aRatePolicy.txRateClass[aRatePolicy.numOfPolicyObjects].shortRetryLimit = 
       
  4475         KSpecialShortRetryLimit;
       
  4476     aRatePolicy.txRateClass[aRatePolicy.numOfPolicyObjects].longRetryLimit = 
       
  4477         KSpecialLongRetryLimit;
       
  4478     
       
  4479     // now we have an additional policy
       
  4480     ++(aRatePolicy.numOfPolicyObjects);
       
  4481     // enable special policy use
       
  4482     aCtxImpl.SpecialTxAutoRatePolicy( aRatePolicy.numOfPolicyObjects );
       
  4483 
       
  4484     OsTracePrint( KTxRateAdapt, (TUint8*)
       
  4485         ("UMAC: WlanDot11State::SpecialTxAutoratePolicy: policy id: %d"),
       
  4486         aRatePolicy.numOfPolicyObjects );
       
  4487     }
       
  4488     
       
  4489 // -----------------------------------------------------------------------------
       
  4490 // 
       
  4491 // -----------------------------------------------------------------------------
       
  4492 //
       
  4493 void WlanDot11State::ConfigureForTxAutoratePolicy(
       
  4494     WlanContextImpl& aCtxImpl,
       
  4495     const TTxRatePolicy& aRatePolicy,
       
  4496     const TQueue2RateClass& aQueue2RateClass,
       
  4497     THtMcsPolicy& aHtMcsPolicy,
       
  4498     TBool aCompleteMgmtRequest )
       
  4499     {
       
  4500     // store the Tx queue to rate class mapping
       
  4501     for ( TUint queueId = ELegacy; queueId < EQueueIdMax; ++queueId )
       
  4502         {
       
  4503         aCtxImpl.SetTxRatePolicy( 
       
  4504             static_cast<WHA::TQueueId>(queueId), 
       
  4505             // rate class ids start from 1, hence the + 1
       
  4506             aQueue2RateClass[queueId] + 1 );
       
  4507         }
       
  4508 
       
  4509     // make sure that our MCS policy contains only MCSs that both the NW
       
  4510     // and the lower layers support
       
  4511     HandleHtMcsPolicy( 
       
  4512         aCtxImpl, 
       
  4513         aHtMcsPolicy,
       
  4514         aRatePolicy.numOfPolicyObjects );
       
  4515     
       
  4516     // change to the state which performs the rest of the configuration
       
  4517     
       
  4518     WlanConfigureTxAutoRatePolicy& complexWhaCmd( 
       
  4519         aCtxImpl.ConfigureTxAutoRatePolicy() );
       
  4520 
       
  4521     complexWhaCmd.Set( aCompleteMgmtRequest );
       
  4522             
       
  4523     // change global state: entry procedure triggers action
       
  4524     ChangeState( aCtxImpl, 
       
  4525         *this,              // prev state
       
  4526         complexWhaCmd       // next state
       
  4527         );    
       
  4528     }
       
  4529     
       
  4530 // -----------------------------------------------------------------------------
       
  4531 // 
       
  4532 // -----------------------------------------------------------------------------
       
  4533 //
       
  4534 void WlanDot11State::HandleHtMcsPolicy(
       
  4535     WlanContextImpl& aCtxImpl,
       
  4536     THtMcsPolicy& aHtMcsPolicy,
       
  4537     TUint aNbrOfMcsSets ) const
       
  4538     {
       
  4539     OsTracePrint( KInfoLevel, (TUint8*)
       
  4540         ("UMAC: WlanDot11State::HandleHtMcsPolicy") );
       
  4541     
       
  4542     const SHtCapabilitiesIE& htCapabilitiesIe( 
       
  4543         aCtxImpl.GetNwHtCapabilitiesIe() );
       
  4544     
       
  4545     for ( TUint mcsSet = 0; mcsSet < aNbrOfMcsSets; ++mcsSet )
       
  4546         {
       
  4547         for ( TUint mcsBucket = 0; 
       
  4548               mcsBucket < WHA::KHtMcsSetLength; 
       
  4549               ++mcsBucket )    
       
  4550             {
       
  4551             aHtMcsPolicy[mcsSet][mcsBucket] = 
       
  4552                 aCtxImpl.WHASettings().iHtCapabilities.iTxMcs[mcsBucket] &
       
  4553                 htCapabilitiesIe.iData.iRxMcsBitmask[mcsBucket] &
       
  4554                 aHtMcsPolicy[mcsSet][mcsBucket];
       
  4555             }        
       
  4556         }
       
  4557     }
       
  4558 
       
  4559 // -----------------------------------------------------------------------------
       
  4560 // 
       
  4561 // -----------------------------------------------------------------------------
       
  4562 //
       
  4563 TBool WlanDot11State::ConfigureForTxRatePolicy(
       
  4564     WlanContextImpl& aCtxImpl,
       
  4565     const TTxRatePolicy& aRatePolicy,
       
  4566     const TWhaRateMasks& aRateMasks,
       
  4567     const TQueue2RateClass& aQueue2RateClass,
       
  4568     const TInitialMaxTxRate4RateClass& aInitialMaxTxRate4RateClass,
       
  4569     TBool aCompleteMgmtRequest )
       
  4570     {
       
  4571     for ( TUint rateClassInd = 0; 
       
  4572           rateClassInd < aRatePolicy.numOfPolicyObjects; 
       
  4573           ++rateClassInd )
       
  4574         {
       
  4575         // provide the ratemask for this rate class to rate adaptation.
       
  4576         // Rate class ids start from 1, hence the + 1
       
  4577         if ( !aCtxImpl.SetTxRateAdaptationRates( 
       
  4578                 rateClassInd + 1, 
       
  4579                 aRateMasks[rateClassInd] ) )
       
  4580             {
       
  4581             // alloc failure; we cannot continue
       
  4582             OsTracePrint( KWarningLevel | KTxRateAdapt, (TUint8*)
       
  4583                 ("UMAC: WlanDot11State::ConfigureForTxRatePolicy: WARNING: "
       
  4584                  "alloc failure in rate adaptation"));
       
  4585             
       
  4586             return EFalse;  // indicate fatal error
       
  4587             }        
       
  4588 
       
  4589         // set the initial max Tx rate for this rate class
       
  4590 
       
  4591         aCtxImpl.SetCurrentMaxTxRate( 
       
  4592             // rate class ids start from 1, hence the + 1
       
  4593             rateClassInd + 1, 
       
  4594             aInitialMaxTxRate4RateClass[rateClassInd] );
       
  4595         }
       
  4596         
       
  4597     // inform rate adaptation about the Tx queue to rate class mapping
       
  4598     for ( TUint queueId = ELegacy; queueId < EQueueIdMax; ++queueId )
       
  4599         {
       
  4600         aCtxImpl.SetTxRatePolicy( 
       
  4601             static_cast<WHA::TQueueId>(queueId), 
       
  4602             // rate class ids start from 1, hence the + 1
       
  4603             aQueue2RateClass[queueId] + 1 );
       
  4604         }
       
  4605 
       
  4606     // update the Rate Policy MIB
       
  4607 
       
  4608     WlanWsaWriteMib& wsa_cmd = aCtxImpl.WsaWriteMib();
       
  4609         
       
  4610     const TUint16 mibLength = sizeof( WHA::StxRatePolicy ) 
       
  4611         // there is space for one policy object (rate class) in the 
       
  4612         // StxRatePolicy struct, so space for any additional objects needs to
       
  4613         // be allocated in addition to that
       
  4614         + sizeof( WHA::StxRateClass ) * 
       
  4615           ( aRatePolicy.numOfPolicyObjects - 1 );
       
  4616      
       
  4617     wsa_cmd.Set( 
       
  4618         aCtxImpl, 
       
  4619         WHA::KMibTxRatePolicy, 
       
  4620         mibLength,
       
  4621         // note that the types WHA::StxRatePolicy and TTxRatePolicy are
       
  4622         // effectively equivalent, so this is ok
       
  4623         &aRatePolicy );
       
  4624         
       
  4625     const TUint32 KNotNecessary2Complete ( 0 );
       
  4626             
       
  4627     // change global state: entry procedure triggers action
       
  4628     ChangeState( aCtxImpl, 
       
  4629         *this,              // prev state
       
  4630         wsa_cmd,            // next state
       
  4631         aCompleteMgmtRequest ? KCompleteManagementRequest : 
       
  4632                                KNotNecessary2Complete
       
  4633         );
       
  4634     
       
  4635     return ETrue;  // indicate success & state change
       
  4636     }
       
  4637 
       
  4638 // ---------------------------------------------------------------------------
       
  4639 // 
       
  4640 // ---------------------------------------------------------------------------
       
  4641 //
       
  4642 TBool WlanDot11State::HandleHtCapabilities( 
       
  4643     WlanContextImpl& aCtxImpl,
       
  4644     WlanElementLocator& aElementLocator ) const
       
  4645     {
       
  4646     TBool status ( ETrue );
       
  4647     TUint8 elementDatalength( 0 );
       
  4648     const TUint8* elementData( NULL );
       
  4649     
       
  4650     // try to locate HT capabilities element
       
  4651     if ( aElementLocator.InformationElement( 
       
  4652             E802Dot11HtCapabilitiesIE,
       
  4653             elementDatalength, 
       
  4654             &elementData ) == WlanElementLocator::EWlanLocateOk )
       
  4655         {
       
  4656         // found, so store it to our context
       
  4657         aCtxImpl.GetNwHtCapabilitiesIe().SetIeData( 
       
  4658             elementData, 
       
  4659             elementDatalength );
       
  4660 
       
  4661         // this also means that the target nw supports HT
       
  4662         aCtxImpl.HtSupportedByNw( ETrue ); 
       
  4663 
       
  4664         OsTracePrint( KInfoLevel, (TUint8*)
       
  4665             ("UMAC: WlanDot11State::HandleHtCapabilities: HT capabilities element present => HT supported by nw") );
       
  4666         }
       
  4667     else
       
  4668         {
       
  4669         // not found => target nw doesn't support HT
       
  4670         aCtxImpl.HtSupportedByNw( EFalse ); 
       
  4671         
       
  4672         OsTracePrint( KInfoLevel, (TUint8*)
       
  4673             ("UMAC: WlanDot11State::HandleHtCapabilities: HT capabilities element not found") );
       
  4674         }
       
  4675     
       
  4676     return status;
       
  4677     }
       
  4678 
       
  4679 // ---------------------------------------------------------------------------
       
  4680 // 
       
  4681 // ---------------------------------------------------------------------------
       
  4682 //
       
  4683 TBool WlanDot11State::HandleHtOperation( 
       
  4684     WlanContextImpl& aCtxImpl,
       
  4685     WlanElementLocator& aElementLocator ) const
       
  4686     {
       
  4687     TBool status ( ETrue );
       
  4688     TUint8 elementDatalength( 0 );
       
  4689     const TUint8* elementData( NULL );
       
  4690     
       
  4691     // try to locate HT Operation element
       
  4692     if ( aElementLocator.InformationElement( 
       
  4693             E802Dot11HtOperationIE,
       
  4694             elementDatalength, 
       
  4695             &elementData ) == WlanElementLocator::EWlanLocateOk )
       
  4696         {
       
  4697         // found, so store it to our context
       
  4698         aCtxImpl.GetNwHtOperationIe().SetIeData( 
       
  4699             elementData, 
       
  4700             elementDatalength );
       
  4701 
       
  4702         OsTracePrint( KInfoLevel, (TUint8*)
       
  4703             ("UMAC: WlanDot11State::HandleHtOperation: element present") );
       
  4704         }
       
  4705     else
       
  4706         {
       
  4707         // not found even though HT capabilities element is present => 
       
  4708         // protocol error
       
  4709         status = EFalse;
       
  4710         
       
  4711         OsTracePrint( KInfoLevel, (TUint8*)
       
  4712             ("UMAC: WlanDot11State::HandleHtOperation: element not found => protocol error") );
       
  4713         }
       
  4714     
       
  4715     return status;
       
  4716     }
       
  4717 
       
  4718 // ---------------------------------------------------------------------------
       
  4719 // 
       
  4720 // ---------------------------------------------------------------------------
       
  4721 //
       
  4722 TBool WlanDot11State::HandleDot11n( 
       
  4723     WlanContextImpl& aCtxImpl,
       
  4724     WlanElementLocator& aElementLocator ) const
       
  4725     {
       
  4726     TBool status ( ETrue ); 
       
  4727     
       
  4728     if ( ( aCtxImpl.PairwiseCipher() == EWlanCipherSuiteTkip ) || 
       
  4729          !( aCtxImpl.QosEnabled() ) )
       
  4730         {
       
  4731         // as the control is here it means that 
       
  4732         // - the WLAN vendor implementation
       
  4733         // supports HT AND EITHER
       
  4734         // - TKIP will be used as the pairwise cipher OR
       
  4735         // - the target nw doesn't support WMM
       
  4736         // In these cases we must not use HT functionality, even if the target 
       
  4737         // nw supported it. We achieve that by handling the target nw as
       
  4738         // a non-HT nw
       
  4739         aCtxImpl.HtSupportedByNw( EFalse );
       
  4740         
       
  4741         OsTracePrint( KInfoLevel, (TUint8*)
       
  4742             ("UMAC: WlanDot11State::HandleDot11n: TKIP as pairwise cipher "
       
  4743              "or WMM not supported => HT disabled") );
       
  4744         }
       
  4745     else
       
  4746         {
       
  4747         status = HandleHtCapabilities( aCtxImpl, aElementLocator ) ;
       
  4748         
       
  4749         // if HT capabilities element is present and ok
       
  4750         if ( aCtxImpl.HtSupportedByNw() && status  )
       
  4751             {
       
  4752             // check also HT Operation element
       
  4753             status = HandleHtOperation( aCtxImpl, aElementLocator );
       
  4754             }
       
  4755         }
       
  4756     
       
  4757     return status;
       
  4758     }