wlan_bearer/wlanldd/wlan_common/umac_common/src/UmacDot11InfrastructureMode.cpp
changeset 0 c40eb8fe8501
child 14 13838cf40350
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 WlanDot11InfrastructureMode class
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 63 %
       
    20 */
       
    21 
       
    22 #include "config.h"
       
    23 #include "UmacDot11InfrastructureMode.h"
       
    24 #include "UmacWsaAddKey.h"
       
    25 #include "umacaddbroadcastwepkey.h"
       
    26 #include "UmacContextImpl.h"
       
    27 #include "UmacWsaKeyIndexMapper.h"
       
    28 #include "UmacWsaWriteMib.h"
       
    29 #include "umacelementlocator.h"
       
    30 #include "umacwhaconfigureac.h"
       
    31 #include "FrameXferBlock.h"
       
    32 
       
    33 
       
    34 // ================= MEMBER FUNCTIONS =======================
       
    35 
       
    36 
       
    37 // ---------------------------------------------------------------------------
       
    38 // 
       
    39 // ---------------------------------------------------------------------------
       
    40 //
       
    41 TBool WlanDot11InfrastructureMode::Connect(
       
    42     WlanContextImpl& aCtxImpl,
       
    43     const TSSID& aSSID,                 
       
    44     const TMacAddress& aBSSID,          
       
    45     TUint16 aAuthAlgorithmNbr,      
       
    46     TEncryptionStatus aEncryptionStatus,
       
    47     TBool /*aIsInfra*/,
       
    48     TUint16 aScanResponseFrameBodyLength,
       
    49     const TUint8* aScanResponseFrameBody,
       
    50     const TUint8* aIeData,
       
    51     TUint16 aIeDataLength )
       
    52     {
       
    53     // store data for later access.
       
    54     // Pointers supplied are valid to the point the
       
    55     // corresponding completion method is called
       
    56 
       
    57     aCtxImpl.SetScanResponseFrameBody( aScanResponseFrameBody );
       
    58     aCtxImpl.SetScanResponseFrameBodyLength( aScanResponseFrameBodyLength );            
       
    59     aCtxImpl.IeData( aIeData );
       
    60     aCtxImpl.IeDataLength( aIeDataLength );
       
    61 
       
    62     return Connect( 
       
    63         aCtxImpl, 
       
    64         aSSID, 
       
    65         aBSSID, 
       
    66         aAuthAlgorithmNbr, 
       
    67         aEncryptionStatus
       
    68         );
       
    69     }
       
    70 
       
    71 // ---------------------------------------------------------------------------
       
    72 // 
       
    73 // ---------------------------------------------------------------------------
       
    74 //
       
    75 TBool WlanDot11InfrastructureMode::Connect(
       
    76     WlanContextImpl& aCtxImpl,
       
    77     const TSSID& aSSID,                 
       
    78     const TMacAddress& aBSSID,          
       
    79     TUint16 aAuthAlgorithmNbr,      
       
    80     TEncryptionStatus aEncryptionStatus )
       
    81     {
       
    82     // construct disassociation frame
       
    83     // note that we don't have to set SA because we have already set it
       
    84     // in the initialize phase of the dot11 state machine
       
    85     //
       
    86 
       
    87     // set the BSSID of the existing network
       
    88     (aCtxImpl.GetDisassociationFrame()).iHeader.iBSSID = aCtxImpl.GetBssId();
       
    89     (aCtxImpl.GetHtDisassociationFrame()).iHeader.iBSSID = aCtxImpl.GetBssId();
       
    90     // set the DA
       
    91     (aCtxImpl.GetDisassociationFrame()).iHeader.iDA = aCtxImpl.GetBssId();
       
    92     (aCtxImpl.GetHtDisassociationFrame()).iHeader.iDA = aCtxImpl.GetBssId();
       
    93     
       
    94     // set current BSSID in reassociation request frame
       
    95     (aCtxImpl.GetReassociationRequestFrame()).iFixedFields.iCurrentApAddress = 
       
    96         aCtxImpl.GetBssId();
       
    97     (aCtxImpl.GetHtReassociationRequestFrame()).iFixedFields.iCurrentApAddress = 
       
    98         aCtxImpl.GetBssId();
       
    99 
       
   100     // ... and make a note that we need to perform reassociation 
       
   101     // instead of association later on towards the new AP
       
   102     aCtxImpl.Reassociate( ETrue );
       
   103 
       
   104     
       
   105     // Store parameters of the new BSS to connect to
       
   106     //
       
   107     (aCtxImpl.GetBssId())= aBSSID;   
       
   108     (aCtxImpl.GetSsId()) = aSSID;   
       
   109     (aCtxImpl.EncryptionStatus()) = aEncryptionStatus;   
       
   110     
       
   111     // set values in authentication frame
       
   112     //
       
   113     (aCtxImpl.AuthenticationAlgorithmNumber()) = aAuthAlgorithmNbr;
       
   114     // set the BSSID field
       
   115     (aCtxImpl.GetAuthenticationFrame()).iHeader.iBSSID = aBSSID;
       
   116     (aCtxImpl.GetHtAuthenticationFrame()).iHeader.iBSSID = aBSSID;
       
   117     // set the DA field
       
   118     (aCtxImpl.GetAuthenticationFrame()).iHeader.iDA = aBSSID;
       
   119     (aCtxImpl.GetHtAuthenticationFrame()).iHeader.iDA = aBSSID;
       
   120     // set the SA field
       
   121     (aCtxImpl.GetAuthenticationFrame()).iHeader.iSA 
       
   122         = aCtxImpl.iWlanMib.dot11StationId;
       
   123     (aCtxImpl.GetHtAuthenticationFrame()).iHeader.iSA 
       
   124         = aCtxImpl.iWlanMib.dot11StationId;
       
   125     aCtxImpl.NetworkOperationMode( WHA::EBSS );
       
   126     
       
   127     if ( aCtxImpl.DisassociatedByAp() )
       
   128         {
       
   129         // if the AP has already sent us a disassociation or deauthentication
       
   130         // frame, we won't send it a disassociation frame any more. So in this
       
   131         // case we skip the dot11DisassociationPending state and go directly to 
       
   132         // dot11Synchronize state.        
       
   133 
       
   134         aCtxImpl.DisassociatedByAp( EFalse ); // also reset the flag
       
   135         
       
   136         ChangeState( aCtxImpl, 
       
   137             *this,                                          // prev state
       
   138             aCtxImpl.iStates.iSynchronizeState              // next state
       
   139             );        
       
   140         }
       
   141     else
       
   142         {
       
   143         // the most common case, i.e. we are still associated with the current
       
   144         // AP. So make a state change to dot11DisassociationPending
       
   145         ChangeState( aCtxImpl, 
       
   146             *this,                                          // prev state
       
   147             aCtxImpl.iStates.iDisassociationPendingState    // next state
       
   148             );
       
   149         }
       
   150 
       
   151     // signal caller that state transition occurred
       
   152     return ETrue;
       
   153     }
       
   154 
       
   155 // ---------------------------------------------------------------------------
       
   156 // 
       
   157 // ---------------------------------------------------------------------------
       
   158 //
       
   159 TBool WlanDot11InfrastructureMode::SetRcpiTriggerLevel(
       
   160     WlanContextImpl& aCtxImpl,
       
   161     TUint32 aRcpiTrigger)
       
   162     {
       
   163     OsTracePrint( KUmacDetails, (TUint8*)
       
   164         ("UMAC: WlanDot11InfrastructureMode::SetRcpiTriggerLevel: aRcpiTrigger: %d"), 
       
   165         aRcpiTrigger );
       
   166  
       
   167     // update the MIB. Also request the WLAN mgmt client request
       
   168     // to be completed
       
   169     return SetRcpiTriggerLevelMib(aCtxImpl, aRcpiTrigger, ETrue );
       
   170     }
       
   171 
       
   172 // -----------------------------------------------------------------------------
       
   173 // 
       
   174 // -----------------------------------------------------------------------------
       
   175 //
       
   176 TBool WlanDot11InfrastructureMode::SetRcpiTriggerLevelMib(
       
   177     WlanContextImpl& aCtxImpl,
       
   178     TUint32 aRcpiTrigger,
       
   179     TBool aCompleteManagementRequest )
       
   180     {
       
   181     OsTracePrint( KUmacDetails, (TUint8*)
       
   182         ("UMAC: WlanDot11InfrastructureMode::SetRcpiTriggerLevelMib: aRcpiTrigger: %d"), 
       
   183         aRcpiTrigger );
       
   184     OsTracePrint( KUmacDetails, (TUint8*)
       
   185         ("UMAC: WlanDot11InfrastructureMode::SetRcpiTriggerLevelMib: aCompleteManagementRequest: %d"), 
       
   186         aCompleteManagementRequest );
       
   187 
       
   188     // allocate memory for the mib to write
       
   189     WHA::SrcpiThreshold* mib = static_cast<WHA::SrcpiThreshold*>
       
   190         (os_alloc( sizeof(WHA::SrcpiThreshold) )); 
       
   191 
       
   192     if ( !mib )
       
   193         {
       
   194         // allocation failed
       
   195         // simulate macnotresponding error
       
   196         OsTracePrint( KWarningLevel, (TUint8*)
       
   197             ("UMAC: WlanDot11InfrastructureMode::SetRcpiTriggerLevelMib: abort") );
       
   198         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
   199         }
       
   200 
       
   201     mib->iThreshold = aRcpiTrigger;
       
   202 
       
   203     WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
       
   204         
       
   205     wha_cmd.Set( aCtxImpl, WHA::KMibRcpiThreshold, sizeof(*mib), mib );
       
   206 
       
   207     const TUint32 KNoNeedToCompleteManagementRequest = 0;
       
   208         
       
   209     // change global state: entry procedure triggers action
       
   210     ChangeState( aCtxImpl, 
       
   211         *this,              // prev state
       
   212         wha_cmd,            // next state
       
   213         aCompleteManagementRequest ? KCompleteManagementRequest : 
       
   214                                      KNoNeedToCompleteManagementRequest
       
   215         );   
       
   216 
       
   217     os_free( mib ); // release the memory
       
   218 
       
   219     // signal caller that a state transition occurred
       
   220     return ETrue;
       
   221     }
       
   222 
       
   223 // ---------------------------------------------------------------------------
       
   224 // 
       
   225 // ---------------------------------------------------------------------------
       
   226 //
       
   227 void WlanDot11InfrastructureMode::OnDeauthenticateFrameRx( 
       
   228     WlanContextImpl& aCtxImpl,
       
   229     TUint8* aBuffer )
       
   230     {
       
   231     // note that the AP has disassociated us (as the AP deauthenticated us
       
   232     // we are also disassociated)
       
   233     aCtxImpl.DisassociatedByAp( ETrue );
       
   234     aCtxImpl.StopVoiceOverWlanCallMaintenance();
       
   235     aCtxImpl.StopKeepAlive();
       
   236     OnInDicationEvent( aCtxImpl, EMediaDisconnect );
       
   237 
       
   238     // release the Rx buffer
       
   239     aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
   240     }
       
   241 
       
   242 // ---------------------------------------------------------------------------
       
   243 // 
       
   244 // ---------------------------------------------------------------------------
       
   245 //
       
   246 void WlanDot11InfrastructureMode::OnDisassociateFrameRx( 
       
   247     WlanContextImpl& aCtxImpl,
       
   248     TUint8* aBuffer )
       
   249     {
       
   250     // note that the AP has disassociated us
       
   251     aCtxImpl.DisassociatedByAp( ETrue );
       
   252     aCtxImpl.StopVoiceOverWlanCallMaintenance();
       
   253     aCtxImpl.StopKeepAlive();
       
   254     OnInDicationEvent( aCtxImpl, EMediaDisconnect );
       
   255 
       
   256     // release the Rx buffer
       
   257     aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
   258     }
       
   259 
       
   260 // ---------------------------------------------------------------------------
       
   261 // 
       
   262 // ---------------------------------------------------------------------------
       
   263 //
       
   264 void WlanDot11InfrastructureMode::OnBeaconFrameRx( 
       
   265     WlanContextImpl& aCtxImpl,
       
   266     const TAny* aFrame,
       
   267     const TUint32 aLength,
       
   268     WHA::TRcpi /*aRcpi*/,
       
   269     TUint8* aBuffer )
       
   270     {
       
   271     OsTracePrint( KRxFrame, (TUint8*)
       
   272         ("UMAC: WlanDot11InfrastructureMode::OnBeaconFrameRx()"));
       
   273 
       
   274     // buffer begin
       
   275     const TUint8* ptr = reinterpret_cast<const TUint8*>(aFrame);
       
   276     
       
   277     // bypass mac header, timestamp fixed field, beacon interval fixed field
       
   278     // and capability fixed field
       
   279     const TUint8 offset = 
       
   280         KMacHeaderLength 
       
   281         + KTimeStampFixedFieldLength 
       
   282         + KBeaconIntervalFixedFieldLength
       
   283         + KCapabilityInformationFixedFieldLength;        
       
   284     ptr += offset; // we now point to the beginning of IEs
       
   285 
       
   286     if ( aLength > offset )
       
   287         {
       
   288         //=================================================================
       
   289         // Check if any dynamic nw parameters, that we are monitoring, have 
       
   290         // changed. If they have, take the new parameters into use
       
   291         //=================================================================
       
   292 
       
   293         WlanElementLocator elementLocator( ptr, aLength - offset );
       
   294         
       
   295         ValidateErpParams( aCtxImpl, elementLocator );
       
   296 
       
   297         if ( aCtxImpl.QosEnabled() )
       
   298             {
       
   299             ValidateAcParams( aCtxImpl, elementLocator );
       
   300             }
       
   301         else
       
   302             {
       
   303             // this is not a QoS connection => not relevant to check
       
   304             // for AC parameter changes
       
   305             }
       
   306 
       
   307         if ( aCtxImpl.HtSupportedByNw() )
       
   308             {
       
   309             ValidateHtBssOperationParams( aCtxImpl, elementLocator );
       
   310             }
       
   311         else
       
   312             {
       
   313             // this is not a HT connection => not relevant to check
       
   314             // for HT operation parameter changes
       
   315             }
       
   316         }
       
   317     else
       
   318         {
       
   319         // frame too short to contain any IEs => ignore it
       
   320         OsTracePrint( KRxFrame | KWarningLevel, (TUint8*)
       
   321             ("UMAC: WlanDot11InfrastructureMode::OnBeaconFrameRx: WARNING: frame too short to contain any IEs => ignored") );        
       
   322         }
       
   323 
       
   324     // release the Rx buffer
       
   325     aCtxImpl.iUmac.MarkRxBufFree( aBuffer);
       
   326     }
       
   327 
       
   328 // ---------------------------------------------------------------------------
       
   329 // 
       
   330 // ---------------------------------------------------------------------------
       
   331 //
       
   332 void WlanDot11InfrastructureMode::ValidateErpParams( 
       
   333     WlanContextImpl& aCtxImpl,
       
   334     WlanElementLocator& aElementLocator )
       
   335     {
       
   336     TUint8 length( 0 );
       
   337     const TUint8* elementData( NULL );
       
   338 
       
   339     if ( WlanElementLocator::EWlanLocateOk == 
       
   340          aElementLocator.InformationElement( 
       
   341             E802Dot11ErpInformationIE, 
       
   342             length, 
       
   343             &elementData ) )
       
   344         {
       
   345         // ERP IE found
       
   346         OsTracePrint( KInfoLevel, (TUint8*)
       
   347             ("UMAC: WlanDot11InfrastructureMode::ValidateErpParams(): ERP IE present"));
       
   348             
       
   349         if ( ( *elementData & KUseProtectionMask ) != aCtxImpl.ProtectionBitSet() )            
       
   350             {
       
   351             OsTracePrint( KInfoLevel, (TUint8*)
       
   352                 ("UMAC: WlanDot11InfrastructureMode::ValidateErpParams(): use protection setting changed, is now: %d"),
       
   353                 *elementData & KUseProtectionMask );
       
   354 
       
   355             // use protection setting has changed, update the setting & 
       
   356             // re-set the MIB
       
   357             //
       
   358             aCtxImpl.ProtectionBitSet( *elementData & KUseProtectionMask );
       
   359 
       
   360             if ( !(aCtxImpl.WsaCmdActive()) )
       
   361                 {
       
   362                 SetCtsToSelfMib( aCtxImpl );
       
   363                 }
       
   364             else
       
   365                 {
       
   366                 // WHA command is in progress so we must defer this access
       
   367                 aCtxImpl.RegisterEvent( KSetCtsToSelf );
       
   368                 }
       
   369             }
       
   370         }
       
   371     }
       
   372 
       
   373 // ---------------------------------------------------------------------------
       
   374 // 
       
   375 // ---------------------------------------------------------------------------
       
   376 //
       
   377 void WlanDot11InfrastructureMode::ValidateAcParams( 
       
   378     WlanContextImpl& aCtxImpl,
       
   379     WlanElementLocator& aElementLocator )
       
   380     {
       
   381     TUint8 length( 0 );
       
   382     const TUint8* elementData( NULL );
       
   383 
       
   384     // is WMM Parameter Element present                        
       
   385     if ( aElementLocator.InformationElement( 
       
   386             E802Dot11VendorSpecificIE,
       
   387             KWmmElemOui,
       
   388             KWmmElemOuiType,
       
   389             KWmmParamElemOuiSubtype,
       
   390             length, 
       
   391             &elementData ) 
       
   392         == WlanElementLocator::EWlanLocateOk )    
       
   393         {
       
   394         // element found
       
   395         OsTracePrint( KQos, (TUint8*)
       
   396             ("UMAC: WlanDot11InfrastructureMode::ValidateAcParams(): WMM param elem present"));
       
   397         
       
   398         if ( (reinterpret_cast<const SWmmParamElemData*>(elementData))->ParameterSetCount() 
       
   399             != aCtxImpl.WmmParameterSetCount() )
       
   400             {
       
   401             // AC parameters have changed => parse them again
       
   402             //
       
   403             OsTracePrint( KQos, (TUint8*)
       
   404                 ("UMAC: WlanDot11InfrastructureMode::ValidateAcParams(): WMM param set count changed (value: %d) => params changed"),
       
   405                 (reinterpret_cast<const SWmmParamElemData*>(elementData))->ParameterSetCount() );
       
   406 
       
   407             ParseAcParameters( aCtxImpl,
       
   408                 reinterpret_cast<const SWmmParamElemData&>(*elementData ) );
       
   409 
       
   410             // we also need to configure the ACs again
       
   411             //
       
   412             if ( !(aCtxImpl.WsaCmdActive()) )
       
   413                 {
       
   414                 ConfigureAcParams( aCtxImpl );
       
   415                 }
       
   416             else
       
   417                 {
       
   418                 // WHA command is in progress so we must defer this access
       
   419                 aCtxImpl.RegisterEvent( KAcParamUpdate );
       
   420                 }
       
   421             }
       
   422         }
       
   423     }
       
   424 
       
   425 // ---------------------------------------------------------------------------
       
   426 // 
       
   427 // ---------------------------------------------------------------------------
       
   428 //
       
   429 void WlanDot11InfrastructureMode::ValidateHtBssOperationParams( 
       
   430     WlanContextImpl& aCtxImpl,
       
   431     WlanElementLocator& aElementLocator )
       
   432     {
       
   433     TUint8 length( 0 );
       
   434     const TUint8* elementData( NULL );
       
   435 
       
   436     if ( WlanElementLocator::EWlanLocateOk == 
       
   437          aElementLocator.InformationElement( 
       
   438             E802Dot11HtOperationIE, 
       
   439             length, 
       
   440             &elementData ) )
       
   441         {
       
   442         // HT Operation element found
       
   443         OsTracePrint( KInfoLevel, (TUint8*)
       
   444             ("UMAC: WlanDot11InfrastructureMode::ValidateHtBssOperationParams: element present"));
       
   445             
       
   446         if ( os_memcmp( 
       
   447                  elementData, 
       
   448                  &(aCtxImpl.GetNwHtOperationIe().iData), 
       
   449                  sizeof( SHtOperationIeData ) ) )            
       
   450             {
       
   451             // content of the element has changed 
       
   452             OsTracePrint( KInfoLevel, (TUint8*)
       
   453                 ("UMAC: element changed"));
       
   454 
       
   455             // store the changed element content to our context
       
   456             aCtxImpl.GetNwHtOperationIe().SetIeData( 
       
   457                 elementData, 
       
   458                 length );
       
   459             
       
   460             // inform the lower layers about the new HT operation 
       
   461             // configuration 
       
   462             if ( !(aCtxImpl.WsaCmdActive()) )
       
   463                 {
       
   464                 ConfigureHtBssOperation( aCtxImpl );
       
   465                 }
       
   466             else
       
   467                 {
       
   468                 // WHA command is in progress so we must defer this access
       
   469                 aCtxImpl.RegisterEvent( KSetHtBssOperation );
       
   470                 }
       
   471             }
       
   472         }
       
   473     }
       
   474 
       
   475 // ---------------------------------------------------------------------------
       
   476 // 
       
   477 // ---------------------------------------------------------------------------
       
   478 //
       
   479 void WlanDot11InfrastructureMode::DoSetTxMpduDaAddress( 
       
   480     SDataFrameHeader& aDataFrameHeader, 
       
   481     const TMacAddress& aMac ) const
       
   482     {
       
   483     aDataFrameHeader.iAddress3 = aMac;
       
   484     }
       
   485 
       
   486 // ---------------------------------------------------------------------------
       
   487 // 
       
   488 // ---------------------------------------------------------------------------
       
   489 //
       
   490 TBool WlanDot11InfrastructureMode::DoIsRxFrameSAourAddress( 
       
   491     WlanContextImpl& aCtxImpl,
       
   492     const SDataFrameHeader& aFrameHeader,
       
   493     const SAmsduSubframeHeader* aSubFrameHeader ) const
       
   494     {
       
   495     if ( aSubFrameHeader )
       
   496         {
       
   497         // the MSDU is part of an A-MSDU and the caller wants to use the
       
   498         // SA in the subframe header for this check
       
   499         return aSubFrameHeader->iSa == aCtxImpl.iWlanMib.dot11StationId;
       
   500         }
       
   501     else
       
   502         {
       
   503         // the caller wants to use the SA in the MAC header for this check
       
   504         return aFrameHeader.iAddress3 == aCtxImpl.iWlanMib.dot11StationId;
       
   505         }
       
   506     }
       
   507 
       
   508 // ---------------------------------------------------------------------------
       
   509 // 
       
   510 // ---------------------------------------------------------------------------
       
   511 //
       
   512 TBool WlanDot11InfrastructureMode::DoIsValidAddressBitCombination(
       
   513     const SDataFrameHeader& aFrameHeader ) const
       
   514     {
       
   515     return (aFrameHeader.IsFromDsBitSet() && !(aFrameHeader.IsToDsBitSet()));
       
   516     }
       
   517 
       
   518 // ---------------------------------------------------------------------------
       
   519 // 
       
   520 // ---------------------------------------------------------------------------
       
   521 //
       
   522 void WlanDot11InfrastructureMode::DoBuildEthernetFrame(
       
   523     TDataBuffer& aBuffer,
       
   524     const SDataMpduHeader& aDot11DataMpdu,
       
   525     const TUint8* aStartOfEtherPayload,
       
   526     TUint aEtherPayloadLength,
       
   527     TBool aAmsdu,
       
   528     TUint8* aCopyBuffer )
       
   529     {
       
   530     OsTracePrint( KUmacDetails, (TUint8*)
       
   531         ("UMAC: WlanDot11InfrastructureMode::DoBuildEthernetFrame"));
       
   532 
       
   533     TUint8* realEtherPayloadStart ( const_cast<TUint8*>(aStartOfEtherPayload) );
       
   534     
       
   535     if ( aCopyBuffer )
       
   536         {
       
   537         // the frame needs to be copied to the copy buffer 
       
   538 
       
   539         // update to point to the new location
       
   540         realEtherPayloadStart = aCopyBuffer + ( 2 * sizeof( TMacAddress ) );
       
   541         
       
   542         os_memcpy( 
       
   543             realEtherPayloadStart,
       
   544             aStartOfEtherPayload, 
       
   545             aEtherPayloadLength );
       
   546         }
       
   547 
       
   548     if ( aAmsdu )
       
   549         {
       
   550         // this MSDU is part of an A-MSDU. Assign SA and DA from subframe
       
   551         // header
       
   552         const SAmsduSubframeHeader* KSubframeHeader ( 
       
   553             reinterpret_cast<const SAmsduSubframeHeader*>( 
       
   554                 aStartOfEtherPayload 
       
   555                 - sizeof( SSnapHeader ) 
       
   556                 - sizeof( SAmsduSubframeHeader ) ) );
       
   557 
       
   558         // copy SA to the correct location.
       
   559         // We do that first so that it doesn't get overwritten by DA
       
   560         os_memcpy( 
       
   561             const_cast<TUint8*>(realEtherPayloadStart) - sizeof( TMacAddress ),
       
   562             reinterpret_cast<const TUint8*>(KSubframeHeader->iSa.iMacAddress),
       
   563             sizeof( TMacAddress ) );
       
   564     
       
   565         // copy DA to the correct location.
       
   566         os_memcpy( 
       
   567             const_cast<TUint8*>(realEtherPayloadStart) 
       
   568                 - ( 2 * sizeof( TMacAddress ) ), 
       
   569             reinterpret_cast<const TUint8*>(KSubframeHeader->iDa.iMacAddress ),
       
   570             sizeof( TMacAddress ) );
       
   571         
       
   572         }
       
   573     else
       
   574         {
       
   575         // assign SA and DA from MAC header 
       
   576         
       
   577         // copy SA to the correct location.
       
   578         // We do that first so that it doesn't get overwritten by DA
       
   579         os_memcpy( 
       
   580             const_cast<TUint8*>(realEtherPayloadStart) - sizeof( TMacAddress ),
       
   581             reinterpret_cast<const TUint8*>(
       
   582                 aDot11DataMpdu.iHdr.iAddress3.iMacAddress ),
       
   583             sizeof( TMacAddress ) );
       
   584     
       
   585         // copy DA to the correct location.
       
   586         os_memcpy( 
       
   587             const_cast<TUint8*>(realEtherPayloadStart) 
       
   588                 - ( 2 * sizeof( TMacAddress ) ), 
       
   589             reinterpret_cast<const TUint8*>(
       
   590                 aDot11DataMpdu.iHdr.iAddress1.iMacAddress ),
       
   591             sizeof( TMacAddress ) );
       
   592         }
       
   593     
       
   594     // set the length
       
   595     aBuffer.KeSetLength( 
       
   596         aEtherPayloadLength 
       
   597         + ( sizeof( TMacAddress ) * 2 ) );
       
   598 
       
   599     // set the frame type
       
   600     aBuffer.FrameType( TDataBuffer::KEthernetFrame );
       
   601     
       
   602     // set the offset to the beginning of the ready ethernet frame 
       
   603     // from the beginning of the Rx buf
       
   604     aBuffer.KeSetOffsetToFrameBeginning( 
       
   605         realEtherPayloadStart - ( 2 * sizeof( TMacAddress ) ) // frame beginning
       
   606         - aBuffer.KeGetBufferStart() );                      // buffer beginning
       
   607 
       
   608     OsTracePrint( KUmacDetails, (TUint8*)
       
   609         ("UMAC: WlanDot11InfrastructureMode::DoBuildEthernetFrame: offset to frame beginning: %d"),
       
   610         aBuffer.KeOffsetToFrameBeginning());
       
   611     }
       
   612     
       
   613 // -----------------------------------------------------------------------------
       
   614 // 
       
   615 // -----------------------------------------------------------------------------
       
   616 //
       
   617 void WlanDot11InfrastructureMode::DoConsecutivePwrModeSetFailuresIndication( 
       
   618     WlanContextImpl& aCtxImpl )
       
   619     {
       
   620     if ( aCtxImpl.OnConsecutivePwrModeSetFailures() )
       
   621         {
       
   622         OnInDicationEvent( aCtxImpl, EConsecutivePwrModeSetFailures );
       
   623         }
       
   624     }
       
   625     
       
   626 // ---------------------------------------------------------------------------
       
   627 // 
       
   628 // ---------------------------------------------------------------------------
       
   629 //
       
   630 TBool WlanDot11InfrastructureMode::Disconnect( WlanContextImpl& aCtxImpl )
       
   631     {
       
   632     OsTracePrint( KInfoLevel, (TUint8*)("UMAC: WlanDot11InfrastructureMode::Disconnect():"));
       
   633 
       
   634     // set completion code to idle state
       
   635     // as it does the request completion
       
   636 
       
   637     aCtxImpl.iStates.iIdleState.Set( KErrNone );
       
   638     ChangeState( aCtxImpl, 
       
   639         *this,                                  // prev state
       
   640         aCtxImpl.iStates.iDeauthPendingState    // next state
       
   641         );                      
       
   642 
       
   643     // signal caller that state transition occurred
       
   644     return ETrue;
       
   645     }
       
   646 
       
   647 // ---------------------------------------------------------------------------
       
   648 // 
       
   649 // ---------------------------------------------------------------------------
       
   650 //
       
   651 TBool WlanDot11InfrastructureMode::RealScan(
       
   652     WlanContextImpl& aCtxImpl,
       
   653     TScanMode aMode,                    
       
   654     const TSSID& aSSID,                 
       
   655     TUint32 aScanRate,                    
       
   656     SChannels& aChannels,
       
   657     TUint32 aMinChannelTime,            
       
   658     TUint32 aMaxChannelTime,
       
   659     TBool aSplitScan )
       
   660     {
       
   661     // scanning mode requested
       
   662     // set parameters
       
   663     // NOTE: OID command parameters are guaranteed to be valid
       
   664     // to the point a correcponding completion method is called
       
   665 
       
   666     aCtxImpl.iStates.iInfrastructureScanningMode.Set( 
       
   667         aMode, aSSID, aScanRate, aChannels,
       
   668         aMinChannelTime, aMaxChannelTime, aSplitScan );
       
   669 
       
   670     ChangeState( aCtxImpl, 
       
   671         *this,                                          // prev state
       
   672         aCtxImpl.iStates.iInfrastructureScanningMode    // next state
       
   673         );                      
       
   674 
       
   675     return ETrue; // global statemachine transition will occur 
       
   676     }
       
   677 
       
   678 // ---------------------------------------------------------------------------
       
   679 // 
       
   680 // ---------------------------------------------------------------------------
       
   681 //
       
   682 void WlanDot11InfrastructureMode::TxMgmtData( 
       
   683     WlanContextImpl& aCtxImpl,
       
   684     TDataBuffer& aDataBuffer )
       
   685     {
       
   686     TWlanUserTxDataCntx& data_cntx( aCtxImpl.GetMgmtTxDataCntx() );
       
   687 
       
   688     // make a note of the frame type
       
   689     const TDataBuffer::TFrameType frameType( aDataBuffer.FrameType() );
       
   690 
       
   691     TUint16 etherType( 0 ); // initial value: not relevant
       
   692     
       
   693     // construct a dot11 frame from databuffer to storage
       
   694     EncapsulateFrame( aCtxImpl, data_cntx, aDataBuffer, etherType );
       
   695     
       
   696     // start of dot11 frame to send
       
   697     const TUint8* start_of_frame( data_cntx.StartOfFrame() );
       
   698         
       
   699     // select correct tx queue
       
   700     const WHA::TQueueId queue_id( 
       
   701         QueueId( aCtxImpl, start_of_frame ) );
       
   702 
       
   703     T802Dot11FrameControlTypeMask dot11FrameType ( E802Dot11FrameTypeDataEapol );
       
   704     TBool useSpecialTxAutoRatePolicy( EFalse );
       
   705     
       
   706     switch ( frameType )
       
   707         {
       
   708         case TDataBuffer::KEthernetFrame:
       
   709             // dot11FrameType already correct
       
   710             
       
   711             // request special Tx autorate policy use for EAPOL and WAI frames
       
   712             useSpecialTxAutoRatePolicy = ETrue;
       
   713             break;
       
   714         case TDataBuffer::KDot11Frame:
       
   715             dot11FrameType = E802Dot11FrameTypeManagementAction;
       
   716             break;
       
   717         case TDataBuffer::KSnapFrame:
       
   718             // these frames have the same Tx completion handling as Eapol 
       
   719             // frames so we use the same dot11FrameType value  - which is
       
   720             // already correct - for them, too
       
   721             break;
       
   722         case TDataBuffer::KEthernetTestFrame:
       
   723             dot11FrameType = E802Dot11FrameTypeTestFrame;
       
   724             break;
       
   725         default:
       
   726             // programming error
       
   727             OsTracePrint( KErrorLevel, (TUint8*)
       
   728                 ("UMAC: unsupported frame type: %d"), frameType );
       
   729             OsAssert( (TUint8*)("UMAC: panic"), 
       
   730                 (TUint8*)(WLAN_FILE), __LINE__ );            
       
   731         }
       
   732     
       
   733     // push the frame to packet scheduler for transmission
       
   734     aCtxImpl.PushPacketToPacketScheduler(
       
   735         start_of_frame,
       
   736         data_cntx.LengthOfFrame(),
       
   737         queue_id,
       
   738         dot11FrameType,
       
   739         &aDataBuffer,
       
   740         EFalse,
       
   741         EFalse,
       
   742         useSpecialTxAutoRatePolicy );
       
   743             
       
   744     // now just wait for the scheduler to call completion methods
       
   745 
       
   746     if ( frameType == TDataBuffer::KEthernetFrame )
       
   747         {
       
   748         // check if we need to change power mgmt mode because of the frame Tx
       
   749     
       
   750         const TPowerMgmtModeChange KPowerMgmtModeChange ( 
       
   751             aCtxImpl.OnFrameTx( queue_id, etherType ) );
       
   752         
       
   753         // if any change change is needed regarding our power mgmt mode,
       
   754         // proceed with it
       
   755         PowerMgmtModeChange( aCtxImpl, KPowerMgmtModeChange );
       
   756         }
       
   757     }
       
   758 
       
   759 // ---------------------------------------------------------------------------
       
   760 // 
       
   761 // ---------------------------------------------------------------------------
       
   762 //
       
   763 void WlanDot11InfrastructureMode::DoRcpiIndication( 
       
   764     WlanContextImpl& aCtxImpl,
       
   765     WHA::TRcpi aRcpi )
       
   766     {
       
   767     OsTracePrint( KWlmIndication, (TUint8*)
       
   768         ("UMAC: WlanDot11InfrastructureMode::DoRcpiIndication: rcpi: %d"),
       
   769         aRcpi ); 
       
   770         
       
   771     OnInDicationEvent( aCtxImpl, ERcpiTrigger );
       
   772     
       
   773     // restore the MIB back to its default value, i.e. zero. 
       
   774     // This means that no further RCPI indications should arrive from WHA 
       
   775     // layer until the RCPI threshold is set again by WLAN Mgmt Client
       
   776     if ( !(aCtxImpl.WsaCmdActive()) )
       
   777         {
       
   778         SetRcpiTriggerLevelMib( aCtxImpl, WHA::KRcpiThresholdDefault, EFalse );
       
   779         }
       
   780     else
       
   781         {
       
   782         // WHA command is in progress so we must defer this access
       
   783         aCtxImpl.RegisterEvent( KSetRcpiTriggerLevel );
       
   784         }
       
   785     }
       
   786 
       
   787 // ---------------------------------------------------------------------------
       
   788 // 
       
   789 // ---------------------------------------------------------------------------
       
   790 //
       
   791 void WlanDot11InfrastructureMode::DoPsModeErrorIndication( 
       
   792     WlanContextImpl& aCtxImpl )
       
   793     {
       
   794     OsTracePrint( KWlmIndication, (TUint8*)
       
   795         ("UMAC: WlanDot11InfrastructureMode::DoPsModeErrorIndication") ); 
       
   796     
       
   797     OnInDicationEvent( aCtxImpl, EPsModeError );    
       
   798     }
       
   799 
       
   800 // ---------------------------------------------------------------------------
       
   801 // 
       
   802 // ---------------------------------------------------------------------------
       
   803 //
       
   804 TBool WlanDot11InfrastructureMode::OnVoiceCallEntryTimerTimeout( 
       
   805     WlanContextImpl& aCtxImpl )
       
   806     {
       
   807     aCtxImpl.OnVoiceCallEntryTimerTimeout();
       
   808 
       
   809     return EFalse;
       
   810     }
       
   811 
       
   812 // ---------------------------------------------------------------------------
       
   813 // 
       
   814 // ---------------------------------------------------------------------------
       
   815 //
       
   816 TBool WlanDot11InfrastructureMode::OnNullTimerTimeout( 
       
   817     WlanContextImpl& aCtxImpl )
       
   818     {
       
   819     aCtxImpl.OnNullTimerTimeout();
       
   820 
       
   821     return EFalse;
       
   822     }
       
   823 
       
   824 // ---------------------------------------------------------------------------
       
   825 // 
       
   826 // ---------------------------------------------------------------------------
       
   827 //
       
   828 TBool WlanDot11InfrastructureMode::OnNoVoiceTimerTimeout( 
       
   829     WlanContextImpl& aCtxImpl )
       
   830     {
       
   831     aCtxImpl.OnNoVoiceTimerTimeout();
       
   832 
       
   833     return EFalse;
       
   834     }
       
   835 
       
   836 // ---------------------------------------------------------------------------
       
   837 // 
       
   838 // ---------------------------------------------------------------------------
       
   839 //
       
   840 TBool WlanDot11InfrastructureMode::OnKeepAliveTimerTimeout( 
       
   841     WlanContextImpl& aCtxImpl )
       
   842     {
       
   843     aCtxImpl.OnKeepAliveTimerTimeout();
       
   844 
       
   845     return EFalse;
       
   846     }
       
   847 
       
   848 // ---------------------------------------------------------------------------
       
   849 // 
       
   850 // ---------------------------------------------------------------------------
       
   851 //
       
   852 TBool WlanDot11InfrastructureMode::OnWlanWakeUpIntervalChange( 
       
   853     WlanContextImpl& aCtxImpl )
       
   854     {
       
   855     OsTracePrint( KPwrStateTransition, (TUint8*)
       
   856         ("UMAC: : WlanDot11InfrastructureMode::OnWlanWakeUpIntervalChange"));
       
   857 
       
   858     WHA::SwlanWakeUpInterval* mib 
       
   859         = static_cast<WHA::SwlanWakeUpInterval*>
       
   860         (os_alloc( sizeof( WHA::SwlanWakeUpInterval ) )); 
       
   861 
       
   862     if ( !mib )
       
   863         {
       
   864         // allocation failed
       
   865         // simulate macnotresponding error
       
   866         OnOidComplete( aCtxImpl );  // complete also
       
   867         OsTracePrint( KWarningLevel, 
       
   868             (TUint8*)("UMAC: WlanDot11InfrastructureMode::OnWlanWakeUpIntervalChange: alloc failed, abort") );
       
   869         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
   870         }
       
   871 
       
   872     // determine the desired new wake-up setting
       
   873     const TDot11PsModeWakeupSetting KDesiredPsModeConfig (
       
   874         aCtxImpl.DesiredPsModeConfig() );
       
   875     
       
   876     // take it into use
       
   877 
       
   878     mib->iMode = KDesiredPsModeConfig.iWakeupMode;
       
   879     mib->iListenInterval = KDesiredPsModeConfig.iListenInterval;
       
   880     
       
   881     WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
       
   882 
       
   883     wha_cmd.Set( 
       
   884         aCtxImpl, WHA::KMibWlanWakeUpInterval, sizeof(*mib), mib );
       
   885 
       
   886     OsTracePrint( KPwrStateTransition, 
       
   887         (TUint8*)("UMAC: WlanDot11InfrastructureMode::OnWlanWakeUpIntervalChange: desired mode: %d"), 
       
   888         mib->iMode );
       
   889     OsTracePrint( KPwrStateTransition, (TUint8*)
       
   890         ("UMAC: WlanDot11InfrastructureMode::OnWlanWakeUpIntervalChange: desired listen interval: %d"), 
       
   891         mib->iListenInterval );
       
   892 
       
   893     // store the new setting also locally
       
   894     aCtxImpl.iWlanMib.iWlanWakeupInterval = mib->iMode;
       
   895     aCtxImpl.iWlanMib.iWlanListenInterval = mib->iListenInterval;
       
   896 
       
   897     // change global state: entry procedure triggers action
       
   898     ChangeState( aCtxImpl, 
       
   899         *this,              // prev state
       
   900         wha_cmd,            // next state
       
   901         // the ACT signals that this operation should be completed to user 
       
   902         WlanDot11State::KCompleteManagementRequest
       
   903         );           
       
   904 
       
   905     // as the parameters have been supplied we can now deallocate
       
   906     os_free( mib );      
       
   907     
       
   908     // signal state transition change
       
   909     return ETrue;
       
   910     }
       
   911 
       
   912 // ---------------------------------------------------------------------------
       
   913 // 
       
   914 // ---------------------------------------------------------------------------
       
   915 //
       
   916 TBool WlanDot11InfrastructureMode::TxNullDataFrame( 
       
   917     WlanContextImpl& aCtxImpl,
       
   918     TBool aQosNull )
       
   919     {
       
   920     OsTracePrint( KWsaTxDetails, (TUint8*)
       
   921         ("UMAC: WlanDot11InfrastructureMode::TxNullDataFrame: aQosNull: %d"),
       
   922         aQosNull );
       
   923 
       
   924     TBool status ( ETrue );
       
   925     
       
   926     TUint32 lengthOfFrame( 0 );
       
   927     T802Dot11FrameControlTypeMask frameType( E802Dot11FrameTypeDataNull );
       
   928 
       
   929     // copy Null Data frame to tx-buffer to correct offset
       
   930     // client doesn't need to take care of the tx buffer header space
       
   931     // as the method below does it by itself
       
   932     TUint8* start_of_frame = aCtxImpl.TxBuffer();
       
   933 
       
   934     if ( start_of_frame )
       
   935         {
       
   936         if ( aQosNull )
       
   937             {
       
   938             // transmit of QoS Null Data Frame requested
       
   939             
       
   940             lengthOfFrame = aCtxImpl.QosNullDataFrameLength();
       
   941             frameType = E802Dot11FrameTypeQosDataNull;
       
   942             
       
   943             os_memcpy( 
       
   944                 start_of_frame,
       
   945                 &(aCtxImpl.QosNullDataFrame()), 
       
   946                 lengthOfFrame );
       
   947 
       
   948             // as this needs to be a trigger frame for Voice AC, set the User
       
   949             // Priority of the frame accordingly
       
   950                 
       
   951             const TUint8 K802Dot1dPriorityVoice = 6;
       
   952             SQosDataFrameHeader* qosHdr = 
       
   953                 reinterpret_cast<SQosDataFrameHeader*>(start_of_frame);
       
   954             qosHdr->SetUserPriority( K802Dot1dPriorityVoice );
       
   955             
       
   956             // note that the Order bit of the Frame Control field of the QoS 
       
   957             // Null data frame has already been given the correct value in 
       
   958             // WlanMacActionState::OnDot11InfrastructureModeStateSpaceEntry()
       
   959             // method
       
   960             }
       
   961         else
       
   962             {
       
   963             // transmit of Null Data Frame requested
       
   964             
       
   965             lengthOfFrame = sizeof( SNullDataFrame );
       
   966             // frame type is already correct for this case
       
   967             
       
   968             os_memcpy( 
       
   969                 start_of_frame,
       
   970                 &(aCtxImpl.NullDataFrame()), 
       
   971                 lengthOfFrame );
       
   972             }
       
   973 
       
   974         // determine Tx queue
       
   975         const WHA::TQueueId queue_id( QueueId( aCtxImpl, start_of_frame ) );
       
   976         
       
   977         // send the Null Data frame by pushing it to packet scheduler
       
   978         aCtxImpl.PushPacketToPacketScheduler( 
       
   979                 start_of_frame, 
       
   980                 lengthOfFrame, 
       
   981                 queue_id,
       
   982                 frameType,
       
   983                 NULL,
       
   984                 EFalse,
       
   985                 EFalse );
       
   986         }                
       
   987     else
       
   988         {
       
   989         // we didn't get a Tx buffer so we can't submit a frame send request.
       
   990         status = EFalse;
       
   991         }
       
   992         
       
   993     return status;                
       
   994     }