wlan_bearer/wlanldd/wlan_common/umac_common/src/UmacDot11Idle.cpp
changeset 0 c40eb8fe8501
child 19 629e60dfa279
--- /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 );
+        }
+    }