wlan_bearer/wlanldd/wlan_common/umac_common/src/UmacDot11PrepareForIbssMode.cpp
changeset 0 c40eb8fe8501
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlan_bearer/wlanldd/wlan_common/umac_common/src/UmacDot11PrepareForIbssMode.cpp	Tue Feb 02 02:03:13 2010 +0200
@@ -0,0 +1,835 @@
+/*
+* Copyright (c) 2005-2008 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 WlanDot11PrepareForIbssMode class
+*
+*/
+
+/*
+* %version: 28 %
+*/
+
+#include "config.h"
+#include "UmacDot11PrepareForIbssMode.h"
+#include "UmacWsaWriteMib.h"
+#include "UmacWsaJoin.h"
+#include "UmacContextImpl.h"
+#include "wha_mibDefaultvalues.h"
+
+const TUint KAllocLen( WHA::KBeaconStorageSize + WHA::StemplateFrame::KHeaderSize );
+
+#ifndef NDEBUG
+const TInt8 WlanDot11PrepareForIbssMode::iName[] = "dot11-prepareforibssmode";
+
+const TUint8 WlanDot11PrepareForIbssMode::iStateName
+    [ESTATEMAX][KMaxStateStringLength] = 
+    {
+        {"EINIT"}, 
+        {"ESETSLEEPMODE"},
+        {"ESETDOT11SLOTTIME"},
+        {"ESETCTSTOSELF"},
+        {"ESETBEACON"},
+        {"ESETPROBERESP"},
+        {"ESETTXRATEPOLICY"},
+        {"ESETBEACONLOSTCOUNT"},
+        {"EJOIN"},
+        {"ECONTINUEDOT11TRAVERSE"}
+    };
+
+const TUint8 WlanDot11PrepareForIbssMode::iEventName
+    [EEVENTMAX][KMaxEventStringLength] = 
+    {
+        {"ESTATEENTRY"}, {"ETXCOMPLETE"}, {"EABORT"}
+    };
+#endif
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// ---------------------------------------------------------
+// 
+// ---------------------------------------------------------
+//
+WlanDot11PrepareForIbssMode::~WlanDot11PrepareForIbssMode()
+    {
+    iMemory = NULL;
+    }
+
+// ---------------------------------------------------------
+// 
+// ---------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::Set( TBool aStartIbss )
+    {
+    iStartIbss = aStartIbss;
+    }
+
+// ---------------------------------------------------------
+// 
+// ---------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::Entry( 
+    WlanContextImpl& aCtxImpl )
+    {
+    if ( aCtxImpl.WsaCmdActive() )
+        {
+        // sanity checking code
+        OsAssert( (TUint8*)("UMAC * panic"), 
+            (TUint8*)(WLAN_FILE), __LINE__ );
+        }
+
+    // don't want to do event dispatching here as we want
+    // to run this dot11 state critter in non pre-emptive mode
+
+    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 WlanDot11PrepareForIbssMode::Exit( 
+    WlanContextImpl& /*aCtxImpl*/ )
+    {
+    // we are traversing to a new dot11 state 
+    // make sure we don't generate a memory leakage
+    os_free( iMemory );
+    iMemory = NULL;
+    
+    iState = EINIT; 
+    iStartIbss = EFalse;
+    }
+
+#ifndef NDEBUG 
+// ---------------------------------------------------------
+// 
+// ---------------------------------------------------------
+//
+const TInt8* WlanDot11PrepareForIbssMode::GetStateName( 
+    TUint8& aLength ) const
+    {
+    aLength = sizeof( iName );
+    return iName;
+    }
+#endif
+
+// ---------------------------------------------------------
+// 
+// ---------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::ChangeInternalState( 
+    WlanContextImpl& aCtxImpl, 
+    TState aNewState )
+    {
+    iState = aNewState;
+    Fsm( aCtxImpl, ESTATEENTRY );
+    }
+
+// ---------------------------------------------------------
+// 
+// ---------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::Fsm( 
+    WlanContextImpl& aCtxImpl, 
+    TEvent aEvent )
+    {
+    OsTracePrint( KUmacDetails, 
+        (TUint8*)("UMAC * dot11-prepareforibssmode * 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 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;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// Handler for state entry event.
+// It is guaranteed by the FSM framework that no WHA command is pending
+// when this method is entered
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::OnStateEntryEvent( 
+    WlanContextImpl& aCtxImpl )
+    {
+    switch ( iState )
+        {
+        case EINIT:
+            iMemory = static_cast<TUint8*>(os_alloc( KAllocLen ));
+            if ( iMemory )
+                {
+                // as we are about to join/start a new network, reset BSS Loss
+                // indicators
+                aCtxImpl.ResetBssLossIndications();
+
+                // start the FSM traversal
+                ChangeInternalState( aCtxImpl, ESETSLEEPMODE );
+                }
+            else
+                {
+                // allocation failure
+                Fsm( aCtxImpl, EABORT );
+                }
+            break;
+        case ESETSLEEPMODE:
+            SetSleepMode( aCtxImpl );
+            break;
+        case ESETDOT11SLOTTIME:
+            SetDot11SlotTime( aCtxImpl );
+            break;
+        case ESETCTSTOSELF:
+            SetCtsToSelf( aCtxImpl );
+            break;
+        case ESETBEACON:
+            ConfigureBeaconTemplate( aCtxImpl );
+            break;
+        case ESETPROBERESP:
+            ConfigureProbeResponseTemplate( aCtxImpl );
+            break;
+        case ESETTXRATEPOLICY:
+            SetTxRatePolicy( aCtxImpl );
+            break;        
+        case ESETBEACONLOSTCOUNT:
+            SetBeaconLostCount( aCtxImpl );
+            break;        
+        case EJOIN:
+            Join( aCtxImpl );
+            break;
+        case ECONTINUEDOT11TRAVERSE:
+            ContinueDot11StateTraversal( 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 WlanDot11PrepareForIbssMode::OnTxCompleteEvent( 
+    WlanContextImpl& aCtxImpl )
+    {
+    switch ( iState )
+        {
+        case ESETSLEEPMODE:
+            // depending if the WLAN vendor specific solution
+            // implements dot11slottime mib we will configure it
+            if ( aCtxImpl.WHASettings().iCapability 
+                & WHA::SSettings::KDot11SlotTime )
+                {
+                // supported
+                ChangeInternalState( aCtxImpl, ESETDOT11SLOTTIME );
+                }
+            else
+                {
+                // not supported so skip it
+                OsTracePrint( KWarningLevel, (TUint8*)
+                    ("UMAC * dot11-prepareforibssmode"));
+                OsTracePrint( KWarningLevel, (TUint8*)
+                    ("no support for dot11slottime mib skipping"));
+
+                ChangeInternalState( aCtxImpl, ESETCTSTOSELF );
+                }
+            break;
+        case ESETDOT11SLOTTIME:
+            ChangeInternalState( aCtxImpl, ESETCTSTOSELF );
+            break;
+        case ESETCTSTOSELF:
+            ChangeInternalState( aCtxImpl, ESETBEACON );
+            break;
+        case ESETBEACON:
+            ChangeInternalState( aCtxImpl, ESETPROBERESP );
+            break;
+        case ESETPROBERESP:
+            ChangeInternalState( aCtxImpl, ESETTXRATEPOLICY );
+            break;
+        case ESETTXRATEPOLICY:
+            ChangeInternalState( aCtxImpl, ESETBEACONLOSTCOUNT );
+            break;
+        case ESETBEACONLOSTCOUNT:
+            ChangeInternalState( aCtxImpl, EJOIN );
+            break;
+        case EJOIN:
+            ChangeInternalState( aCtxImpl, ECONTINUEDOT11TRAVERSE );
+            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 WlanDot11PrepareForIbssMode::SetSleepMode( 
+    WlanContextImpl& aCtxImpl )
+    {
+    WHA::SsleepMode* mib 
+        = reinterpret_cast<WHA::SsleepMode*>(iMemory); 
+
+    mib->iMode = WHA::KPowerDownMode;
+    
+    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
+        );           
+    }
+
+// ---------------------------------------------------------
+// the caller of thismethod has allready checked does the 
+// WLAN vendor specific solution support this mib so we 
+// don't have to anymore check it here again
+// ---------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::SetDot11SlotTime( 
+    WlanContextImpl& aCtxImpl )
+    {
+    WHA::Sdot11SlotTime* mib 
+        = reinterpret_cast<WHA::Sdot11SlotTime*>(iMemory); 
+
+    if ( aCtxImpl.UseShortSlotTime() )
+        {
+        mib->iDot11SlotTime = WHA::KSlotTime9;        
+        }
+    else
+        {
+        mib->iDot11SlotTime = WHA::KSlotTime20;
+        }
+
+    WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
+    wha_cmd.Set( 
+        aCtxImpl, WHA::KMibDot11SlotTime, sizeof(*mib), mib );
+
+    // change global state: entry procedure triggers action
+    ChangeState( aCtxImpl, 
+        *this,              // prev state
+        wha_cmd             // next state
+        );           
+    }
+
+// ---------------------------------------------------------
+// 
+// ---------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::SetCtsToSelf( 
+    WlanContextImpl& aCtxImpl )
+    {    
+    WHA::SctsToSelf* mib 
+        = reinterpret_cast<WHA::SctsToSelf*>(iMemory); 
+
+    if ( aCtxImpl.ProtectionBitSet() )
+        {
+        OsTracePrint( 
+            KUmacDetails, 
+            (TUint8*)("UMAC: WlanDot11PrepareForIbssMode::SetCtsToSelf(): enable CTS to self") );
+            
+        mib->iCtsToSelf = ETrue;
+        }
+    else
+        {
+        OsTracePrint( 
+            KUmacDetails, 
+            (TUint8*)("UMAC: WlanDot11PrepareForIbssMode::SetCtsToSelf(): disable CTS to self") );
+
+        mib->iCtsToSelf = EFalse;
+        }
+
+    WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
+    wha_cmd.Set( 
+        aCtxImpl, WHA::KMibCtsToSelf, sizeof(*mib), mib );
+
+    // change global state: entry procedure triggers action
+    ChangeState( aCtxImpl, 
+        *this,              // prev state
+        wha_cmd             // next state
+        );           
+    }
+
+// ---------------------------------------------------------
+// simulate macnotresponding error
+// ---------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::OnAbortEvent( 
+    WlanContextImpl& aCtxImpl )
+    {
+    // memory is released by Exit() method
+    OsTracePrint( KWarningLevel, 
+        (TUint8*)("UMAC: WlanDot11PrepareForIbssMode::OnAbortEvent") );
+
+    DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
+    }
+
+// ---------------------------------------------------------
+// 
+// ---------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::ConfigureBeaconTemplate( 
+    WlanContextImpl& aCtxImpl )
+    {
+    TUint32 length( 0 );
+    ConfigureTemplate( aCtxImpl, length );
+
+    // default frame configuration is done 
+    // now set beacon frame specific configuration
+    SManagementFrameHeader* hdr 
+        = reinterpret_cast<SManagementFrameHeader*>
+        (iMemory + WHA::StemplateFrame::KHeaderSize );
+                    
+    hdr->iDA = KBroadcastMacAddr;
+    hdr->iFrameControl.iType = E802Dot11FrameTypeBeacon;
+
+    // set privacy bit depending do we have a 
+    // encryption key set or not
+    const WHA::TKeyType group_key = aCtxImpl.GroupKeyType();
+    const WHA::TKeyType pairwise_key = aCtxImpl.PairWiseKeyType();
+
+    OsTracePrint( KUmacDetails, (TUint8*)
+        ("UMAC: WlanDot11PrepareForIbssMode::ConfigureBeaconTemplate: check for WEP") );
+
+    if ( (group_key != WHA::EKeyNone
+        || pairwise_key != WHA::EKeyNone) )
+        {
+        // we have set a group or pairwise key
+        // enable privacy
+        SCapabilityInformationField* cap_ptr
+            = reinterpret_cast<SCapabilityInformationField*>
+            (reinterpret_cast<TUint8*>(hdr + 1) 
+            + KTimeStampFixedFieldLength 
+            + KBeaconIntervalFixedFieldLength);
+        
+        OsTracePrint( KUmacDetails, (TUint8*)
+            ("UMAC: WlanDot11PrepareForIbssMode::ConfigureBeaconTemplate: enable WEP") );
+
+        cap_ptr->SetWepBit();
+        }
+
+    // all done now write the MIB
+
+    WHA::StemplateFrame* mib 
+        = reinterpret_cast<WHA::StemplateFrame*>(iMemory);
+
+    mib->iFrameType = WHA::KBeaconTemplate;
+    mib->iInitialTransmitRate = BeaconTxRate( aCtxImpl );
+    mib->iLength = length;
+    
+    WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
+    
+    TUint32 mib_len( 
+        // length of MIB header
+        WHA::StemplateFrame::KHeaderSize
+        // length of the frame template
+        + mib->iLength );
+
+    // align length of MIB to 4-byte boundary
+    mib_len = Align4( mib_len );
+
+    wha_cmd.Set( 
+        aCtxImpl, 
+        WHA::KMibTemplateFrame, 
+        mib_len, 
+        mib );
+      
+    if ( iStartIbss )
+        {
+        // we are starting a new IBSS        
+        // transfer our own beacon also to mgmt client as an Rx frame
+        
+        TUint8* buffer = aCtxImpl.GetRxBuffer( 
+            mib->iLength,
+            // tell that this is an internally triggered buffer request
+            ETrue );
+        
+        if ( buffer )
+            {
+            // copy the beacon to the beginning of the buffer
+            os_memcpy( buffer, reinterpret_cast<TUint8*>(hdr), mib->iLength );
+            
+            XferDot11FrameToMgmtClient( 
+                aCtxImpl,
+                // frame beginning
+                buffer, 
+                mib->iLength, 
+                // RCPI is not relevant in this case
+                0,
+                // buffer beginning
+                buffer );
+            }
+#ifndef NDEBUG
+        else
+            {
+            // Rx buffer reservation failed. That should not happen when we are
+            // starting an IBSS
+            OsTracePrint( KErrorLevel, (TUint8*)
+                ("UMAC: Rx buf reservation failed") );        
+            OsAssert( 
+                (TUint8*)("UMAC: panic"), 
+                (TUint8*)(WLAN_FILE), 
+                __LINE__ );
+            }
+#endif        
+        }
+   
+    // change global state: entry procedure triggers action
+    ChangeState( aCtxImpl, 
+        *this,              // prev state
+        wha_cmd             // next state
+        );            
+    }
+
+// ---------------------------------------------------------
+// 
+// ---------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::ConfigureProbeResponseTemplate( 
+    WlanContextImpl& aCtxImpl )
+    {
+    TUint32 length( 0 );
+    ConfigureTemplate( aCtxImpl, length );
+
+    // default frame configuration has been done allready 
+    // now set probe response frame specific configuration
+    SManagementFrameHeader* hdr 
+        = reinterpret_cast<SManagementFrameHeader*>
+        (iMemory + WHA::StemplateFrame::KHeaderSize );
+
+    hdr->iFrameControl.iType = E802Dot11FrameTypeProbeResp;
+
+    // set privacy bit depending do we have a 
+    // encryption key set or not
+    const WHA::TKeyType group_key = aCtxImpl.GroupKeyType();
+    const WHA::TKeyType pairwise_key = aCtxImpl.PairWiseKeyType();
+
+    OsTracePrint( KUmacDetails, (TUint8*)
+        ("UMAC: WlanDot11PrepareForIbssMode::ConfigureProbeResponseTemplate: check for WEP") );
+
+    if ( (group_key != WHA::EKeyNone
+        || pairwise_key != WHA::EKeyNone) )
+        {
+        // we have set a group or pairwise key
+        // enable privacy
+        SCapabilityInformationField* cap_ptr
+            = reinterpret_cast<SCapabilityInformationField*>
+            (reinterpret_cast<TUint8*>(hdr + 1) 
+            + KTimeStampFixedFieldLength 
+            + KBeaconIntervalFixedFieldLength);
+        
+        OsTracePrint( KUmacDetails, (TUint8*)
+            ("UMAC: WlanDot11PrepareForIbssMode::ConfigureProbeResponseTemplate: enable WEP") );
+
+        cap_ptr->SetWepBit();
+        }
+
+    // all done now write the MIB
+    WHA::StemplateFrame* mib 
+        = reinterpret_cast<WHA::StemplateFrame*>(iMemory);
+    mib->iFrameType = WHA::KProbeResponseTemplate;
+    mib->iInitialTransmitRate = ProbeResponseTxRate( aCtxImpl );
+    mib->iLength = length;
+
+    WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
+
+    TUint32 mib_len( 
+        // length of MIB header
+        WHA::StemplateFrame::KHeaderSize
+        // length of the frame template
+        + mib->iLength );
+
+    // align length of MIB to 4-byte boundary
+    mib_len = Align4( mib_len );
+    
+    wha_cmd.Set( 
+        aCtxImpl, 
+        WHA::KMibTemplateFrame, 
+        mib_len, 
+        mib );
+        
+    // change global state: entry procedure triggers action
+    ChangeState( aCtxImpl, 
+        *this,              // prev state
+        wha_cmd             // next state
+        );                       
+    }
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::SetTxRatePolicy( 
+    WlanContextImpl& aCtxImpl )
+    {
+    OsTracePrint( KUmacDetails, (TUint8*)
+        ("UMAC: WlanDot11PrepareForIbssMode::SetTxRatePolicy(): rate bitmask: 0x%08x"),
+        aCtxImpl.RateBitMask() );
+
+    if ( !ConfigureTxRatePolicies( aCtxImpl ) )
+        {
+        // alloc failue just send abort event to fsm 
+        // it takes care of the rest
+        Fsm( aCtxImpl, EABORT );
+        return;        
+        }
+    }
+    
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::SetBeaconLostCount( 
+    WlanContextImpl& aCtxImpl )
+    {
+    OsTracePrint( KUmacDetails, 
+        (TUint8*)("UMAC: WlanDot11PrepareForIbssMode::SetBeaconLostCount()") );
+
+    WHA::SbeaconLostCount* mib 
+        = reinterpret_cast<WHA::SbeaconLostCount*>(iMemory);
+
+    // disable BSS lost (and thus also BSS regained) indications
+    const TUint8 KDisableIndications( 0 );
+    mib->iLostCount = KDisableIndications;
+        
+    WlanWsaWriteMib& wsa_cmd = aCtxImpl.WsaWriteMib();
+        
+    wsa_cmd.Set( 
+        aCtxImpl, WHA::KMibBeaconLostCount, sizeof(*mib), mib );
+        
+    // change global state: entry procedure triggers action
+    ChangeState( aCtxImpl, 
+        *this,              // prev state
+        wsa_cmd             // next state
+        );   
+    }
+
+// ---------------------------------------------------------
+// 
+// ---------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::Join( 
+    WlanContextImpl& aCtxImpl )
+    {
+    // templates are configured now do a join
+
+    // make WHA types
+    WHA::SSSID ssid;
+    ssid.iSSIDLength = aCtxImpl.GetSsId().ssidLength;
+    os_memcpy( 
+        ssid.iSSID, 
+        aCtxImpl.GetSsId().ssid, 
+        aCtxImpl.GetSsId().ssidLength );
+    WHA::TMacAddress mac;
+    os_memcpy( 
+        &mac, 
+        &(aCtxImpl.GetBssId()), 
+        WHA::TMacAddress::KMacAddressLength );
+
+    // feed the critter with parameters
+    aCtxImpl.WsaJoin().Set( 
+        aCtxImpl, 
+        aCtxImpl.NetworkOperationMode(), 
+        mac, 
+        // only 2.4 GHz band is supported for now, so we can hard 
+        // code it should be changed as soon as our implemetation 
+        // supports multiple bands
+        WHA::KBand2dot4GHzMask,
+        ssid, 
+        aCtxImpl.NetworkChannelNumeber(), 
+        aCtxImpl.NetworkBeaconInterval(), 
+        aCtxImpl.BasicRateSet(), 
+        aCtxImpl.AtimWindow(),  // ATIM
+        (aCtxImpl.UseShortPreamble()) 
+        ? WHA::EShortPreamble : WHA::ELongPreamble,
+        ( aCtxImpl.WHASettings().iCapability 
+          & WHA::SSettings::KProbe4Join ) ? ETrue : EFalse );
+    
+    // change global state: entry procedure triggers action
+    ChangeState( aCtxImpl, 
+        *this,              // prev state
+        aCtxImpl.WsaJoin()  // next state
+        );                       
+    }
+
+// ---------------------------------------------------------
+// 
+// ---------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::ContinueDot11StateTraversal( 
+    WlanContextImpl& aCtxImpl )
+    {
+    // join success continue state traversal
+    ChangeState( aCtxImpl, 
+        *this,                                  // prev state
+        aCtxImpl.iStates.iIbssNormalMode        // next state
+        );
+
+    // there exists no valid use case for IBSS join to fail
+    // so assume allways success
+    }
+
+// ---------------------------------------------------------
+// 
+// ---------------------------------------------------------
+//
+void WlanDot11PrepareForIbssMode::ConfigureTemplate( 
+    WlanContextImpl& aCtxImpl,
+    TUint32& aLength)
+    {    
+    // set up the template
+    os_memset( iMemory, 0, KAllocLen );
+
+    // set dot11 header
+
+    SManagementFrameHeader* hdr 
+        = reinterpret_cast<SManagementFrameHeader*>
+        (iMemory + WHA::StemplateFrame::KHeaderSize );
+
+    hdr->iSA = aCtxImpl.iWlanMib.dot11StationId;
+    hdr->iBSSID = aCtxImpl.GetBssId();
+
+    // set beacon interval
+    TUint16* ptr = 
+        (reinterpret_cast<TUint16*>(hdr + 1)) 
+        + (KTimeStampFixedFieldLength / (sizeof(*ptr)));
+    *ptr = aCtxImpl.NetworkBeaconInterval();
+
+    // set capability information
+    SCapabilityInformationField* cap_ptr
+        = reinterpret_cast<SCapabilityInformationField*>(++ptr);
+    cap_ptr->SetIbss();
+    if ( aCtxImpl.UseShortPreamble() )
+        {
+        cap_ptr->SetShortPreamble();
+        }
+    else
+        {
+        cap_ptr->ClearShortPreamble();
+        }
+
+    // set SSID
+    new (++cap_ptr) SSsIdIE( 
+        aCtxImpl.GetSsId().ssid, 
+        aCtxImpl.GetSsId().ssidLength );
+            
+    TUint8* p = reinterpret_cast<TUint8*>(cap_ptr);
+    
+    p += aCtxImpl.GetSsId().ssidLength + sizeof(SInformationElementHeader);
+
+    // set supported rates IE
+    os_memcpy( 
+        p, 
+        &(aCtxImpl.GetOurSupportedRatesIE()), 
+        aCtxImpl.GetOurSupportedRatesIE().GetIeLength() );
+
+    p += aCtxImpl.GetOurSupportedRatesIE().GetIeLength();
+
+    // set DS parameter set IE
+    new (p) SDsParameterSetIE( aCtxImpl.NetworkChannelNumeber() );        
+    p += sizeof(SDsParameterSetIE);
+
+    // set IBSS parameter set IE
+    SIbssParameterSetIE ibssparam( aCtxImpl.AtimWindow() );
+
+    // NOTE: we use memcpy for this as there is no gurantee that 
+    // SDsParameterSetIE ends as 16-bit aligned and iValue member is
+    // 16-bit long which means we could get an alignment fault
+    os_memcpy( p, &ibssparam, sizeof(SIbssParameterSetIE) );
+    p += sizeof(SIbssParameterSetIE);
+    
+    // set extended supported rates IE if it's not empty 
+    // 
+    if ( aCtxImpl.GetOurExtendedSupportedRatesIE().GetElementLength() )
+        {
+        os_memcpy( 
+            p, 
+            &(aCtxImpl.GetOurExtendedSupportedRatesIE()), 
+            aCtxImpl.GetOurExtendedSupportedRatesIE().GetIeLength() );
+        
+            p += aCtxImpl.GetOurExtendedSupportedRatesIE().GetIeLength();
+        }        
+    
+    // store length of the beacon
+    aLength = reinterpret_cast<TUint32>(p) - reinterpret_cast<TUint32>(hdr);
+    }
+
+// ---------------------------------------------------------
+// 
+// ---------------------------------------------------------
+//
+WHA::TRate WlanDot11PrepareForIbssMode::BeaconTxRate( 
+    WlanContextImpl& aCtxImpl ) const
+    {
+    return aCtxImpl.GetMinBasicRate();
+    }
+
+// ---------------------------------------------------------
+// 
+// ---------------------------------------------------------
+//
+WHA::TRate WlanDot11PrepareForIbssMode::ProbeResponseTxRate( 
+    WlanContextImpl& aCtxImpl ) const
+    {
+    return aCtxImpl.GetMinBasicRate();
+    }