wlan_bearer/wlanldd/wlan_common/umac_common/src/UmacDot11Idle.cpp
changeset 0 c40eb8fe8501
child 19 629e60dfa279
equal deleted inserted replaced
-1:000000000000 0:c40eb8fe8501
       
     1 /*
       
     2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Implementation of the UmacDot11Idle class
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 41 %
       
    20 */
       
    21 
       
    22 #include "config.h"
       
    23 #include "UmacDot11Idle.h"
       
    24 #include "UmacContextImpl.h"
       
    25 #include "UmacWsaWriteMib.h"
       
    26 #include "umacwharelease.h"
       
    27 #include "wha_mibDefaultvalues.h"
       
    28 #include "UmacWsaAddKey.h"
       
    29 #include "UmacWsaKeyIndexMapper.h"
       
    30 
       
    31 #ifndef NDEBUG
       
    32 const TInt8 WlanDot11Idle::iName[] = "dot11-idle";
       
    33 
       
    34 const TUint8 WlanDot11Idle::iStateName
       
    35     [ESTATEMAX][KMaxStateStringLength] = 
       
    36     {
       
    37         {"EINIT"}, 
       
    38         {"EWRITEMIB"},
       
    39         {"EFINIT"}
       
    40     };
       
    41 
       
    42 const TUint8 WlanDot11Idle::iEventName
       
    43     [EEVENTMAX][KMaxEventStringLength] = 
       
    44     {
       
    45         {"ESTATEENTRY"}, {"ETXCOMPLETE"}, {"ESCAN"}, 
       
    46         {"ECONNECT"}, {"ECONNECTIBSS"}, {"EDISCONNECT"}, 
       
    47         {"ERELEASE"}, {"EABORT"}
       
    48     };
       
    49 #endif
       
    50 
       
    51 // ================= MEMBER FUNCTIONS =======================
       
    52 
       
    53 #ifndef NDEBUG 
       
    54 // ---------------------------------------------------------------------------
       
    55 // 
       
    56 // ---------------------------------------------------------------------------
       
    57 //
       
    58 const TInt8* WlanDot11Idle::GetStateName( TUint8& aLength ) const
       
    59     {
       
    60     aLength = sizeof( iName );
       
    61     return iName;
       
    62     }
       
    63 #endif
       
    64 
       
    65 // ---------------------------------------------------------------------------
       
    66 // 
       
    67 // ---------------------------------------------------------------------------
       
    68 //
       
    69 void WlanDot11Idle::Set( TInt aCompletionCode ) 
       
    70     { 
       
    71     iEventMask |= KCompleteUponEntry;
       
    72     iCompletionCode = aCompletionCode; 
       
    73     }
       
    74 
       
    75 // ---------------------------------------------------------------------------
       
    76 // 
       
    77 // ---------------------------------------------------------------------------
       
    78 //
       
    79 void WlanDot11Idle::CompleteScanUponEntry()
       
    80     {
       
    81     iEventMask |= KIndicateScanCompletionUponEntry;
       
    82     }
       
    83 
       
    84 // ---------------------------------------------------------------------------
       
    85 // 
       
    86 // ---------------------------------------------------------------------------
       
    87 //
       
    88 void WlanDot11Idle::Entry( WlanContextImpl& aCtxImpl )
       
    89     {
       
    90     if ( aCtxImpl.WsaCmdActive() )
       
    91         {
       
    92         // sanity checking code
       
    93         OsAssert( (TUint8*)("UMAC * panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
    94         }
       
    95 
       
    96     if ( iState != EINIT )
       
    97         {
       
    98         // this is NOT the start of the the FSM actions
       
    99         // note that we send the ETXCOMPLETE event as the states
       
   100         // that wait for it are the only ones that can be interrupted
       
   101         // as they are asynchronous operations by nature
       
   102         // and wait for corresponding WHA completion method
       
   103         Fsm( aCtxImpl, ETXCOMPLETE );
       
   104         }
       
   105     else
       
   106         {
       
   107         // this is the start of the the FSM actions
       
   108         Fsm( aCtxImpl, ESTATEENTRY );
       
   109         }
       
   110     }
       
   111 
       
   112 // ---------------------------------------------------------------------------
       
   113 // 
       
   114 // ---------------------------------------------------------------------------
       
   115 //
       
   116 void WlanDot11Idle::Exit( WlanContextImpl& /*aCtxImpl*/ )
       
   117     {
       
   118     // reset fsm for the next time we come back to this state
       
   119     iState = EINIT;
       
   120     }
       
   121     
       
   122 // ---------------------------------------------------------------------------
       
   123 // 
       
   124 // ---------------------------------------------------------------------------
       
   125 //
       
   126 TInt WlanDot11Idle::StartIBSS(
       
   127     WlanContextImpl& aCtxImpl,
       
   128     const TSSID& aSSID,                 
       
   129     TUint32 aBeaconInterval,            
       
   130     TUint32 aAtim,                      
       
   131     TUint32 aChannel,                   
       
   132     TEncryptionStatus aEncryptionStatus)
       
   133     {
       
   134     aCtxImpl.NetworkOperationMode( WHA::EIBSS );
       
   135     GenerateRandomBssIDForIbss( aCtxImpl );
       
   136     (aCtxImpl.GetSsId()) = aSSID;   
       
   137     aCtxImpl.NetworkChannelNumeber( aChannel );
       
   138     aCtxImpl.NetworkBeaconInterval( aBeaconInterval );
       
   139     aCtxImpl.AtimWindow( aAtim );
       
   140     aCtxImpl.UseShortPreamble( ETrue );
       
   141     (aCtxImpl.EncryptionStatus()) = aEncryptionStatus;           
       
   142 
       
   143     // clear & set our supported rates
       
   144     //
       
   145     aCtxImpl.GetOurSupportedRatesIE().Clear();
       
   146     aCtxImpl.GetOurExtendedSupportedRatesIE().Clear();
       
   147     
       
   148     TUint rateCount ( 0 );
       
   149     TUint8 rate_to_add( 0 );
       
   150     aCtxImpl.ClearBasicRateSet();    
       
   151     aCtxImpl.GetMinBasicRate() = 0;
       
   152     aCtxImpl.GetMaxBasicRate() = 0;
       
   153     
       
   154     for (TUint i = 0; i < KMaxNumberOfDot11bAndgRates; ++i )
       
   155         {
       
   156         OsTracePrint( 
       
   157             KUmacDetails, 
       
   158             (TUint8*)("UMAC: WlanDot11Idle::StartIBSS(): iSupportedRate: %d"),
       
   159             aCtxImpl.iSupportedRatesLookUpTable[i].iSupportedRate );
       
   160 
       
   161         if ( aCtxImpl.iSupportedRatesLookUpTable[i].iSupportedRate)
       
   162             {
       
   163             if ( rateCount < KMaxNumberOfRates )
       
   164                 {
       
   165                 rate_to_add 
       
   166                     = aCtxImpl.iSupportedRatesLookUpTable[i].iSupportedRate;
       
   167                 
       
   168                 if ( rate_to_add == E802Dot11Rate1MBit ||
       
   169                      rate_to_add == E802Dot11Rate2MBit ||
       
   170                      rate_to_add == E802Dot11Rate5p5MBit ||
       
   171                      rate_to_add == E802Dot11Rate11MBit )
       
   172                     {
       
   173                     // make this rate a basic rate
       
   174                     rate_to_add |= KBasicRateMask;
       
   175                     // and add it to our WHA basic rate mask
       
   176                     aCtxImpl.BasicRateSetBitSet( 
       
   177                         aCtxImpl.iSupportedRatesLookUpTable[i].iWsaRate );
       
   178                     
       
   179                     // store min basic rate
       
   180                     if ( aCtxImpl.GetMinBasicRate() == 0 )
       
   181                         {
       
   182                         aCtxImpl.GetMinBasicRate() = 
       
   183                             aCtxImpl.iSupportedRatesLookUpTable[i].iWsaRate;
       
   184                         }
       
   185                     
       
   186                     // store max basic rate
       
   187                     if ( aCtxImpl.GetMaxBasicRate() < 
       
   188                          aCtxImpl.iSupportedRatesLookUpTable[i].iWsaRate )
       
   189                         {
       
   190                         aCtxImpl.GetMaxBasicRate() 
       
   191                             = aCtxImpl.iSupportedRatesLookUpTable[i].iWsaRate;
       
   192                         }
       
   193                     }
       
   194 
       
   195                 aCtxImpl.GetOurSupportedRatesIE().Append( rate_to_add );
       
   196 
       
   197                 ++rateCount;
       
   198                 OsTracePrint( 
       
   199                     KUmacDetails, 
       
   200                     (TUint8*)("UMAC: rateCount: %d"), rateCount );
       
   201                 }
       
   202             else
       
   203                 {
       
   204                 aCtxImpl.GetOurExtendedSupportedRatesIE().Append( 
       
   205                     aCtxImpl.iSupportedRatesLookUpTable[i].iSupportedRate );
       
   206 
       
   207                 OsTracePrint( KUmacDetails, 
       
   208                     (TUint8*)("UMAC: %d:th rate added to ext rates"), i + 1 );                    
       
   209                 }
       
   210             }
       
   211         }
       
   212 
       
   213 #ifndef NDEBUG 
       
   214     OsTracePrint( 
       
   215         KUmacDetails, 
       
   216         (TUint8*)("UMAC: WlanDot11Idle::StartIBSS(): supported rates len: %d"),
       
   217         aCtxImpl.GetOurSupportedRatesIE().iHeader.iLength );                    
       
   218 
       
   219 
       
   220     TUint8* ptr 
       
   221         = reinterpret_cast<TUint8*>
       
   222         (&(aCtxImpl.GetOurSupportedRatesIE().iSupportedRatesIE));
       
   223     for (TUint8 j = 0; j < aCtxImpl.GetOurSupportedRatesIE().iHeader.iLength; j++ )
       
   224         {
       
   225         OsTracePrint( 
       
   226             KUmacDetails, 
       
   227             (TUint8*)("UMAC: WlanDot11Idle::StartIBSS(): supported rate: %d"),
       
   228             *ptr );                    
       
   229         ptr++;
       
   230         }
       
   231 
       
   232     OsTracePrint( 
       
   233         KUmacDetails, 
       
   234         (TUint8*)("UMAC: WlanDot11Idle::StartIBSS(): ext supported rates len: %d"),
       
   235         aCtxImpl.GetOurExtendedSupportedRatesIE().iHeader.iLength );                    
       
   236 
       
   237     ptr = reinterpret_cast<TUint8*>
       
   238         (&(aCtxImpl.GetOurExtendedSupportedRatesIE().iSupportedRatesIE));
       
   239     for (TUint8 j = 0 
       
   240         ; j < aCtxImpl.GetOurExtendedSupportedRatesIE().iHeader.iLength 
       
   241         ; j++ )
       
   242         {
       
   243         OsTracePrint( KUmacDetails, 
       
   244             (TUint8*)("UMAC: extended supported rate: %d"), *ptr );
       
   245         ptr++;
       
   246         }
       
   247 
       
   248     OsTracePrint( KUmacDetails, (TUint8*)
       
   249         ("UMAC: min basic WHA rate: 0x%08x"), aCtxImpl.GetMinBasicRate() );
       
   250     OsTracePrint( KUmacDetails, (TUint8*)
       
   251         ("UMAC: max basic WHA rate: 0x%08x"), aCtxImpl.GetMaxBasicRate() );
       
   252     
       
   253 #endif
       
   254     
       
   255     // as we are starting our own IBSS nw, the "common" rates between us
       
   256     // and the network are our supported rates
       
   257     aCtxImpl.RateBitMask( aCtxImpl.WHASettings().iRates );
       
   258 
       
   259     // determine U-APSD usage for the ACs/Tx queues; which in this (IBSS) case
       
   260     // means disabling U-APSD 
       
   261     DetermineAcUapsdUsage( aCtxImpl );
       
   262 
       
   263     // inform the next state that we are starting a new IBSS
       
   264     aCtxImpl.iStates.iPrepareForIbssMode.Set( ETrue );
       
   265 
       
   266     Fsm( aCtxImpl, ECONNECTIBSS );
       
   267 
       
   268     // global state transition will occur
       
   269     return ETrue;
       
   270     }
       
   271 
       
   272 // ---------------------------------------------------------------------------
       
   273 // 
       
   274 // ---------------------------------------------------------------------------
       
   275 //
       
   276 TBool WlanDot11Idle::Connect(
       
   277     WlanContextImpl& aCtxImpl,
       
   278     const TSSID& aSSID,                 
       
   279     const TMacAddress& aBSSID,          
       
   280     TUint16 aAuthAlgorithmNbr,      
       
   281     TEncryptionStatus aEncryptionStatus,
       
   282     TBool aIsInfra,
       
   283     TUint16 aScanResponseFrameBodyLength,
       
   284     const TUint8* aScanResponseFrameBody,
       
   285     const TUint8* aIeData,
       
   286     TUint16 aIeDataLength )
       
   287     {
       
   288     TBool ret( ETrue );
       
   289 
       
   290     (aCtxImpl.GetBssId())= aBSSID;   
       
   291     (aCtxImpl.GetSsId()) = aSSID;   
       
   292     (aCtxImpl.EncryptionStatus()) = aEncryptionStatus;           
       
   293     (aCtxImpl.AuthenticationAlgorithmNumber()) = aAuthAlgorithmNbr;
       
   294     // set the BSSID field
       
   295     (aCtxImpl.GetAuthenticationFrame()).iHeader.iBSSID 
       
   296         = (aCtxImpl.GetBssId());
       
   297     (aCtxImpl.GetHtAuthenticationFrame()).iHeader.iBSSID 
       
   298         = (aCtxImpl.GetBssId());
       
   299     // set the DA field
       
   300     (aCtxImpl.GetAuthenticationFrame()).iHeader.iDA 
       
   301         = (aCtxImpl.GetBssId()); 
       
   302     (aCtxImpl.GetHtAuthenticationFrame()).iHeader.iDA 
       
   303         = (aCtxImpl.GetBssId()); 
       
   304     // set the SA field
       
   305     (aCtxImpl.GetAuthenticationFrame()).iHeader.iSA 
       
   306         = aCtxImpl.iWlanMib.dot11StationId;
       
   307     (aCtxImpl.GetHtAuthenticationFrame()).iHeader.iSA 
       
   308         = aCtxImpl.iWlanMib.dot11StationId;
       
   309     aCtxImpl.NetworkOperationMode( 
       
   310         aIsInfra ? WHA::EBSS : WHA::EIBSS );
       
   311 
       
   312     // store Tx IE data for later access
       
   313     // pointers supplied are valid to the point the
       
   314     // corresponding completion method is called
       
   315     aCtxImpl.IeData( aIeData );
       
   316     aCtxImpl.IeDataLength( aIeDataLength );
       
   317 
       
   318 
       
   319     // check do we meet the requirements for the network
       
   320     // and construct necessary objects for establishing the connection
       
   321     if ( InitNetworkConnect( 
       
   322             aCtxImpl, 
       
   323             aScanResponseFrameBodyLength, 
       
   324             aScanResponseFrameBody ) )
       
   325         {
       
   326         // continue
       
   327 
       
   328         // make WHA types
       
   329         WHA::SSSID ssid;
       
   330         ssid.iSSIDLength = aSSID.ssidLength;
       
   331         os_memcpy( ssid.iSSID, aSSID.ssid, ssid.iSSIDLength );
       
   332 
       
   333         // infrastructure or IBSS mode
       
   334         if ( aIsInfra )
       
   335             {
       
   336             OsTracePrint( KUmacDetails, (TUint8*)
       
   337                 ("UMAC: WlanDot11Idle::Connect: infra"));
       
   338                 
       
   339             Fsm( aCtxImpl, ECONNECT );            
       
   340             }
       
   341         else    // --- IBSS mode ---
       
   342             {
       
   343             OsTracePrint( KUmacDetails, (TUint8*)
       
   344                 ("UMAC: WlanDot11Idle::Connect: IBSS"));
       
   345                 
       
   346             Fsm( aCtxImpl, ECONNECTIBSS );
       
   347             }
       
   348         }
       
   349     else    // --- InitNetworkConnect failure ---
       
   350         {
       
   351         // abort
       
   352         ret = EFalse;
       
   353         OnOidComplete( aCtxImpl, KErrGeneral );
       
   354         }
       
   355 
       
   356     return ret;    
       
   357     }
       
   358 
       
   359 // ---------------------------------------------------------------------------
       
   360 // 
       
   361 // ---------------------------------------------------------------------------
       
   362 //
       
   363 TBool WlanDot11Idle::Disconnect( 
       
   364     WlanContextImpl& aCtxImpl )
       
   365     {
       
   366     Fsm( aCtxImpl, EDISCONNECT );
       
   367         
       
   368     // global state transition will occur
       
   369     return ETrue;
       
   370     }
       
   371 
       
   372 // ---------------------------------------------------------------------------
       
   373 // 
       
   374 // ---------------------------------------------------------------------------
       
   375 //
       
   376 TBool WlanDot11Idle::RealScan(
       
   377     WlanContextImpl& aCtxImpl,
       
   378     TScanMode aMode,                    
       
   379     const TSSID& aSSID,                 
       
   380     TUint32 aScanRate,                    
       
   381     SChannels& aChannels,
       
   382     TUint32 aMinChannelTime,            
       
   383     TUint32 aMaxChannelTime,
       
   384     TBool aSplitScan )                 
       
   385     {
       
   386     // scanning mode requested
       
   387     // set parameters
       
   388     // NOTE: OID command parameters are guaranteed to be valid
       
   389     // to the point a correcponding completion method is called
       
   390 
       
   391     aCtxImpl.iStates.iIdleScanningMode.Set( 
       
   392         aMode, aSSID, aScanRate, aChannels, 
       
   393         aMinChannelTime, aMaxChannelTime, aSplitScan );
       
   394 
       
   395     Fsm( aCtxImpl, ESCAN );
       
   396 
       
   397     return ETrue; // global statemachine transition will occur 
       
   398     }
       
   399 
       
   400 // ---------------------------------------------------------------------------
       
   401 // 
       
   402 // ---------------------------------------------------------------------------
       
   403 //
       
   404 void WlanDot11Idle::FinitSystem( 
       
   405     WlanContextImpl& aCtxImpl )
       
   406     {
       
   407     Fsm( aCtxImpl, ERELEASE );
       
   408     }
       
   409 
       
   410 // ---------------------------------------------------------------------------
       
   411 // 
       
   412 // ---------------------------------------------------------------------------
       
   413 //
       
   414 TBool WlanDot11Idle::AddBroadcastWepKey(
       
   415     WlanContextImpl& aCtxImpl,
       
   416     TUint32 aKeyIndex,             
       
   417     TBool aUseAsDefaulKey,                
       
   418     TUint32 aKeyLength,                      
       
   419     const TUint8 aKey[KMaxWEPKeyLength],
       
   420     const TMacAddress& aMac )
       
   421     {
       
   422     return OnAddBroadcastWepKey( aCtxImpl, aKeyIndex, aUseAsDefaulKey, 
       
   423         EFalse, // do not set as PTK
       
   424         aKeyLength, aKey, aMac );
       
   425     }
       
   426 
       
   427 // ---------------------------------------------------------------------------
       
   428 // 
       
   429 // ---------------------------------------------------------------------------
       
   430 //
       
   431 TBool WlanDot11Idle::AddUnicastWepKey(
       
   432     WlanContextImpl& aCtxImpl,
       
   433     const TMacAddress& aMacAddr,
       
   434     TUint32 aKeyLength,                      
       
   435     const TUint8 aKey[KMaxWEPKeyLength])
       
   436     {
       
   437     // allocate memory for the key structure
       
   438     WHA::SWepPairwiseKey* key = static_cast<WHA::SWepPairwiseKey*>
       
   439         (os_alloc( WHA::SWepPairwiseKey::KHeaderSize + aKeyLength )); 
       
   440 
       
   441     if ( !key )
       
   442         {
       
   443         // allocation failure
       
   444         Fsm( aCtxImpl, EABORT );
       
   445         return EFalse;
       
   446         }
       
   447 
       
   448     os_memcpy( 
       
   449         &(key->iMacAddr), 
       
   450         aMacAddr.iMacAddress,
       
   451         sizeof(key->iMacAddr) );
       
   452     key->iKeyLengthInBytes = static_cast<TUint8>(aKeyLength);
       
   453     os_memcpy( key->iKey, aKey, key->iKeyLengthInBytes );
       
   454     
       
   455     WlanWsaAddKey& wsa_cmd = aCtxImpl.WsaAddKey();    
       
   456     wsa_cmd.Set( aCtxImpl, 
       
   457         WHA::EWepPairWiseKey,
       
   458         key,
       
   459         WlanWsaKeyIndexMapper::Extract( WHA::EWepPairWiseKey ) );
       
   460     
       
   461     // change global state: entry procedure triggers action
       
   462     ChangeState( aCtxImpl, 
       
   463         *this,              // prev state
       
   464         wsa_cmd,            // next state
       
   465         // the ACT
       
   466         KCompleteManagementRequest
       
   467         );                           
       
   468     
       
   469     os_free( key ); // allways remember to release the memory
       
   470 
       
   471     // signal caller that a state transition occurred
       
   472     return ETrue;
       
   473     }
       
   474 
       
   475 // ---------------------------------------------------------------------------
       
   476 // 
       
   477 // ---------------------------------------------------------------------------
       
   478 //
       
   479 void WlanDot11Idle::ChangeInternalState( 
       
   480     WlanContextImpl& aCtxImpl, 
       
   481     TState aNewState )
       
   482     {
       
   483     iState = aNewState;
       
   484     Fsm( aCtxImpl, ESTATEENTRY );
       
   485     }
       
   486 
       
   487 // ---------------------------------------------------------------------------
       
   488 // 
       
   489 // ---------------------------------------------------------------------------
       
   490 //
       
   491 void WlanDot11Idle::Fsm( 
       
   492     WlanContextImpl& aCtxImpl, 
       
   493     TEvent aEvent )
       
   494     {
       
   495     OsTracePrint( KUmacDetails, 
       
   496         (TUint8*)("UMAC * dot11-idle * FSM EVENT") );
       
   497 #ifndef NDEBUG
       
   498     OsTracePrint( KUmacDetails, (TUint8*)("event:"));
       
   499     OsTracePrint( KUmacDetails, iEventName[aEvent] );
       
   500     OsTracePrint( KUmacDetails, (TUint8*)("state:"));
       
   501     OsTracePrint( KUmacDetails, iStateName[iState] );
       
   502 #endif
       
   503 
       
   504     switch ( aEvent )
       
   505         {
       
   506         case ESTATEENTRY:
       
   507             OnStateEntryEvent( aCtxImpl );
       
   508             break;
       
   509         case ETXCOMPLETE:
       
   510             OnTxCompleteEvent( aCtxImpl );
       
   511             break;
       
   512         case ESCAN:
       
   513             OnScanEvent( aCtxImpl );
       
   514             break;
       
   515         case ECONNECT:
       
   516             OnConnectEvent( aCtxImpl );
       
   517             break;
       
   518         case ECONNECTIBSS:
       
   519             OnConnectIbssEvent( aCtxImpl );
       
   520             break;
       
   521         case EDISCONNECT:
       
   522             OnDisconnectEvent( aCtxImpl );
       
   523             break;
       
   524         case ERELEASE:
       
   525             OnReleaseEvent( aCtxImpl );
       
   526             break;
       
   527         case EABORT:
       
   528             OnAbortEvent( aCtxImpl );
       
   529             break;
       
   530         default:
       
   531             // catch internal FSM programming error
       
   532 #ifndef NDEBUG
       
   533             OsTracePrint( KErrorLevel, (TUint8*)("event:"));
       
   534             OsTracePrint( KErrorLevel, iEventName[aEvent] );                
       
   535 #endif
       
   536             OsAssert( (TUint8*)("* UMAC * panic"), 
       
   537                 (TUint8*)(WLAN_FILE), __LINE__ );
       
   538             break;
       
   539         }
       
   540     }
       
   541 
       
   542 // ---------------------------------------------------------------------------
       
   543 // 
       
   544 // ---------------------------------------------------------------------------
       
   545 //
       
   546 void WlanDot11Idle::OnStateEntryEvent( 
       
   547     WlanContextImpl& aCtxImpl )
       
   548     {
       
   549     switch ( iState )
       
   550         {
       
   551         case EINIT:
       
   552             if ( aCtxImpl.Reassociate() )
       
   553                 {
       
   554                 // a roaming case
       
   555                 ChangeInternalState( aCtxImpl, EFINIT );
       
   556                 }
       
   557             else
       
   558                 {
       
   559                 // not a roaming case
       
   560                 ChangeInternalState( aCtxImpl, EWRITEMIB );
       
   561                 }
       
   562             break;
       
   563         case EWRITEMIB:
       
   564             WriteSleepModeMib( aCtxImpl );
       
   565             break;
       
   566         case EFINIT:
       
   567             // fsm execution complete 
       
   568 
       
   569             // execute OID completion if necessary
       
   570             CompleteOid( aCtxImpl );
       
   571             // indicate scan completion if necessary
       
   572             IndicateScanCompletion( aCtxImpl );
       
   573             break;
       
   574         default:
       
   575             // catch internal FSM programming error
       
   576 #ifndef NDEBUG
       
   577             OsTracePrint( KErrorLevel, (TUint8*)("state:"));
       
   578             OsTracePrint( KErrorLevel, iStateName[iState] );
       
   579 #endif
       
   580             OsAssert( (TUint8*)("* UMAC * panic"), 
       
   581                 (TUint8*)(WLAN_FILE), __LINE__ );
       
   582             break;
       
   583         }
       
   584     }
       
   585 
       
   586 // ---------------------------------------------------------------------------
       
   587 // 
       
   588 // ---------------------------------------------------------------------------
       
   589 //
       
   590 void WlanDot11Idle::OnTxCompleteEvent( 
       
   591     WlanContextImpl& aCtxImpl )
       
   592     {
       
   593     switch ( iState )
       
   594         {
       
   595         case EWRITEMIB:
       
   596             ChangeInternalState( aCtxImpl, EFINIT );
       
   597             break;
       
   598         case EFINIT:
       
   599             // default handler has issued a WHA command and we 
       
   600             // have come back to this object
       
   601             // we have absolutely nothing to do here
       
   602             // expect mayby complete something
       
   603             CompleteOid( aCtxImpl );
       
   604             break;
       
   605         default:
       
   606             // catch internal FSM programming error
       
   607 #ifndef NDEBUG
       
   608             OsTracePrint( KErrorLevel, (TUint8*)("state:"));
       
   609             OsTracePrint( KErrorLevel, iStateName[iState] );
       
   610 #endif
       
   611             OsAssert( (TUint8*)("* UMAC * panic"), 
       
   612                 (TUint8*)(WLAN_FILE), __LINE__ );
       
   613             break;
       
   614         }
       
   615     }
       
   616 
       
   617 // ---------------------------------------------------------
       
   618 // simulate macnotresponding error
       
   619 // ---------------------------------------------------------
       
   620 //
       
   621 void WlanDot11Idle::OnAbortEvent( 
       
   622     WlanContextImpl& aCtxImpl )
       
   623     {
       
   624     OsTracePrint( KWarningLevel, (TUint8*)("UMAC * dot11-idle * abort") );
       
   625 
       
   626     DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
   627     }
       
   628 
       
   629 
       
   630 // ---------------------------------------------------------------------------
       
   631 // 
       
   632 // ---------------------------------------------------------------------------
       
   633 //
       
   634 void WlanDot11Idle::OnScanEvent( 
       
   635     WlanContextImpl& aCtxImpl )
       
   636     {
       
   637     // change global state: entry procedure triggers action
       
   638     ChangeState( aCtxImpl, 
       
   639         *this,                                  // prev state
       
   640         aCtxImpl.iStates.iIdleScanningMode      // next state
       
   641         );      
       
   642     }
       
   643 
       
   644 // ---------------------------------------------------------------------------
       
   645 // 
       
   646 // ---------------------------------------------------------------------------
       
   647 //
       
   648 void WlanDot11Idle::OnConnectEvent( 
       
   649     WlanContextImpl& aCtxImpl )
       
   650     {
       
   651     // change global state: entry procedure triggers action
       
   652     ChangeState( aCtxImpl, 
       
   653         *this,                               // prev state
       
   654         aCtxImpl.iStates.iPrepareForBssMode  // next state
       
   655         );
       
   656     }
       
   657 
       
   658 // ---------------------------------------------------------------------------
       
   659 // 
       
   660 // ---------------------------------------------------------------------------
       
   661 //
       
   662 void WlanDot11Idle::OnConnectIbssEvent(
       
   663     WlanContextImpl& aCtxImpl )
       
   664     {
       
   665     ChangeState( aCtxImpl, 
       
   666         *this,                                  // prev state
       
   667         aCtxImpl.iStates.iPrepareForIbssMode    // next state
       
   668         );            
       
   669     }
       
   670 
       
   671 // ---------------------------------------------------------------------------
       
   672 // 
       
   673 // ---------------------------------------------------------------------------
       
   674 //
       
   675 void WlanDot11Idle::OnDisconnectEvent( 
       
   676     WlanContextImpl& aCtxImpl )
       
   677     {
       
   678     // set completion code for the oid 
       
   679     Set( KErrNone );
       
   680 
       
   681     // change global state: entry procedure triggers action
       
   682     ChangeState( aCtxImpl, 
       
   683         *this,                              // prev state
       
   684         aCtxImpl.iStates.iSoftResetState    // next state
       
   685         );      
       
   686     }
       
   687 
       
   688 // ---------------------------------------------------------------------------
       
   689 // 
       
   690 // ---------------------------------------------------------------------------
       
   691 //
       
   692 void WlanDot11Idle::OnReleaseEvent( 
       
   693     WlanContextImpl& aCtxImpl )
       
   694     {
       
   695     // register oid completion by setting completion value
       
   696     Set( KErrNone );
       
   697     // and execute transition
       
   698     ChangeState( aCtxImpl, 
       
   699         *this,                      // prev state
       
   700         aCtxImpl.WlanWhaRelease()   // next state
       
   701         );      
       
   702     }
       
   703 
       
   704 // ---------------------------------------------------------------------------
       
   705 // 
       
   706 // ---------------------------------------------------------------------------
       
   707 //
       
   708 void WlanDot11Idle::WriteSleepModeMib( 
       
   709     WlanContextImpl& aCtxImpl )
       
   710     {
       
   711     WHA::SsleepMode* mib 
       
   712         = static_cast<WHA::SsleepMode*>(os_alloc( sizeof( WHA::SsleepMode ) )); 
       
   713 
       
   714     if ( !mib )
       
   715         {
       
   716         // allocation failure
       
   717         Fsm( aCtxImpl, EABORT );
       
   718         return;
       
   719         }
       
   720 
       
   721     // allocation success continue
       
   722     mib->iMode = WHA::KLowPowerMode;
       
   723     
       
   724     WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
       
   725     wha_cmd.Set( 
       
   726         aCtxImpl, WHA::KMibSleepMode, sizeof(*mib), mib );
       
   727 
       
   728     // change global state: entry procedure triggers action
       
   729     ChangeState( aCtxImpl, 
       
   730         *this,              // prev state
       
   731         wha_cmd             // next state
       
   732         );           
       
   733 
       
   734     // as the parameters have been supplied we can now deallocate
       
   735     os_free( mib );       
       
   736     }
       
   737 
       
   738 // ---------------------------------------------------------------------------
       
   739 // 
       
   740 // ---------------------------------------------------------------------------
       
   741 //
       
   742 void WlanDot11Idle::GenerateRandomBssIDForIbss( 
       
   743     WlanContextImpl& aCtxImpl ) const
       
   744     {
       
   745     // generate random BSSID for IBSS
       
   746     TMacAddress mac;
       
   747     TUint16* ptr = reinterpret_cast<TUint16*>(mac.iMacAddress);
       
   748     const TUint16* const ptr_end 
       
   749         = ptr + (sizeof(TMacAddress) / sizeof(TUint16));
       
   750 
       
   751     while ( ptr != ptr_end )
       
   752         {
       
   753         *ptr = aCtxImpl.Random();
       
   754         ++ptr;
       
   755         }
       
   756 
       
   757     // the Universal/Local bit must be set ( 2nd bit of octet 0 )
       
   758     // the Induvidual/Group bit must be cleared ( 1st bit of octet 0 )
       
   759     GroupBit( mac, EFalse );    // clear
       
   760     LocalBit( mac );             // set
       
   761 
       
   762     // store the BSSID
       
   763     aCtxImpl.GetBssId() = mac;
       
   764     }
       
   765 
       
   766 // ---------------------------------------------------------------------------
       
   767 // 
       
   768 // ---------------------------------------------------------------------------
       
   769 //
       
   770 void WlanDot11Idle::CompleteOid( 
       
   771     WlanContextImpl& aCtxImpl )
       
   772     {
       
   773     if ( iEventMask & KCompleteUponEntry )
       
   774         {
       
   775         iEventMask &= ~KCompleteUponEntry;
       
   776 
       
   777         OnOidComplete( aCtxImpl, iCompletionCode );
       
   778         }
       
   779     }
       
   780 
       
   781 // ---------------------------------------------------------------------------
       
   782 // 
       
   783 // ---------------------------------------------------------------------------
       
   784 //
       
   785 void WlanDot11Idle::IndicateScanCompletion( 
       
   786     WlanContextImpl& aCtxImpl )
       
   787     {
       
   788     if ( iEventMask & KIndicateScanCompletionUponEntry )
       
   789         {
       
   790         iEventMask &= ~KIndicateScanCompletionUponEntry;
       
   791 
       
   792         OsTracePrint( KScan, (TUint8*)
       
   793             ("UMAC: WlanDot11Idle::IndicateScanCompletion: Send scan complete indication"));
       
   794     
       
   795         OnInDicationEvent( aCtxImpl, EScanCompleted );
       
   796         }
       
   797     }