--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/wlan_bearer/wlanldd/wlan_common/umac_common/src/UmacDot11InfrastructureMode.cpp Tue Feb 02 02:03:13 2010 +0200
@@ -0,0 +1,994 @@
+/*
+* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Implementation of the WlanDot11InfrastructureMode class
+*
+*/
+
+/*
+* %version: 63 %
+*/
+
+#include "config.h"
+#include "UmacDot11InfrastructureMode.h"
+#include "UmacWsaAddKey.h"
+#include "umacaddbroadcastwepkey.h"
+#include "UmacContextImpl.h"
+#include "UmacWsaKeyIndexMapper.h"
+#include "UmacWsaWriteMib.h"
+#include "umacelementlocator.h"
+#include "umacwhaconfigureac.h"
+#include "FrameXferBlock.h"
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11InfrastructureMode::Connect(
+ WlanContextImpl& aCtxImpl,
+ const TSSID& aSSID,
+ const TMacAddress& aBSSID,
+ TUint16 aAuthAlgorithmNbr,
+ TEncryptionStatus aEncryptionStatus,
+ TBool /*aIsInfra*/,
+ TUint16 aScanResponseFrameBodyLength,
+ const TUint8* aScanResponseFrameBody,
+ const TUint8* aIeData,
+ TUint16 aIeDataLength )
+ {
+ // store data for later access.
+ // Pointers supplied are valid to the point the
+ // corresponding completion method is called
+
+ aCtxImpl.SetScanResponseFrameBody( aScanResponseFrameBody );
+ aCtxImpl.SetScanResponseFrameBodyLength( aScanResponseFrameBodyLength );
+ aCtxImpl.IeData( aIeData );
+ aCtxImpl.IeDataLength( aIeDataLength );
+
+ return Connect(
+ aCtxImpl,
+ aSSID,
+ aBSSID,
+ aAuthAlgorithmNbr,
+ aEncryptionStatus
+ );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11InfrastructureMode::Connect(
+ WlanContextImpl& aCtxImpl,
+ const TSSID& aSSID,
+ const TMacAddress& aBSSID,
+ TUint16 aAuthAlgorithmNbr,
+ TEncryptionStatus aEncryptionStatus )
+ {
+ // construct disassociation frame
+ // note that we don't have to set SA because we have already set it
+ // in the initialize phase of the dot11 state machine
+ //
+
+ // set the BSSID of the existing network
+ (aCtxImpl.GetDisassociationFrame()).iHeader.iBSSID = aCtxImpl.GetBssId();
+ (aCtxImpl.GetHtDisassociationFrame()).iHeader.iBSSID = aCtxImpl.GetBssId();
+ // set the DA
+ (aCtxImpl.GetDisassociationFrame()).iHeader.iDA = aCtxImpl.GetBssId();
+ (aCtxImpl.GetHtDisassociationFrame()).iHeader.iDA = aCtxImpl.GetBssId();
+
+ // set current BSSID in reassociation request frame
+ (aCtxImpl.GetReassociationRequestFrame()).iFixedFields.iCurrentApAddress =
+ aCtxImpl.GetBssId();
+ (aCtxImpl.GetHtReassociationRequestFrame()).iFixedFields.iCurrentApAddress =
+ aCtxImpl.GetBssId();
+
+ // ... and make a note that we need to perform reassociation
+ // instead of association later on towards the new AP
+ aCtxImpl.Reassociate( ETrue );
+
+
+ // Store parameters of the new BSS to connect to
+ //
+ (aCtxImpl.GetBssId())= aBSSID;
+ (aCtxImpl.GetSsId()) = aSSID;
+ (aCtxImpl.EncryptionStatus()) = aEncryptionStatus;
+
+ // set values in authentication frame
+ //
+ (aCtxImpl.AuthenticationAlgorithmNumber()) = aAuthAlgorithmNbr;
+ // set the BSSID field
+ (aCtxImpl.GetAuthenticationFrame()).iHeader.iBSSID = aBSSID;
+ (aCtxImpl.GetHtAuthenticationFrame()).iHeader.iBSSID = aBSSID;
+ // set the DA field
+ (aCtxImpl.GetAuthenticationFrame()).iHeader.iDA = aBSSID;
+ (aCtxImpl.GetHtAuthenticationFrame()).iHeader.iDA = aBSSID;
+ // set the SA field
+ (aCtxImpl.GetAuthenticationFrame()).iHeader.iSA
+ = aCtxImpl.iWlanMib.dot11StationId;
+ (aCtxImpl.GetHtAuthenticationFrame()).iHeader.iSA
+ = aCtxImpl.iWlanMib.dot11StationId;
+ aCtxImpl.NetworkOperationMode( WHA::EBSS );
+
+ if ( aCtxImpl.DisassociatedByAp() )
+ {
+ // if the AP has already sent us a disassociation or deauthentication
+ // frame, we won't send it a disassociation frame any more. So in this
+ // case we skip the dot11DisassociationPending state and go directly to
+ // dot11Synchronize state.
+
+ aCtxImpl.DisassociatedByAp( EFalse ); // also reset the flag
+
+ ChangeState( aCtxImpl,
+ *this, // prev state
+ aCtxImpl.iStates.iSynchronizeState // next state
+ );
+ }
+ else
+ {
+ // the most common case, i.e. we are still associated with the current
+ // AP. So make a state change to dot11DisassociationPending
+ ChangeState( aCtxImpl,
+ *this, // prev state
+ aCtxImpl.iStates.iDisassociationPendingState // next state
+ );
+ }
+
+ // signal caller that state transition occurred
+ return ETrue;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11InfrastructureMode::SetRcpiTriggerLevel(
+ WlanContextImpl& aCtxImpl,
+ TUint32 aRcpiTrigger)
+ {
+ OsTracePrint( KUmacDetails, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::SetRcpiTriggerLevel: aRcpiTrigger: %d"),
+ aRcpiTrigger );
+
+ // update the MIB. Also request the WLAN mgmt client request
+ // to be completed
+ return SetRcpiTriggerLevelMib(aCtxImpl, aRcpiTrigger, ETrue );
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TBool WlanDot11InfrastructureMode::SetRcpiTriggerLevelMib(
+ WlanContextImpl& aCtxImpl,
+ TUint32 aRcpiTrigger,
+ TBool aCompleteManagementRequest )
+ {
+ OsTracePrint( KUmacDetails, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::SetRcpiTriggerLevelMib: aRcpiTrigger: %d"),
+ aRcpiTrigger );
+ OsTracePrint( KUmacDetails, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::SetRcpiTriggerLevelMib: aCompleteManagementRequest: %d"),
+ aCompleteManagementRequest );
+
+ // allocate memory for the mib to write
+ WHA::SrcpiThreshold* mib = static_cast<WHA::SrcpiThreshold*>
+ (os_alloc( sizeof(WHA::SrcpiThreshold) ));
+
+ if ( !mib )
+ {
+ // allocation failed
+ // simulate macnotresponding error
+ OsTracePrint( KWarningLevel, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::SetRcpiTriggerLevelMib: abort") );
+ return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
+ }
+
+ mib->iThreshold = aRcpiTrigger;
+
+ WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
+
+ wha_cmd.Set( aCtxImpl, WHA::KMibRcpiThreshold, sizeof(*mib), mib );
+
+ const TUint32 KNoNeedToCompleteManagementRequest = 0;
+
+ // change global state: entry procedure triggers action
+ ChangeState( aCtxImpl,
+ *this, // prev state
+ wha_cmd, // next state
+ aCompleteManagementRequest ? KCompleteManagementRequest :
+ KNoNeedToCompleteManagementRequest
+ );
+
+ os_free( mib ); // release the memory
+
+ // signal caller that a state transition occurred
+ return ETrue;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11InfrastructureMode::OnDeauthenticateFrameRx(
+ WlanContextImpl& aCtxImpl,
+ TUint8* aBuffer )
+ {
+ // note that the AP has disassociated us (as the AP deauthenticated us
+ // we are also disassociated)
+ aCtxImpl.DisassociatedByAp( ETrue );
+ aCtxImpl.StopVoiceOverWlanCallMaintenance();
+ aCtxImpl.StopKeepAlive();
+ OnInDicationEvent( aCtxImpl, EMediaDisconnect );
+
+ // release the Rx buffer
+ aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11InfrastructureMode::OnDisassociateFrameRx(
+ WlanContextImpl& aCtxImpl,
+ TUint8* aBuffer )
+ {
+ // note that the AP has disassociated us
+ aCtxImpl.DisassociatedByAp( ETrue );
+ aCtxImpl.StopVoiceOverWlanCallMaintenance();
+ aCtxImpl.StopKeepAlive();
+ OnInDicationEvent( aCtxImpl, EMediaDisconnect );
+
+ // release the Rx buffer
+ aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11InfrastructureMode::OnBeaconFrameRx(
+ WlanContextImpl& aCtxImpl,
+ const TAny* aFrame,
+ const TUint32 aLength,
+ WHA::TRcpi /*aRcpi*/,
+ TUint8* aBuffer )
+ {
+ OsTracePrint( KRxFrame, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::OnBeaconFrameRx()"));
+
+ // buffer begin
+ const TUint8* ptr = reinterpret_cast<const TUint8*>(aFrame);
+
+ // bypass mac header, timestamp fixed field, beacon interval fixed field
+ // and capability fixed field
+ const TUint8 offset =
+ KMacHeaderLength
+ + KTimeStampFixedFieldLength
+ + KBeaconIntervalFixedFieldLength
+ + KCapabilityInformationFixedFieldLength;
+ ptr += offset; // we now point to the beginning of IEs
+
+ if ( aLength > offset )
+ {
+ //=================================================================
+ // Check if any dynamic nw parameters, that we are monitoring, have
+ // changed. If they have, take the new parameters into use
+ //=================================================================
+
+ WlanElementLocator elementLocator( ptr, aLength - offset );
+
+ ValidateErpParams( aCtxImpl, elementLocator );
+
+ if ( aCtxImpl.QosEnabled() )
+ {
+ ValidateAcParams( aCtxImpl, elementLocator );
+ }
+ else
+ {
+ // this is not a QoS connection => not relevant to check
+ // for AC parameter changes
+ }
+
+ if ( aCtxImpl.HtSupportedByNw() )
+ {
+ ValidateHtBssOperationParams( aCtxImpl, elementLocator );
+ }
+ else
+ {
+ // this is not a HT connection => not relevant to check
+ // for HT operation parameter changes
+ }
+ }
+ else
+ {
+ // frame too short to contain any IEs => ignore it
+ OsTracePrint( KRxFrame | KWarningLevel, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::OnBeaconFrameRx: WARNING: frame too short to contain any IEs => ignored") );
+ }
+
+ // release the Rx buffer
+ aCtxImpl.iUmac.MarkRxBufFree( aBuffer);
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11InfrastructureMode::ValidateErpParams(
+ WlanContextImpl& aCtxImpl,
+ WlanElementLocator& aElementLocator )
+ {
+ TUint8 length( 0 );
+ const TUint8* elementData( NULL );
+
+ if ( WlanElementLocator::EWlanLocateOk ==
+ aElementLocator.InformationElement(
+ E802Dot11ErpInformationIE,
+ length,
+ &elementData ) )
+ {
+ // ERP IE found
+ OsTracePrint( KInfoLevel, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::ValidateErpParams(): ERP IE present"));
+
+ if ( ( *elementData & KUseProtectionMask ) != aCtxImpl.ProtectionBitSet() )
+ {
+ OsTracePrint( KInfoLevel, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::ValidateErpParams(): use protection setting changed, is now: %d"),
+ *elementData & KUseProtectionMask );
+
+ // use protection setting has changed, update the setting &
+ // re-set the MIB
+ //
+ aCtxImpl.ProtectionBitSet( *elementData & KUseProtectionMask );
+
+ if ( !(aCtxImpl.WsaCmdActive()) )
+ {
+ SetCtsToSelfMib( aCtxImpl );
+ }
+ else
+ {
+ // WHA command is in progress so we must defer this access
+ aCtxImpl.RegisterEvent( KSetCtsToSelf );
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11InfrastructureMode::ValidateAcParams(
+ WlanContextImpl& aCtxImpl,
+ WlanElementLocator& aElementLocator )
+ {
+ TUint8 length( 0 );
+ const TUint8* elementData( NULL );
+
+ // is WMM Parameter Element present
+ if ( aElementLocator.InformationElement(
+ E802Dot11VendorSpecificIE,
+ KWmmElemOui,
+ KWmmElemOuiType,
+ KWmmParamElemOuiSubtype,
+ length,
+ &elementData )
+ == WlanElementLocator::EWlanLocateOk )
+ {
+ // element found
+ OsTracePrint( KQos, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::ValidateAcParams(): WMM param elem present"));
+
+ if ( (reinterpret_cast<const SWmmParamElemData*>(elementData))->ParameterSetCount()
+ != aCtxImpl.WmmParameterSetCount() )
+ {
+ // AC parameters have changed => parse them again
+ //
+ OsTracePrint( KQos, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::ValidateAcParams(): WMM param set count changed (value: %d) => params changed"),
+ (reinterpret_cast<const SWmmParamElemData*>(elementData))->ParameterSetCount() );
+
+ ParseAcParameters( aCtxImpl,
+ reinterpret_cast<const SWmmParamElemData&>(*elementData ) );
+
+ // we also need to configure the ACs again
+ //
+ if ( !(aCtxImpl.WsaCmdActive()) )
+ {
+ ConfigureAcParams( aCtxImpl );
+ }
+ else
+ {
+ // WHA command is in progress so we must defer this access
+ aCtxImpl.RegisterEvent( KAcParamUpdate );
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11InfrastructureMode::ValidateHtBssOperationParams(
+ WlanContextImpl& aCtxImpl,
+ WlanElementLocator& aElementLocator )
+ {
+ TUint8 length( 0 );
+ const TUint8* elementData( NULL );
+
+ if ( WlanElementLocator::EWlanLocateOk ==
+ aElementLocator.InformationElement(
+ E802Dot11HtOperationIE,
+ length,
+ &elementData ) )
+ {
+ // HT Operation element found
+ OsTracePrint( KInfoLevel, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::ValidateHtBssOperationParams: element present"));
+
+ if ( os_memcmp(
+ elementData,
+ &(aCtxImpl.GetNwHtOperationIe().iData),
+ sizeof( SHtOperationIeData ) ) )
+ {
+ // content of the element has changed
+ OsTracePrint( KInfoLevel, (TUint8*)
+ ("UMAC: element changed"));
+
+ // store the changed element content to our context
+ aCtxImpl.GetNwHtOperationIe().SetIeData(
+ elementData,
+ length );
+
+ // inform the lower layers about the new HT operation
+ // configuration
+ if ( !(aCtxImpl.WsaCmdActive()) )
+ {
+ ConfigureHtBssOperation( aCtxImpl );
+ }
+ else
+ {
+ // WHA command is in progress so we must defer this access
+ aCtxImpl.RegisterEvent( KSetHtBssOperation );
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11InfrastructureMode::DoSetTxMpduDaAddress(
+ SDataFrameHeader& aDataFrameHeader,
+ const TMacAddress& aMac ) const
+ {
+ aDataFrameHeader.iAddress3 = aMac;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11InfrastructureMode::DoIsRxFrameSAourAddress(
+ WlanContextImpl& aCtxImpl,
+ const SDataFrameHeader& aFrameHeader,
+ const SAmsduSubframeHeader* aSubFrameHeader ) const
+ {
+ if ( aSubFrameHeader )
+ {
+ // the MSDU is part of an A-MSDU and the caller wants to use the
+ // SA in the subframe header for this check
+ return aSubFrameHeader->iSa == aCtxImpl.iWlanMib.dot11StationId;
+ }
+ else
+ {
+ // the caller wants to use the SA in the MAC header for this check
+ return aFrameHeader.iAddress3 == aCtxImpl.iWlanMib.dot11StationId;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11InfrastructureMode::DoIsValidAddressBitCombination(
+ const SDataFrameHeader& aFrameHeader ) const
+ {
+ return (aFrameHeader.IsFromDsBitSet() && !(aFrameHeader.IsToDsBitSet()));
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11InfrastructureMode::DoBuildEthernetFrame(
+ TDataBuffer& aBuffer,
+ const SDataMpduHeader& aDot11DataMpdu,
+ const TUint8* aStartOfEtherPayload,
+ TUint aEtherPayloadLength,
+ TBool aAmsdu,
+ TUint8* aCopyBuffer )
+ {
+ OsTracePrint( KUmacDetails, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::DoBuildEthernetFrame"));
+
+ TUint8* realEtherPayloadStart ( const_cast<TUint8*>(aStartOfEtherPayload) );
+
+ if ( aCopyBuffer )
+ {
+ // the frame needs to be copied to the copy buffer
+
+ // update to point to the new location
+ realEtherPayloadStart = aCopyBuffer + ( 2 * sizeof( TMacAddress ) );
+
+ os_memcpy(
+ realEtherPayloadStart,
+ aStartOfEtherPayload,
+ aEtherPayloadLength );
+ }
+
+ if ( aAmsdu )
+ {
+ // this MSDU is part of an A-MSDU. Assign SA and DA from subframe
+ // header
+ const SAmsduSubframeHeader* KSubframeHeader (
+ reinterpret_cast<const SAmsduSubframeHeader*>(
+ aStartOfEtherPayload
+ - sizeof( SSnapHeader )
+ - sizeof( SAmsduSubframeHeader ) ) );
+
+ // copy SA to the correct location.
+ // We do that first so that it doesn't get overwritten by DA
+ os_memcpy(
+ const_cast<TUint8*>(realEtherPayloadStart) - sizeof( TMacAddress ),
+ reinterpret_cast<const TUint8*>(KSubframeHeader->iSa.iMacAddress),
+ sizeof( TMacAddress ) );
+
+ // copy DA to the correct location.
+ os_memcpy(
+ const_cast<TUint8*>(realEtherPayloadStart)
+ - ( 2 * sizeof( TMacAddress ) ),
+ reinterpret_cast<const TUint8*>(KSubframeHeader->iDa.iMacAddress ),
+ sizeof( TMacAddress ) );
+
+ }
+ else
+ {
+ // assign SA and DA from MAC header
+
+ // copy SA to the correct location.
+ // We do that first so that it doesn't get overwritten by DA
+ os_memcpy(
+ const_cast<TUint8*>(realEtherPayloadStart) - sizeof( TMacAddress ),
+ reinterpret_cast<const TUint8*>(
+ aDot11DataMpdu.iHdr.iAddress3.iMacAddress ),
+ sizeof( TMacAddress ) );
+
+ // copy DA to the correct location.
+ os_memcpy(
+ const_cast<TUint8*>(realEtherPayloadStart)
+ - ( 2 * sizeof( TMacAddress ) ),
+ reinterpret_cast<const TUint8*>(
+ aDot11DataMpdu.iHdr.iAddress1.iMacAddress ),
+ sizeof( TMacAddress ) );
+ }
+
+ // set the length
+ aBuffer.KeSetLength(
+ aEtherPayloadLength
+ + ( sizeof( TMacAddress ) * 2 ) );
+
+ // set the frame type
+ aBuffer.FrameType( TDataBuffer::KEthernetFrame );
+
+ // set the offset to the beginning of the ready ethernet frame
+ // from the beginning of the Rx buf
+ aBuffer.KeSetOffsetToFrameBeginning(
+ realEtherPayloadStart - ( 2 * sizeof( TMacAddress ) ) // frame beginning
+ - aBuffer.KeGetBufferStart() ); // buffer beginning
+
+ OsTracePrint( KUmacDetails, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::DoBuildEthernetFrame: offset to frame beginning: %d"),
+ aBuffer.KeOffsetToFrameBeginning());
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void WlanDot11InfrastructureMode::DoConsecutivePwrModeSetFailuresIndication(
+ WlanContextImpl& aCtxImpl )
+ {
+ if ( aCtxImpl.OnConsecutivePwrModeSetFailures() )
+ {
+ OnInDicationEvent( aCtxImpl, EConsecutivePwrModeSetFailures );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11InfrastructureMode::Disconnect( WlanContextImpl& aCtxImpl )
+ {
+ OsTracePrint( KInfoLevel, (TUint8*)("UMAC: WlanDot11InfrastructureMode::Disconnect():"));
+
+ // set completion code to idle state
+ // as it does the request completion
+
+ aCtxImpl.iStates.iIdleState.Set( KErrNone );
+ ChangeState( aCtxImpl,
+ *this, // prev state
+ aCtxImpl.iStates.iDeauthPendingState // next state
+ );
+
+ // signal caller that state transition occurred
+ return ETrue;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11InfrastructureMode::RealScan(
+ WlanContextImpl& aCtxImpl,
+ TScanMode aMode,
+ const TSSID& aSSID,
+ TUint32 aScanRate,
+ SChannels& aChannels,
+ TUint32 aMinChannelTime,
+ TUint32 aMaxChannelTime,
+ TBool aSplitScan )
+ {
+ // scanning mode requested
+ // set parameters
+ // NOTE: OID command parameters are guaranteed to be valid
+ // to the point a correcponding completion method is called
+
+ aCtxImpl.iStates.iInfrastructureScanningMode.Set(
+ aMode, aSSID, aScanRate, aChannels,
+ aMinChannelTime, aMaxChannelTime, aSplitScan );
+
+ ChangeState( aCtxImpl,
+ *this, // prev state
+ aCtxImpl.iStates.iInfrastructureScanningMode // next state
+ );
+
+ return ETrue; // global statemachine transition will occur
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11InfrastructureMode::TxMgmtData(
+ WlanContextImpl& aCtxImpl,
+ TDataBuffer& aDataBuffer )
+ {
+ TWlanUserTxDataCntx& data_cntx( aCtxImpl.GetMgmtTxDataCntx() );
+
+ // make a note of the frame type
+ const TDataBuffer::TFrameType frameType( aDataBuffer.FrameType() );
+
+ TUint16 etherType( 0 ); // initial value: not relevant
+
+ // construct a dot11 frame from databuffer to storage
+ EncapsulateFrame( aCtxImpl, data_cntx, aDataBuffer, etherType );
+
+ // start of dot11 frame to send
+ const TUint8* start_of_frame( data_cntx.StartOfFrame() );
+
+ // select correct tx queue
+ const WHA::TQueueId queue_id(
+ QueueId( aCtxImpl, start_of_frame ) );
+
+ T802Dot11FrameControlTypeMask dot11FrameType ( E802Dot11FrameTypeDataEapol );
+ TBool useSpecialTxAutoRatePolicy( EFalse );
+
+ switch ( frameType )
+ {
+ case TDataBuffer::KEthernetFrame:
+ // dot11FrameType already correct
+
+ // request special Tx autorate policy use for EAPOL and WAI frames
+ useSpecialTxAutoRatePolicy = ETrue;
+ break;
+ case TDataBuffer::KDot11Frame:
+ dot11FrameType = E802Dot11FrameTypeManagementAction;
+ break;
+ case TDataBuffer::KSnapFrame:
+ // these frames have the same Tx completion handling as Eapol
+ // frames so we use the same dot11FrameType value - which is
+ // already correct - for them, too
+ break;
+ case TDataBuffer::KEthernetTestFrame:
+ dot11FrameType = E802Dot11FrameTypeTestFrame;
+ break;
+ default:
+ // programming error
+ OsTracePrint( KErrorLevel, (TUint8*)
+ ("UMAC: unsupported frame type: %d"), frameType );
+ OsAssert( (TUint8*)("UMAC: panic"),
+ (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+
+ // push the frame to packet scheduler for transmission
+ aCtxImpl.PushPacketToPacketScheduler(
+ start_of_frame,
+ data_cntx.LengthOfFrame(),
+ queue_id,
+ dot11FrameType,
+ &aDataBuffer,
+ EFalse,
+ EFalse,
+ useSpecialTxAutoRatePolicy );
+
+ // now just wait for the scheduler to call completion methods
+
+ if ( frameType == TDataBuffer::KEthernetFrame )
+ {
+ // check if we need to change power mgmt mode because of the frame Tx
+
+ const TPowerMgmtModeChange KPowerMgmtModeChange (
+ aCtxImpl.OnFrameTx( queue_id, etherType ) );
+
+ // if any change change is needed regarding our power mgmt mode,
+ // proceed with it
+ PowerMgmtModeChange( aCtxImpl, KPowerMgmtModeChange );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11InfrastructureMode::DoRcpiIndication(
+ WlanContextImpl& aCtxImpl,
+ WHA::TRcpi aRcpi )
+ {
+ OsTracePrint( KWlmIndication, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::DoRcpiIndication: rcpi: %d"),
+ aRcpi );
+
+ OnInDicationEvent( aCtxImpl, ERcpiTrigger );
+
+ // restore the MIB back to its default value, i.e. zero.
+ // This means that no further RCPI indications should arrive from WHA
+ // layer until the RCPI threshold is set again by WLAN Mgmt Client
+ if ( !(aCtxImpl.WsaCmdActive()) )
+ {
+ SetRcpiTriggerLevelMib( aCtxImpl, WHA::KRcpiThresholdDefault, EFalse );
+ }
+ else
+ {
+ // WHA command is in progress so we must defer this access
+ aCtxImpl.RegisterEvent( KSetRcpiTriggerLevel );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11InfrastructureMode::DoPsModeErrorIndication(
+ WlanContextImpl& aCtxImpl )
+ {
+ OsTracePrint( KWlmIndication, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::DoPsModeErrorIndication") );
+
+ OnInDicationEvent( aCtxImpl, EPsModeError );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11InfrastructureMode::OnVoiceCallEntryTimerTimeout(
+ WlanContextImpl& aCtxImpl )
+ {
+ aCtxImpl.OnVoiceCallEntryTimerTimeout();
+
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11InfrastructureMode::OnNullTimerTimeout(
+ WlanContextImpl& aCtxImpl )
+ {
+ aCtxImpl.OnNullTimerTimeout();
+
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11InfrastructureMode::OnNoVoiceTimerTimeout(
+ WlanContextImpl& aCtxImpl )
+ {
+ aCtxImpl.OnNoVoiceTimerTimeout();
+
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11InfrastructureMode::OnKeepAliveTimerTimeout(
+ WlanContextImpl& aCtxImpl )
+ {
+ aCtxImpl.OnKeepAliveTimerTimeout();
+
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11InfrastructureMode::OnWlanWakeUpIntervalChange(
+ WlanContextImpl& aCtxImpl )
+ {
+ OsTracePrint( KPwrStateTransition, (TUint8*)
+ ("UMAC: : WlanDot11InfrastructureMode::OnWlanWakeUpIntervalChange"));
+
+ WHA::SwlanWakeUpInterval* mib
+ = static_cast<WHA::SwlanWakeUpInterval*>
+ (os_alloc( sizeof( WHA::SwlanWakeUpInterval ) ));
+
+ if ( !mib )
+ {
+ // allocation failed
+ // simulate macnotresponding error
+ OnOidComplete( aCtxImpl ); // complete also
+ OsTracePrint( KWarningLevel,
+ (TUint8*)("UMAC: WlanDot11InfrastructureMode::OnWlanWakeUpIntervalChange: alloc failed, abort") );
+ return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
+ }
+
+ // determine the desired new wake-up setting
+ const TDot11PsModeWakeupSetting KDesiredPsModeConfig (
+ aCtxImpl.DesiredPsModeConfig() );
+
+ // take it into use
+
+ mib->iMode = KDesiredPsModeConfig.iWakeupMode;
+ mib->iListenInterval = KDesiredPsModeConfig.iListenInterval;
+
+ WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
+
+ wha_cmd.Set(
+ aCtxImpl, WHA::KMibWlanWakeUpInterval, sizeof(*mib), mib );
+
+ OsTracePrint( KPwrStateTransition,
+ (TUint8*)("UMAC: WlanDot11InfrastructureMode::OnWlanWakeUpIntervalChange: desired mode: %d"),
+ mib->iMode );
+ OsTracePrint( KPwrStateTransition, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::OnWlanWakeUpIntervalChange: desired listen interval: %d"),
+ mib->iListenInterval );
+
+ // store the new setting also locally
+ aCtxImpl.iWlanMib.iWlanWakeupInterval = mib->iMode;
+ aCtxImpl.iWlanMib.iWlanListenInterval = mib->iListenInterval;
+
+ // change global state: entry procedure triggers action
+ ChangeState( aCtxImpl,
+ *this, // prev state
+ wha_cmd, // next state
+ // the ACT signals that this operation should be completed to user
+ WlanDot11State::KCompleteManagementRequest
+ );
+
+ // as the parameters have been supplied we can now deallocate
+ os_free( mib );
+
+ // signal state transition change
+ return ETrue;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11InfrastructureMode::TxNullDataFrame(
+ WlanContextImpl& aCtxImpl,
+ TBool aQosNull )
+ {
+ OsTracePrint( KWsaTxDetails, (TUint8*)
+ ("UMAC: WlanDot11InfrastructureMode::TxNullDataFrame: aQosNull: %d"),
+ aQosNull );
+
+ TBool status ( ETrue );
+
+ TUint32 lengthOfFrame( 0 );
+ T802Dot11FrameControlTypeMask frameType( E802Dot11FrameTypeDataNull );
+
+ // copy Null Data frame to tx-buffer to correct offset
+ // client doesn't need to take care of the tx buffer header space
+ // as the method below does it by itself
+ TUint8* start_of_frame = aCtxImpl.TxBuffer();
+
+ if ( start_of_frame )
+ {
+ if ( aQosNull )
+ {
+ // transmit of QoS Null Data Frame requested
+
+ lengthOfFrame = aCtxImpl.QosNullDataFrameLength();
+ frameType = E802Dot11FrameTypeQosDataNull;
+
+ os_memcpy(
+ start_of_frame,
+ &(aCtxImpl.QosNullDataFrame()),
+ lengthOfFrame );
+
+ // as this needs to be a trigger frame for Voice AC, set the User
+ // Priority of the frame accordingly
+
+ const TUint8 K802Dot1dPriorityVoice = 6;
+ SQosDataFrameHeader* qosHdr =
+ reinterpret_cast<SQosDataFrameHeader*>(start_of_frame);
+ qosHdr->SetUserPriority( K802Dot1dPriorityVoice );
+
+ // note that the Order bit of the Frame Control field of the QoS
+ // Null data frame has already been given the correct value in
+ // WlanMacActionState::OnDot11InfrastructureModeStateSpaceEntry()
+ // method
+ }
+ else
+ {
+ // transmit of Null Data Frame requested
+
+ lengthOfFrame = sizeof( SNullDataFrame );
+ // frame type is already correct for this case
+
+ os_memcpy(
+ start_of_frame,
+ &(aCtxImpl.NullDataFrame()),
+ lengthOfFrame );
+ }
+
+ // determine Tx queue
+ const WHA::TQueueId queue_id( QueueId( aCtxImpl, start_of_frame ) );
+
+ // send the Null Data frame by pushing it to packet scheduler
+ aCtxImpl.PushPacketToPacketScheduler(
+ start_of_frame,
+ lengthOfFrame,
+ queue_id,
+ frameType,
+ NULL,
+ EFalse,
+ EFalse );
+ }
+ else
+ {
+ // we didn't get a Tx buffer so we can't submit a frame send request.
+ status = EFalse;
+ }
+
+ return status;
+ }