--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/wlan_bearer/wlanldd/wlan_common/umac_common/src/UmacDot11Idle.cpp Tue Feb 02 02:03:13 2010 +0200
@@ -0,0 +1,797 @@
+/*
+* 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 UmacDot11Idle class
+*
+*/
+
+/*
+* %version: 41 %
+*/
+
+#include "config.h"
+#include "UmacDot11Idle.h"
+#include "UmacContextImpl.h"
+#include "UmacWsaWriteMib.h"
+#include "umacwharelease.h"
+#include "wha_mibDefaultvalues.h"
+#include "UmacWsaAddKey.h"
+#include "UmacWsaKeyIndexMapper.h"
+
+#ifndef NDEBUG
+const TInt8 WlanDot11Idle::iName[] = "dot11-idle";
+
+const TUint8 WlanDot11Idle::iStateName
+ [ESTATEMAX][KMaxStateStringLength] =
+ {
+ {"EINIT"},
+ {"EWRITEMIB"},
+ {"EFINIT"}
+ };
+
+const TUint8 WlanDot11Idle::iEventName
+ [EEVENTMAX][KMaxEventStringLength] =
+ {
+ {"ESTATEENTRY"}, {"ETXCOMPLETE"}, {"ESCAN"},
+ {"ECONNECT"}, {"ECONNECTIBSS"}, {"EDISCONNECT"},
+ {"ERELEASE"}, {"EABORT"}
+ };
+#endif
+
+// ================= MEMBER FUNCTIONS =======================
+
+#ifndef NDEBUG
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+const TInt8* WlanDot11Idle::GetStateName( TUint8& aLength ) const
+ {
+ aLength = sizeof( iName );
+ return iName;
+ }
+#endif
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::Set( TInt aCompletionCode )
+ {
+ iEventMask |= KCompleteUponEntry;
+ iCompletionCode = aCompletionCode;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::CompleteScanUponEntry()
+ {
+ iEventMask |= KIndicateScanCompletionUponEntry;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::Entry( WlanContextImpl& aCtxImpl )
+ {
+ if ( aCtxImpl.WsaCmdActive() )
+ {
+ // sanity checking code
+ OsAssert( (TUint8*)("UMAC * panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+
+ if ( iState != EINIT )
+ {
+ // this is NOT the start of the the FSM actions
+ // note that we send the ETXCOMPLETE event as the states
+ // that wait for it are the only ones that can be interrupted
+ // as they are asynchronous operations by nature
+ // and wait for corresponding WHA completion method
+ Fsm( aCtxImpl, ETXCOMPLETE );
+ }
+ else
+ {
+ // this is the start of the the FSM actions
+ Fsm( aCtxImpl, ESTATEENTRY );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::Exit( WlanContextImpl& /*aCtxImpl*/ )
+ {
+ // reset fsm for the next time we come back to this state
+ iState = EINIT;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TInt WlanDot11Idle::StartIBSS(
+ WlanContextImpl& aCtxImpl,
+ const TSSID& aSSID,
+ TUint32 aBeaconInterval,
+ TUint32 aAtim,
+ TUint32 aChannel,
+ TEncryptionStatus aEncryptionStatus)
+ {
+ aCtxImpl.NetworkOperationMode( WHA::EIBSS );
+ GenerateRandomBssIDForIbss( aCtxImpl );
+ (aCtxImpl.GetSsId()) = aSSID;
+ aCtxImpl.NetworkChannelNumeber( aChannel );
+ aCtxImpl.NetworkBeaconInterval( aBeaconInterval );
+ aCtxImpl.AtimWindow( aAtim );
+ aCtxImpl.UseShortPreamble( ETrue );
+ (aCtxImpl.EncryptionStatus()) = aEncryptionStatus;
+
+ // clear & set our supported rates
+ //
+ aCtxImpl.GetOurSupportedRatesIE().Clear();
+ aCtxImpl.GetOurExtendedSupportedRatesIE().Clear();
+
+ TUint rateCount ( 0 );
+ TUint8 rate_to_add( 0 );
+ aCtxImpl.ClearBasicRateSet();
+ aCtxImpl.GetMinBasicRate() = 0;
+ aCtxImpl.GetMaxBasicRate() = 0;
+
+ for (TUint i = 0; i < KMaxNumberOfDot11bAndgRates; ++i )
+ {
+ OsTracePrint(
+ KUmacDetails,
+ (TUint8*)("UMAC: WlanDot11Idle::StartIBSS(): iSupportedRate: %d"),
+ aCtxImpl.iSupportedRatesLookUpTable[i].iSupportedRate );
+
+ if ( aCtxImpl.iSupportedRatesLookUpTable[i].iSupportedRate)
+ {
+ if ( rateCount < KMaxNumberOfRates )
+ {
+ rate_to_add
+ = aCtxImpl.iSupportedRatesLookUpTable[i].iSupportedRate;
+
+ if ( rate_to_add == E802Dot11Rate1MBit ||
+ rate_to_add == E802Dot11Rate2MBit ||
+ rate_to_add == E802Dot11Rate5p5MBit ||
+ rate_to_add == E802Dot11Rate11MBit )
+ {
+ // make this rate a basic rate
+ rate_to_add |= KBasicRateMask;
+ // and add it to our WHA basic rate mask
+ aCtxImpl.BasicRateSetBitSet(
+ aCtxImpl.iSupportedRatesLookUpTable[i].iWsaRate );
+
+ // store min basic rate
+ if ( aCtxImpl.GetMinBasicRate() == 0 )
+ {
+ aCtxImpl.GetMinBasicRate() =
+ aCtxImpl.iSupportedRatesLookUpTable[i].iWsaRate;
+ }
+
+ // store max basic rate
+ if ( aCtxImpl.GetMaxBasicRate() <
+ aCtxImpl.iSupportedRatesLookUpTable[i].iWsaRate )
+ {
+ aCtxImpl.GetMaxBasicRate()
+ = aCtxImpl.iSupportedRatesLookUpTable[i].iWsaRate;
+ }
+ }
+
+ aCtxImpl.GetOurSupportedRatesIE().Append( rate_to_add );
+
+ ++rateCount;
+ OsTracePrint(
+ KUmacDetails,
+ (TUint8*)("UMAC: rateCount: %d"), rateCount );
+ }
+ else
+ {
+ aCtxImpl.GetOurExtendedSupportedRatesIE().Append(
+ aCtxImpl.iSupportedRatesLookUpTable[i].iSupportedRate );
+
+ OsTracePrint( KUmacDetails,
+ (TUint8*)("UMAC: %d:th rate added to ext rates"), i + 1 );
+ }
+ }
+ }
+
+#ifndef NDEBUG
+ OsTracePrint(
+ KUmacDetails,
+ (TUint8*)("UMAC: WlanDot11Idle::StartIBSS(): supported rates len: %d"),
+ aCtxImpl.GetOurSupportedRatesIE().iHeader.iLength );
+
+
+ TUint8* ptr
+ = reinterpret_cast<TUint8*>
+ (&(aCtxImpl.GetOurSupportedRatesIE().iSupportedRatesIE));
+ for (TUint8 j = 0; j < aCtxImpl.GetOurSupportedRatesIE().iHeader.iLength; j++ )
+ {
+ OsTracePrint(
+ KUmacDetails,
+ (TUint8*)("UMAC: WlanDot11Idle::StartIBSS(): supported rate: %d"),
+ *ptr );
+ ptr++;
+ }
+
+ OsTracePrint(
+ KUmacDetails,
+ (TUint8*)("UMAC: WlanDot11Idle::StartIBSS(): ext supported rates len: %d"),
+ aCtxImpl.GetOurExtendedSupportedRatesIE().iHeader.iLength );
+
+ ptr = reinterpret_cast<TUint8*>
+ (&(aCtxImpl.GetOurExtendedSupportedRatesIE().iSupportedRatesIE));
+ for (TUint8 j = 0
+ ; j < aCtxImpl.GetOurExtendedSupportedRatesIE().iHeader.iLength
+ ; j++ )
+ {
+ OsTracePrint( KUmacDetails,
+ (TUint8*)("UMAC: extended supported rate: %d"), *ptr );
+ ptr++;
+ }
+
+ OsTracePrint( KUmacDetails, (TUint8*)
+ ("UMAC: min basic WHA rate: 0x%08x"), aCtxImpl.GetMinBasicRate() );
+ OsTracePrint( KUmacDetails, (TUint8*)
+ ("UMAC: max basic WHA rate: 0x%08x"), aCtxImpl.GetMaxBasicRate() );
+
+#endif
+
+ // as we are starting our own IBSS nw, the "common" rates between us
+ // and the network are our supported rates
+ aCtxImpl.RateBitMask( aCtxImpl.WHASettings().iRates );
+
+ // determine U-APSD usage for the ACs/Tx queues; which in this (IBSS) case
+ // means disabling U-APSD
+ DetermineAcUapsdUsage( aCtxImpl );
+
+ // inform the next state that we are starting a new IBSS
+ aCtxImpl.iStates.iPrepareForIbssMode.Set( ETrue );
+
+ Fsm( aCtxImpl, ECONNECTIBSS );
+
+ // global state transition will occur
+ return ETrue;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11Idle::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 )
+ {
+ TBool ret( ETrue );
+
+ (aCtxImpl.GetBssId())= aBSSID;
+ (aCtxImpl.GetSsId()) = aSSID;
+ (aCtxImpl.EncryptionStatus()) = aEncryptionStatus;
+ (aCtxImpl.AuthenticationAlgorithmNumber()) = aAuthAlgorithmNbr;
+ // set the BSSID field
+ (aCtxImpl.GetAuthenticationFrame()).iHeader.iBSSID
+ = (aCtxImpl.GetBssId());
+ (aCtxImpl.GetHtAuthenticationFrame()).iHeader.iBSSID
+ = (aCtxImpl.GetBssId());
+ // set the DA field
+ (aCtxImpl.GetAuthenticationFrame()).iHeader.iDA
+ = (aCtxImpl.GetBssId());
+ (aCtxImpl.GetHtAuthenticationFrame()).iHeader.iDA
+ = (aCtxImpl.GetBssId());
+ // set the SA field
+ (aCtxImpl.GetAuthenticationFrame()).iHeader.iSA
+ = aCtxImpl.iWlanMib.dot11StationId;
+ (aCtxImpl.GetHtAuthenticationFrame()).iHeader.iSA
+ = aCtxImpl.iWlanMib.dot11StationId;
+ aCtxImpl.NetworkOperationMode(
+ aIsInfra ? WHA::EBSS : WHA::EIBSS );
+
+ // store Tx IE data for later access
+ // pointers supplied are valid to the point the
+ // corresponding completion method is called
+ aCtxImpl.IeData( aIeData );
+ aCtxImpl.IeDataLength( aIeDataLength );
+
+
+ // check do we meet the requirements for the network
+ // and construct necessary objects for establishing the connection
+ if ( InitNetworkConnect(
+ aCtxImpl,
+ aScanResponseFrameBodyLength,
+ aScanResponseFrameBody ) )
+ {
+ // continue
+
+ // make WHA types
+ WHA::SSSID ssid;
+ ssid.iSSIDLength = aSSID.ssidLength;
+ os_memcpy( ssid.iSSID, aSSID.ssid, ssid.iSSIDLength );
+
+ // infrastructure or IBSS mode
+ if ( aIsInfra )
+ {
+ OsTracePrint( KUmacDetails, (TUint8*)
+ ("UMAC: WlanDot11Idle::Connect: infra"));
+
+ Fsm( aCtxImpl, ECONNECT );
+ }
+ else // --- IBSS mode ---
+ {
+ OsTracePrint( KUmacDetails, (TUint8*)
+ ("UMAC: WlanDot11Idle::Connect: IBSS"));
+
+ Fsm( aCtxImpl, ECONNECTIBSS );
+ }
+ }
+ else // --- InitNetworkConnect failure ---
+ {
+ // abort
+ ret = EFalse;
+ OnOidComplete( aCtxImpl, KErrGeneral );
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11Idle::Disconnect(
+ WlanContextImpl& aCtxImpl )
+ {
+ Fsm( aCtxImpl, EDISCONNECT );
+
+ // global state transition will occur
+ return ETrue;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11Idle::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.iIdleScanningMode.Set(
+ aMode, aSSID, aScanRate, aChannels,
+ aMinChannelTime, aMaxChannelTime, aSplitScan );
+
+ Fsm( aCtxImpl, ESCAN );
+
+ return ETrue; // global statemachine transition will occur
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::FinitSystem(
+ WlanContextImpl& aCtxImpl )
+ {
+ Fsm( aCtxImpl, ERELEASE );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11Idle::AddBroadcastWepKey(
+ WlanContextImpl& aCtxImpl,
+ TUint32 aKeyIndex,
+ TBool aUseAsDefaulKey,
+ TUint32 aKeyLength,
+ const TUint8 aKey[KMaxWEPKeyLength],
+ const TMacAddress& aMac )
+ {
+ return OnAddBroadcastWepKey( aCtxImpl, aKeyIndex, aUseAsDefaulKey,
+ EFalse, // do not set as PTK
+ aKeyLength, aKey, aMac );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool WlanDot11Idle::AddUnicastWepKey(
+ WlanContextImpl& aCtxImpl,
+ const TMacAddress& aMacAddr,
+ TUint32 aKeyLength,
+ const TUint8 aKey[KMaxWEPKeyLength])
+ {
+ // allocate memory for the key structure
+ WHA::SWepPairwiseKey* key = static_cast<WHA::SWepPairwiseKey*>
+ (os_alloc( WHA::SWepPairwiseKey::KHeaderSize + aKeyLength ));
+
+ if ( !key )
+ {
+ // allocation failure
+ Fsm( aCtxImpl, EABORT );
+ return EFalse;
+ }
+
+ os_memcpy(
+ &(key->iMacAddr),
+ aMacAddr.iMacAddress,
+ sizeof(key->iMacAddr) );
+ key->iKeyLengthInBytes = static_cast<TUint8>(aKeyLength);
+ os_memcpy( key->iKey, aKey, key->iKeyLengthInBytes );
+
+ WlanWsaAddKey& wsa_cmd = aCtxImpl.WsaAddKey();
+ wsa_cmd.Set( aCtxImpl,
+ WHA::EWepPairWiseKey,
+ key,
+ WlanWsaKeyIndexMapper::Extract( WHA::EWepPairWiseKey ) );
+
+ // change global state: entry procedure triggers action
+ ChangeState( aCtxImpl,
+ *this, // prev state
+ wsa_cmd, // next state
+ // the ACT
+ KCompleteManagementRequest
+ );
+
+ os_free( key ); // allways remember to release the memory
+
+ // signal caller that a state transition occurred
+ return ETrue;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::ChangeInternalState(
+ WlanContextImpl& aCtxImpl,
+ TState aNewState )
+ {
+ iState = aNewState;
+ Fsm( aCtxImpl, ESTATEENTRY );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::Fsm(
+ WlanContextImpl& aCtxImpl,
+ TEvent aEvent )
+ {
+ OsTracePrint( KUmacDetails,
+ (TUint8*)("UMAC * dot11-idle * FSM EVENT") );
+#ifndef NDEBUG
+ OsTracePrint( KUmacDetails, (TUint8*)("event:"));
+ OsTracePrint( KUmacDetails, iEventName[aEvent] );
+ OsTracePrint( KUmacDetails, (TUint8*)("state:"));
+ OsTracePrint( KUmacDetails, iStateName[iState] );
+#endif
+
+ switch ( aEvent )
+ {
+ case ESTATEENTRY:
+ OnStateEntryEvent( aCtxImpl );
+ break;
+ case ETXCOMPLETE:
+ OnTxCompleteEvent( aCtxImpl );
+ break;
+ case ESCAN:
+ OnScanEvent( aCtxImpl );
+ break;
+ case ECONNECT:
+ OnConnectEvent( aCtxImpl );
+ break;
+ case ECONNECTIBSS:
+ OnConnectIbssEvent( aCtxImpl );
+ break;
+ case EDISCONNECT:
+ OnDisconnectEvent( aCtxImpl );
+ break;
+ case ERELEASE:
+ OnReleaseEvent( aCtxImpl );
+ break;
+ case EABORT:
+ OnAbortEvent( aCtxImpl );
+ break;
+ default:
+ // catch internal FSM programming error
+#ifndef NDEBUG
+ OsTracePrint( KErrorLevel, (TUint8*)("event:"));
+ OsTracePrint( KErrorLevel, iEventName[aEvent] );
+#endif
+ OsAssert( (TUint8*)("* UMAC * panic"),
+ (TUint8*)(WLAN_FILE), __LINE__ );
+ break;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::OnStateEntryEvent(
+ WlanContextImpl& aCtxImpl )
+ {
+ switch ( iState )
+ {
+ case EINIT:
+ if ( aCtxImpl.Reassociate() )
+ {
+ // a roaming case
+ ChangeInternalState( aCtxImpl, EFINIT );
+ }
+ else
+ {
+ // not a roaming case
+ ChangeInternalState( aCtxImpl, EWRITEMIB );
+ }
+ break;
+ case EWRITEMIB:
+ WriteSleepModeMib( aCtxImpl );
+ break;
+ case EFINIT:
+ // fsm execution complete
+
+ // execute OID completion if necessary
+ CompleteOid( aCtxImpl );
+ // indicate scan completion if necessary
+ IndicateScanCompletion( aCtxImpl );
+ break;
+ default:
+ // catch internal FSM programming error
+#ifndef NDEBUG
+ OsTracePrint( KErrorLevel, (TUint8*)("state:"));
+ OsTracePrint( KErrorLevel, iStateName[iState] );
+#endif
+ OsAssert( (TUint8*)("* UMAC * panic"),
+ (TUint8*)(WLAN_FILE), __LINE__ );
+ break;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::OnTxCompleteEvent(
+ WlanContextImpl& aCtxImpl )
+ {
+ switch ( iState )
+ {
+ case EWRITEMIB:
+ ChangeInternalState( aCtxImpl, EFINIT );
+ break;
+ case EFINIT:
+ // default handler has issued a WHA command and we
+ // have come back to this object
+ // we have absolutely nothing to do here
+ // expect mayby complete something
+ CompleteOid( aCtxImpl );
+ break;
+ default:
+ // catch internal FSM programming error
+#ifndef NDEBUG
+ OsTracePrint( KErrorLevel, (TUint8*)("state:"));
+ OsTracePrint( KErrorLevel, iStateName[iState] );
+#endif
+ OsAssert( (TUint8*)("* UMAC * panic"),
+ (TUint8*)(WLAN_FILE), __LINE__ );
+ break;
+ }
+ }
+
+// ---------------------------------------------------------
+// simulate macnotresponding error
+// ---------------------------------------------------------
+//
+void WlanDot11Idle::OnAbortEvent(
+ WlanContextImpl& aCtxImpl )
+ {
+ OsTracePrint( KWarningLevel, (TUint8*)("UMAC * dot11-idle * abort") );
+
+ DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
+ }
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::OnScanEvent(
+ WlanContextImpl& aCtxImpl )
+ {
+ // change global state: entry procedure triggers action
+ ChangeState( aCtxImpl,
+ *this, // prev state
+ aCtxImpl.iStates.iIdleScanningMode // next state
+ );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::OnConnectEvent(
+ WlanContextImpl& aCtxImpl )
+ {
+ // change global state: entry procedure triggers action
+ ChangeState( aCtxImpl,
+ *this, // prev state
+ aCtxImpl.iStates.iPrepareForBssMode // next state
+ );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::OnConnectIbssEvent(
+ WlanContextImpl& aCtxImpl )
+ {
+ ChangeState( aCtxImpl,
+ *this, // prev state
+ aCtxImpl.iStates.iPrepareForIbssMode // next state
+ );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::OnDisconnectEvent(
+ WlanContextImpl& aCtxImpl )
+ {
+ // set completion code for the oid
+ Set( KErrNone );
+
+ // change global state: entry procedure triggers action
+ ChangeState( aCtxImpl,
+ *this, // prev state
+ aCtxImpl.iStates.iSoftResetState // next state
+ );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::OnReleaseEvent(
+ WlanContextImpl& aCtxImpl )
+ {
+ // register oid completion by setting completion value
+ Set( KErrNone );
+ // and execute transition
+ ChangeState( aCtxImpl,
+ *this, // prev state
+ aCtxImpl.WlanWhaRelease() // next state
+ );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::WriteSleepModeMib(
+ WlanContextImpl& aCtxImpl )
+ {
+ WHA::SsleepMode* mib
+ = static_cast<WHA::SsleepMode*>(os_alloc( sizeof( WHA::SsleepMode ) ));
+
+ if ( !mib )
+ {
+ // allocation failure
+ Fsm( aCtxImpl, EABORT );
+ return;
+ }
+
+ // allocation success continue
+ mib->iMode = WHA::KLowPowerMode;
+
+ WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
+ wha_cmd.Set(
+ aCtxImpl, WHA::KMibSleepMode, sizeof(*mib), mib );
+
+ // change global state: entry procedure triggers action
+ ChangeState( aCtxImpl,
+ *this, // prev state
+ wha_cmd // next state
+ );
+
+ // as the parameters have been supplied we can now deallocate
+ os_free( mib );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::GenerateRandomBssIDForIbss(
+ WlanContextImpl& aCtxImpl ) const
+ {
+ // generate random BSSID for IBSS
+ TMacAddress mac;
+ TUint16* ptr = reinterpret_cast<TUint16*>(mac.iMacAddress);
+ const TUint16* const ptr_end
+ = ptr + (sizeof(TMacAddress) / sizeof(TUint16));
+
+ while ( ptr != ptr_end )
+ {
+ *ptr = aCtxImpl.Random();
+ ++ptr;
+ }
+
+ // the Universal/Local bit must be set ( 2nd bit of octet 0 )
+ // the Induvidual/Group bit must be cleared ( 1st bit of octet 0 )
+ GroupBit( mac, EFalse ); // clear
+ LocalBit( mac ); // set
+
+ // store the BSSID
+ aCtxImpl.GetBssId() = mac;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::CompleteOid(
+ WlanContextImpl& aCtxImpl )
+ {
+ if ( iEventMask & KCompleteUponEntry )
+ {
+ iEventMask &= ~KCompleteUponEntry;
+
+ OnOidComplete( aCtxImpl, iCompletionCode );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void WlanDot11Idle::IndicateScanCompletion(
+ WlanContextImpl& aCtxImpl )
+ {
+ if ( iEventMask & KIndicateScanCompletionUponEntry )
+ {
+ iEventMask &= ~KIndicateScanCompletionUponEntry;
+
+ OsTracePrint( KScan, (TUint8*)
+ ("UMAC: WlanDot11Idle::IndicateScanCompletion: Send scan complete indication"));
+
+ OnInDicationEvent( aCtxImpl, EScanCompleted );
+ }
+ }