wlan_bearer/wlanldd/wlan_common/umac_common/src/UmacDot11ReassociationPending.cpp
changeset 0 c40eb8fe8501
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 UmacDot11ReassociationPending class
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 37 %
       
    20 */
       
    21 
       
    22 #include "config.h"
       
    23 #include "UmacDot11ReassociationPending.h"
       
    24 #include "UmacContextImpl.h"
       
    25 #include "umacelementlocator.h"
       
    26 #include "umacwhaconfigureac.h"
       
    27 #include "802dot11DefaultValues.h"
       
    28 
       
    29 #ifndef NDEBUG
       
    30 const TInt8 WlanDot11ReassociationPending::iName[] = "dot11-reassociationpending";
       
    31 
       
    32 const TUint8 WlanDot11ReassociationPending::iStateName
       
    33     [ESTATEMAX][KMaxStateStringLength] = 
       
    34     {
       
    35         {"EINIT"},
       
    36         {"ETXREASSOCIATIONFRAME"},
       
    37         {"EWAIT4REASSOCIATIONRESPONSE"},
       
    38         {"ECONFIGUREAC"}, 
       
    39         {"EWAIT4PUSHPACKET"},
       
    40         {"ECONTINUEDOT11TRAVERSE"} 
       
    41     };
       
    42 
       
    43 const TUint8 WlanDot11ReassociationPending::iEventName
       
    44     [EEVENTMAX][KMaxEventStringLength] = 
       
    45     {
       
    46         {"ESTATEENTRY"}, 
       
    47         {"ETXREASSOCFRAMEXFER"}, 
       
    48         {"ERXREASSOCRESPONSE"}, 
       
    49         {"ETXCOMPLETE"},
       
    50         {"ETIMEOUT"},
       
    51         {"ETX_SCHEDULER_FULL"},
       
    52         {"EPUSHPACKET"}
       
    53     };
       
    54 #endif
       
    55 
       
    56 
       
    57 // ================= MEMBER FUNCTIONS =======================
       
    58 
       
    59 // -----------------------------------------------------------------------------
       
    60 // 
       
    61 // -----------------------------------------------------------------------------
       
    62 //
       
    63 #ifndef NDEBUG 
       
    64 const TInt8* WlanDot11ReassociationPending::GetStateName( 
       
    65     TUint8& aLength ) const
       
    66     {
       
    67     aLength = sizeof( iName );
       
    68     return iName;
       
    69     }
       
    70 #endif
       
    71 
       
    72 // -----------------------------------------------------------------------------
       
    73 // 
       
    74 // -----------------------------------------------------------------------------
       
    75 //
       
    76 void WlanDot11ReassociationPending::Entry( 
       
    77     WlanContextImpl& aCtxImpl )
       
    78     {
       
    79     OsTracePrint( KUmacProtocolState | KUmacAssoc, 
       
    80         (TUint8*)("UMAC * execute dot11 assoiate"));
       
    81 
       
    82     if ( aCtxImpl.WsaCmdActive() )
       
    83         {
       
    84         // sanity checking code
       
    85         OsAssert( (TUint8*)("UMAC: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
    86         }
       
    87 
       
    88     // no need to do event dispatching as this
       
    89     // thing is triggered by the user and
       
    90     // is executed synchronously as we only do OID completion
       
    91     // at the end of reassociation process
       
    92 
       
    93     if ( iState == EINIT )
       
    94         {
       
    95         // this is the start of the the FSM actions
       
    96         Fsm( aCtxImpl, ESTATEENTRY );
       
    97         }
       
    98     else
       
    99         {
       
   100         // this is NOT the start of the the FSM actions
       
   101         // note that we send the ETXCOMPLETE event as the states
       
   102         // that wait for it are the only ones that can be interrupted
       
   103         // as they are asynchronous operations by nature
       
   104         // and wait for corresponding WHA completion method
       
   105         Fsm( aCtxImpl, ETXCOMPLETE );        
       
   106         }
       
   107     }
       
   108 
       
   109 // -----------------------------------------------------------------------------
       
   110 // 
       
   111 // -----------------------------------------------------------------------------
       
   112 //
       
   113 void WlanDot11ReassociationPending::Exit( 
       
   114     WlanContextImpl& /*aCtxImpl*/ )
       
   115     {
       
   116     OsTracePrint( 
       
   117         KUmacProtocolState, 
       
   118         (TUint8*)("UMAC: WlanDot11ReassociationPending::Exit"));
       
   119 
       
   120     // we are departing this dot11state to another dot11state
       
   121     // we simple reset our local FSM for the next time...
       
   122     iState = EINIT;
       
   123     }
       
   124 
       
   125 // -----------------------------------------------------------------------------
       
   126 // 
       
   127 // -----------------------------------------------------------------------------
       
   128 //
       
   129 void WlanDot11ReassociationPending::OnPacketTransferComplete( 
       
   130     WlanContextImpl& aCtxImpl, 
       
   131     TUint32 aPacketId,
       
   132     TDataBuffer* aMetaHeader )
       
   133     {
       
   134     OsTracePrint( KUmacAssoc, (TUint8*)
       
   135         ("UMAC: WlanDot11ReassociationPending::OnPacketTransferComplete"));
       
   136         
       
   137     if ( aPacketId == E802Dot11FrameTypeData )
       
   138         {
       
   139         OnTxProtocolStackDataComplete( aCtxImpl, aMetaHeader );
       
   140         }
       
   141     else if ( aPacketId == E802Dot11FrameTypeDataEapol || 
       
   142               aPacketId == E802Dot11FrameTypeManagementAction ||
       
   143               aPacketId == E802Dot11FrameTypeTestFrame )
       
   144         {
       
   145         OnMgmtPathWriteComplete( aCtxImpl );
       
   146         }
       
   147     else
       
   148         {
       
   149         // this frame Tx request didn't come from above us (i.e. neither 
       
   150         // through the user data nor the management data API) but is
       
   151         // related to a frame Tx we have done internally. So we need to mark
       
   152         // the internal Tx buffer free again
       
   153         aCtxImpl.MarkInternalTxBufFree();
       
   154         }
       
   155 
       
   156     if ( aPacketId == E802Dot11FrameTypeReassociationReq )
       
   157         {
       
   158         // reassociation tx message has been xferred to the WLAN device
       
   159         
       
   160         Fsm( aCtxImpl, ETXREASSOCFRAMEXFER );
       
   161         }
       
   162     }
       
   163 
       
   164 // -----------------------------------------------------------------------------
       
   165 // 
       
   166 // -----------------------------------------------------------------------------
       
   167 //
       
   168 void WlanDot11ReassociationPending::ReceivePacket( 
       
   169     WlanContextImpl& aCtxImpl,
       
   170     WHA::TStatus aStatus,
       
   171     const void* aFrame,
       
   172     TUint16 aLength,
       
   173     WHA::TRate /*aRate*/,
       
   174     WHA::TRcpi aRcpi,
       
   175     WHA::TChannelNumber /*aChannel*/,
       
   176     TUint8* aBuffer,
       
   177     TUint32 aFlags )
       
   178     {
       
   179     OsTracePrint( KUmacDetails, (TUint8*)
       
   180         ("UMAC: WlanDot11ReassociationPending::ReceivePacket()"));
       
   181 
       
   182     if ( aStatus == WHA::KSuccess )
       
   183         {
       
   184         // receive success
       
   185         const Sdot11MacHeader* dot11_hdr( 
       
   186             static_cast<const Sdot11MacHeader*>(aFrame) );
       
   187 
       
   188         // we accept only frames with ToDS bit cleared
       
   189         if ( dot11_hdr->IsToDsBitSet() )
       
   190             {
       
   191             OsTracePrint( KWarningLevel | KUmacAssoc, 
       
   192                 (TUint8*)("UMAC: associating to BSS:") );
       
   193             OsTracePrint( KWarningLevel | KUmacAssoc, 
       
   194             (TUint8*)("UMAC: rx-frame: ToDs bit set, discard frame") );
       
   195 
       
   196             // release the Rx buffer & abort
       
   197             aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
   198             return;
       
   199             }
       
   200 
       
   201         const TBool class3_frame( IsClass3Frame( 
       
   202             dot11_hdr->iFrameControl.iType ) );
       
   203         const TBool unicast_addr( !IsGroupBitSet( dot11_hdr->iAddress1 ) );
       
   204 
       
   205         if ( class3_frame && unicast_addr )
       
   206             {
       
   207             OsTracePrint( KWarningLevel | KUmacAssoc, 
       
   208                 (TUint8*)("UMAC: re-associating to BSS:") );
       
   209             OsTracePrint( KWarningLevel | KUmacAssoc, 
       
   210                 (TUint8*)("rx class3 frame with unicast DA address") );
       
   211 
       
   212             // class 3 frame rx and unicast address in address1 field
       
   213 
       
   214             // That's not the frame we are expecting so release the Rx buffer
       
   215             aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
   216             
       
   217             if ( !Associated() )
       
   218                 {
       
   219                 // we do not have a valid association with the 
       
   220                 // BSS where the frame came from
       
   221                 OsTracePrint( KWarningLevel | KUmacAssoc, 
       
   222                     (TUint8*)("UMAC: TxDisassociate") );
       
   223                 
       
   224                 // set the BSSID of the existing network; and the DA
       
   225                 if ( aCtxImpl.HtSupportedByNw() )
       
   226                     {
       
   227                     (aCtxImpl.GetHtDisassociationFrame()).iHeader.iBSSID 
       
   228                         = aCtxImpl.GetBssId();
       
   229                     (aCtxImpl.GetHtDisassociationFrame()).iHeader.iDA 
       
   230                         = aCtxImpl.GetBssId();                    
       
   231                     }
       
   232                 else
       
   233                     {
       
   234                     (aCtxImpl.GetDisassociationFrame()).iHeader.iBSSID 
       
   235                         = aCtxImpl.GetBssId();
       
   236                     (aCtxImpl.GetDisassociationFrame()).iHeader.iDA 
       
   237                         = aCtxImpl.GetBssId();
       
   238                     }
       
   239                 if ( !TxDisassociate( 
       
   240                         aCtxImpl, 
       
   241                         E802Dot11ReasonClass3FrameWhenNotAssoc ) )
       
   242                     {
       
   243                     // frame was not sent because either packet scheduler was 
       
   244                     // full or because we didn't get a Tx buffer. In any case
       
   245                     // we won't try to send it again. 
       
   246                     }                    
       
   247                 }
       
   248             else
       
   249                 {
       
   250                 // this section is left intentionally empty
       
   251                 }
       
   252             }
       
   253         else
       
   254             {
       
   255             // default handler
       
   256             OnReceiveFrameSuccess( 
       
   257                 aCtxImpl, 
       
   258                 aFrame, 
       
   259                 aLength, 
       
   260                 aRcpi, 
       
   261                 aFlags, 
       
   262                 aBuffer );
       
   263             }
       
   264         }
       
   265     else    // --- aStatus == WHA::KSuccess ---
       
   266         {
       
   267         // receive failed, so discard and release the Rx buffer
       
   268         aCtxImpl.iUmac.MarkRxBufFree( aBuffer );        
       
   269         }
       
   270     }
       
   271 
       
   272 // -----------------------------------------------------------------------------
       
   273 //
       
   274 // -----------------------------------------------------------------------------
       
   275 //
       
   276 void WlanDot11ReassociationPending::OnReceiveFrameSuccess(
       
   277     WlanContextImpl& aCtxImpl,
       
   278     const void* aFrame,
       
   279     TUint16 aLength,
       
   280     WHA::TRcpi aRcpi,
       
   281     TUint32 aFlags,
       
   282     TUint8* aBuffer )
       
   283     {    
       
   284     // receive success
       
   285     // parse frame in order to determine if it is what we are expecting
       
   286     const SManagementFrameHeader* frame_hdr( 
       
   287         static_cast<const SManagementFrameHeader*>(aFrame) );
       
   288 
       
   289     TBool type_match( EFalse );
       
   290 
       
   291     if ( // is this reassociation response frame
       
   292          IsRequestedFrameType(
       
   293             frame_hdr->iFrameControl.iType,
       
   294             E802Dot11FrameTypeReassociationResp, type_match )
       
   295          // AND our MAC address is DA
       
   296          && ( frame_hdr->iDA == aCtxImpl.iWlanMib.dot11StationId )
       
   297          // AND we haven't received the reassoc response yet
       
   298          && ( !( iFlags & KReassocReceived ) ) )
       
   299         {
       
   300         T802Dot11ManagementStatusCode status(
       
   301             IsRxReassociationSuccess( aCtxImpl, aFrame, aFlags ) );
       
   302 
       
   303         if ( status == E802Dot11StatusSuccess )
       
   304             {
       
   305             // --- begin WMM
       
   306             if ( aCtxImpl.QosEnabled() )
       
   307                 {
       
   308                 WlanElementLocator elementLocator(
       
   309                     reinterpret_cast<const TUint8*>( aFrame ) +
       
   310                     sizeof( SManagementFrameHeader ) +
       
   311                     sizeof( SReassociationResponseFixedFields ),
       
   312                     aLength -
       
   313                     sizeof( SManagementFrameHeader ) +
       
   314                     sizeof( SReassociationResponseFixedFields ) );
       
   315 
       
   316                 TUint8 length( 0 );
       
   317                 const TUint8* data( NULL );
       
   318 
       
   319                 // is WMM Parameter Element present
       
   320                 if ( elementLocator.InformationElement(
       
   321                     E802Dot11VendorSpecificIE,
       
   322                     KWmmElemOui,
       
   323                     KWmmElemOuiType,
       
   324                     KWmmParamElemOuiSubtype,
       
   325                     length,
       
   326                     &data )
       
   327                     == WlanElementLocator::EWlanLocateOk )
       
   328                     {
       
   329                     // WMM Parameter Element found
       
   330                     OsTracePrint( KUmacAssoc, (TUint8*)
       
   331                         ("UMAC: WlanDot11ReassociationPending::ReceivePacket(): WMM param set cnt: %d"),
       
   332                         (reinterpret_cast<const SWmmParamElemData*>(data))->ParameterSetCount() );
       
   333 
       
   334                     if ( (reinterpret_cast<const SWmmParamElemData*>
       
   335                         (data))->ParameterSetCount() !=
       
   336                         aCtxImpl.WmmParameterSetCount() )
       
   337                         {
       
   338                         // AC parameters have changed => parse again
       
   339                         ParseAcParameters( aCtxImpl,
       
   340                             reinterpret_cast<const SWmmParamElemData&>(*data ) );
       
   341                         // in this case we need to re-issue configure AC wha cmd
       
   342                         // so make a note of that
       
   343                         iFlags |= KConfigureAc;
       
   344                         }
       
   345                     }
       
   346                 else
       
   347                     {
       
   348                     // protocol error from AP; just try to continue with
       
   349                     // current WMM parameters
       
   350                     OsTracePrint( KWarningLevel | KUmacAssoc, (TUint8*)
       
   351                         ("UMAC: WlanDot11AssociationPending::ReceivePacket(): PROTOCOL ERROR from AP side") );
       
   352                     }
       
   353                 }
       
   354             // --- end WMM
       
   355             }
       
   356         else
       
   357             {
       
   358             // reassociation failed
       
   359             OsTracePrint( KUmacAssoc | KWarningLevel, (TUint8*)
       
   360                 ("UMAC: WlanDot11ReassociationPending::ReceivePacket(): reassociation denied, status %d"),
       
   361                 status );
       
   362 
       
   363             // in this case we will go back to idle state
       
   364             // where the connect oid will be completed.
       
   365             // So set the completion code value to be returned to user mode
       
   366             aCtxImpl.iStates.iIdleState.Set( status );
       
   367             }
       
   368 
       
   369         // forward the re-association response frame to Wlan Mgmt client
       
   370         if ( XferDot11FrameToMgmtClient(
       
   371                 aCtxImpl,
       
   372                 aFrame,
       
   373                 aLength,
       
   374                 aRcpi,
       
   375                 aBuffer ) )
       
   376             {
       
   377             // forwarding succeeded. Now we can say that we have received
       
   378             // the Reassoc response successfully
       
   379 
       
   380             iFlags |= KReassocReceived;
       
   381             aCtxImpl.CancelTimer();
       
   382 
       
   383             if ( status == E802Dot11StatusSuccess )
       
   384                 {
       
   385                 iFlags |= KReassocSuccess;
       
   386 
       
   387                 OsTracePrint( KUmacAssoc,
       
   388                     (TUint8*)("UMAC: reassociation success") );
       
   389                 }
       
   390 
       
   391             Fsm( aCtxImpl, ERXREASSOCRESPONSE );
       
   392             }
       
   393         else
       
   394             {
       
   395             // forwarding the frame to WLAN Mgmt client failed, which
       
   396             // won't happen in this situation under the normal circumstances.
       
   397             // Anyhow, it has happened now, so we have no other choice than to
       
   398             // discard the frame. The Rx buffer has already been
       
   399             // released. So no action here
       
   400             }
       
   401         }
       
   402     else
       
   403         {
       
   404         // not a valid frame in this situation; we just silently discard it
       
   405         OsTracePrint( KUmacAssoc | KUmacDetails, (TUint8*)
       
   406             ("UMAC: WlanDot11ReassociationPending::OnReceiveFrameSuccess: "
       
   407              "not relevant frame; ignore"));
       
   408 
       
   409         // release the Rx buffer
       
   410         aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
   411         }
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // 
       
   416 // -----------------------------------------------------------------------------
       
   417 //
       
   418 TBool WlanDot11ReassociationPending::OnTimeout( 
       
   419     WlanContextImpl& aCtxImpl )
       
   420     {
       
   421     TBool stateChange ( ETrue );
       
   422     
       
   423     switch ( iState )
       
   424         {
       
   425         case EWAIT4REASSOCIATIONRESPONSE:
       
   426             // reassociation timeout
       
   427             
       
   428             OsTracePrint( KWarningLevel | KUmacAssoc, (TUint8*)
       
   429                 ("UMAC: WlanDot11ReassociationPending::OnTimeout: timeout => reassociation failed!") );
       
   430 
       
   431             Fsm( aCtxImpl, ETIMEOUT );
       
   432             
       
   433             // in this case we return ETrue, i.e. signal the caller that a 
       
   434             // state change occurred
       
   435             
       
   436             break;
       
   437         default:
       
   438             // a timeout occurred when we weren't expecting it (yet). This 
       
   439             // means that a timeout callback had already been registered when
       
   440             // we tried to cancel this timer the previous time (regarding
       
   441             // authentication). So this callback is not relevant for 
       
   442             // reassociation and can be ignored. 
       
   443             
       
   444             OsTracePrint( KWarningLevel | KUmacAssoc, (TUint8*)
       
   445                 ("UMAC: WlanDot11ReassociationPending::OnTimeout: irrelevant timeout; ignored") );
       
   446 
       
   447             // Signal the caller that no state change occurred
       
   448             stateChange = EFalse;
       
   449         }
       
   450         
       
   451     return stateChange;
       
   452     }
       
   453 
       
   454 // -----------------------------------------------------------------------------
       
   455 // 
       
   456 // -----------------------------------------------------------------------------
       
   457 //
       
   458 void WlanDot11ReassociationPending::Fsm( 
       
   459     WlanContextImpl& aCtxImpl, 
       
   460     TEvent aEvent )
       
   461     {
       
   462 #ifndef NDEBUG
       
   463     OsTracePrint( 
       
   464         KUmacDetails, 
       
   465         (TUint8*)("UMAC: WlanDot11ReassociationPending::Fsm(): event: "));
       
   466     OsTracePrint( KUmacDetails, iEventName[aEvent] );
       
   467     OsTracePrint( 
       
   468         KUmacDetails, 
       
   469         (TUint8*)("UMAC: WlanDot11ReassociationPending::Fsm(): state: ")); 
       
   470     OsTracePrint( KUmacDetails, iStateName[iState] );
       
   471 #endif
       
   472 
       
   473     switch ( aEvent )
       
   474         {
       
   475         case ESTATEENTRY:
       
   476             OnStateEntryEvent( aCtxImpl );
       
   477             break;
       
   478         case ETXREASSOCFRAMEXFER:
       
   479             OnTxReassocFrameXferEvent( aCtxImpl );
       
   480             break;
       
   481         case ERXREASSOCRESPONSE:
       
   482             OnRxReassocResponseEvent( aCtxImpl );
       
   483             break;
       
   484         case ETXCOMPLETE:
       
   485             OnTxCompleteEvent( aCtxImpl );
       
   486             break;
       
   487         case ETIMEOUT:
       
   488             OnTimeoutEvent( aCtxImpl );
       
   489             break;
       
   490         case ETX_SCHEDULER_FULL:
       
   491             OnTxSchedulerFullEvent( aCtxImpl );
       
   492             break;
       
   493         case EPUSHPACKET:
       
   494             OnPushPacketEvent( aCtxImpl );
       
   495             break;
       
   496         default:
       
   497             OsTracePrint( KErrorLevel, 
       
   498                 (TUint8*)("UMAC: event: %d"), aEvent);        
       
   499             OsAssert( (TUint8*)("UMAC: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
   500             break;
       
   501         }
       
   502     }
       
   503 
       
   504 // -----------------------------------------------------------------------------
       
   505 // 
       
   506 // -----------------------------------------------------------------------------
       
   507 //
       
   508 void WlanDot11ReassociationPending::OnStateEntryEvent( 
       
   509     WlanContextImpl& aCtxImpl )
       
   510     {
       
   511     OsTracePrint( 
       
   512         KUmacDetails, 
       
   513         (TUint8*)("UMAC: WlanDot11ReassociationPending::OnStateEntryEvent()"));
       
   514 
       
   515     switch ( iState )
       
   516         {
       
   517         case EINIT:
       
   518             iFlags = 0;
       
   519             ChangeInternalState( aCtxImpl, ETXREASSOCIATIONFRAME );
       
   520             break;
       
   521         case ETXREASSOCIATIONFRAME:
       
   522             if ( !SendReassociationRequest( aCtxImpl ) )
       
   523                 {
       
   524                 // tx of dot11-reassociate frame failed  
       
   525                 // because packet scheduler was full
       
   526                 // or because we didn't get a Tx buffer
       
   527                 // so we enter to a wait state
       
   528                 Fsm( aCtxImpl, ETX_SCHEDULER_FULL );
       
   529                 }
       
   530             break;
       
   531         case EWAIT4REASSOCIATIONRESPONSE:
       
   532             // start a timer to wait for the response frame
       
   533             StartReassociationResponseTimer( aCtxImpl );
       
   534             break;
       
   535         case ECONFIGUREAC:
       
   536             ConfigureAc( aCtxImpl );
       
   537             break;
       
   538         case ECONTINUEDOT11TRAVERSE:
       
   539             ContinueDot11StateTraversal( aCtxImpl );
       
   540             break;            
       
   541         case EWAIT4PUSHPACKET:
       
   542             // nothing to do here than wait 
       
   543             break;
       
   544         default:
       
   545             // programming error
       
   546 #ifndef NDEBUG
       
   547             OsTracePrint( KErrorLevel, (TUint8*)("UMAC: state:"));
       
   548             OsTracePrint( KErrorLevel, iStateName[iState] );
       
   549 #endif
       
   550             OsAssert( (TUint8*)("UMAC: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
   551             break;
       
   552         }
       
   553     }
       
   554 
       
   555 // -----------------------------------------------------------------------------
       
   556 // 
       
   557 // -----------------------------------------------------------------------------
       
   558 //
       
   559 void WlanDot11ReassociationPending::ContinueDot11StateTraversal( 
       
   560     WlanContextImpl& aCtxImpl )
       
   561     {
       
   562     if ( iFlags & KReassocSuccess )
       
   563         {
       
   564         // reassociation was a success
       
   565         // so we proceed to next state
       
   566         //
       
   567         ChangeState( aCtxImpl,
       
   568             *this,                                      // prev state   
       
   569             aCtxImpl.iStates.iInfrastructureModeInit    // next state
       
   570             );
       
   571         }
       
   572     else
       
   573         {
       
   574         // reassociation was a failure
       
   575         // either due AP denial or timeout.
       
   576         // The reason does not really intrest us here
       
   577         // as the procedure is the same...
       
   578         ChangeState( aCtxImpl, 
       
   579             *this,                                      // prev state
       
   580             aCtxImpl.iStates.iIdleState                 // next state
       
   581             );
       
   582         }
       
   583     }
       
   584 
       
   585 // -----------------------------------------------------------------------------
       
   586 // 
       
   587 // -----------------------------------------------------------------------------
       
   588 //
       
   589 void WlanDot11ReassociationPending::ChangeInternalState( 
       
   590     WlanContextImpl& aCtxImpl, 
       
   591     TState aNewState )
       
   592     {
       
   593 #ifndef NDEBUG
       
   594     OsTracePrint( KUmacDetails, 
       
   595         (TUint8*)("UMAC: WlanDot11ReassociationPending::ChangeInternalState(): old state:"));
       
   596     OsTracePrint( KUmacDetails, iStateName[iState] );
       
   597     OsTracePrint( KUmacDetails, 
       
   598         (TUint8*)("UMAC: WlanDot11ReassociationPending::ChangeInternalState(): new state:"));
       
   599     OsTracePrint( KUmacDetails, iStateName[aNewState] );
       
   600 #endif
       
   601 
       
   602     iState = aNewState;
       
   603     Fsm( aCtxImpl, ESTATEENTRY );
       
   604     }
       
   605 
       
   606 // -----------------------------------------------------------------------------
       
   607 // 
       
   608 // -----------------------------------------------------------------------------
       
   609 //
       
   610 TBool WlanDot11ReassociationPending::SendReassociationRequest( WlanContextImpl& aCtxImpl )
       
   611     {
       
   612     OsTracePrint( KUmacAssoc, (TUint8*)
       
   613         ("UMAC: WlanDot11ReassociationPending::SendReassociationRequest"));
       
   614 
       
   615     TBool status ( EFalse );
       
   616     TUint8* startOfFrame ( NULL );
       
   617 
       
   618     const TUint32 length_of_frame 
       
   619         = ConstructReassociationRequestFrame( aCtxImpl, startOfFrame );
       
   620     
       
   621     if ( length_of_frame )
       
   622         {
       
   623         // frame is ready for delivery in the tx buffer
       
   624         // send reassociation request message to the AP
       
   625         //
       
   626         
       
   627         const WHA::TQueueId queue_id 
       
   628             = QueueId( aCtxImpl, startOfFrame );
       
   629 
       
   630         // push the frame to packet scheduler for transmission
       
   631         status = aCtxImpl.PushPacketToPacketScheduler(
       
   632                     startOfFrame,
       
   633                     length_of_frame,
       
   634                     queue_id,
       
   635                     E802Dot11FrameTypeReassociationReq,
       
   636                     NULL,
       
   637                     EFalse,
       
   638                     EFalse,
       
   639                     ETrue );
       
   640 
       
   641         if ( !status )
       
   642             {
       
   643             // as we came here we did get an internal Tx buffer for the frame
       
   644             // but packet push to scheduler failed. In this case we need cancel
       
   645             // the internal Tx buffer reservation as we will request it again
       
   646             // when the Packet Scheduler is again ready for packet push
       
   647             aCtxImpl.MarkInternalTxBufFree();
       
   648             }
       
   649         }
       
   650     else
       
   651         {
       
   652         // frame not ready for delivery. EFalse will be returned
       
   653         }
       
   654         
       
   655     return status;
       
   656     }
       
   657 
       
   658 // -----------------------------------------------------------------------------
       
   659 // 
       
   660 // -----------------------------------------------------------------------------
       
   661 //
       
   662 TUint32 WlanDot11ReassociationPending::ConstructReassociationRequestFrame( 
       
   663     WlanContextImpl& aCtxImpl,
       
   664     TUint8*& aStartOfFrame )
       
   665     {
       
   666     OsTracePrint( KUmacAssoc, (TUint8*)
       
   667         ("UMAC: WlanDot11ReassociationPending::ConstructReassociationRequestFrame") );
       
   668 
       
   669     TUint32 lengthOfFrame ( 0 );
       
   670     
       
   671     // client doesn't have to take care of the tx buffer header space
       
   672     // as the method below does that by itself
       
   673     aStartOfFrame = aCtxImpl.TxBuffer( ETrue );
       
   674     
       
   675     if ( aStartOfFrame )
       
   676         {
       
   677         // construct reassociation request frame
       
   678         // Note that we don't need to set SA because we have already set it 
       
   679         // in the initialization phase of the state machine.
       
   680         // Also capabilty information field is already set to frame template 
       
   681         // in AreNetworkRequirementsMet() method.
       
   682         // Also the address of the old AP has already been set in the
       
   683         // reassociation request frame
       
   684 
       
   685         TUint8* buffer_ptr = aStartOfFrame;
       
   686 
       
   687         if ( aCtxImpl.HtSupportedByNw() && aCtxImpl.QosEnabled() )
       
   688             {
       
   689             // set the BSSID field     
       
   690             (aCtxImpl.GetHtReassociationRequestFrame()).iHeader.iBSSID = 
       
   691                 aCtxImpl.GetBssId();
       
   692             // set the DA field 
       
   693             (aCtxImpl.GetHtReassociationRequestFrame()).iHeader.iDA = 
       
   694                 aCtxImpl.GetBssId();
       
   695     
       
   696             // set listen interval (in units of beacon interval)
       
   697             (aCtxImpl.GetHtReassociationRequestFrame()).iFixedFields.iListenInterval 
       
   698                 = KDot11ListenIntervalInMs / aCtxImpl.NetworkBeaconInterval();
       
   699                 
       
   700             // copy frame to tx-buffer to correct offset
       
   701             os_memcpy( 
       
   702                 buffer_ptr,
       
   703                 &(aCtxImpl.GetHtReassociationRequestFrame()), 
       
   704                 sizeof( SHtReassociationRequestFrame ) );
       
   705     
       
   706             buffer_ptr += sizeof( SHtReassociationRequestFrame );            
       
   707             }
       
   708         else
       
   709             {
       
   710             // set the BSSID field     
       
   711             (aCtxImpl.GetReassociationRequestFrame()).iHeader.iBSSID = 
       
   712                 aCtxImpl.GetBssId();
       
   713             // set the DA field 
       
   714             (aCtxImpl.GetReassociationRequestFrame()).iHeader.iDA = 
       
   715                 aCtxImpl.GetBssId();
       
   716     
       
   717             // set listen interval (in units of beacon interval)
       
   718             (aCtxImpl.GetReassociationRequestFrame()).iFixedFields.iListenInterval 
       
   719                 = KDot11ListenIntervalInMs / aCtxImpl.NetworkBeaconInterval();
       
   720                 
       
   721             // copy frame to tx-buffer to correct offset
       
   722             os_memcpy( 
       
   723                 buffer_ptr,
       
   724                 &(aCtxImpl.GetReassociationRequestFrame()), 
       
   725                 sizeof( SReassociationRequestFrame ) );
       
   726     
       
   727             buffer_ptr += sizeof( SReassociationRequestFrame );
       
   728             }
       
   729 
       
   730         // set SSID IE
       
   731         
       
   732         SSsIdIE ssid_ie( (aCtxImpl.GetSsId()).ssid, 
       
   733             (aCtxImpl.GetSsId()).ssidLength );
       
   734 
       
   735         const TUint8 ssidIeLength( ssid_ie.GetIeLength() );
       
   736                 
       
   737         os_memcpy(
       
   738             buffer_ptr, 
       
   739             &ssid_ie, 
       
   740             ssidIeLength );
       
   741 
       
   742         buffer_ptr += ssidIeLength;
       
   743 
       
   744         // set supported rates IE
       
   745 
       
   746         const TUint8 supportedRatesIeLength( 
       
   747             aCtxImpl.GetOurSupportedRatesIE().GetIeLength() );
       
   748 
       
   749         os_memcpy( 
       
   750             buffer_ptr, 
       
   751             &(aCtxImpl.GetOurSupportedRatesIE()), 
       
   752             supportedRatesIeLength );
       
   753 
       
   754         buffer_ptr += supportedRatesIeLength;
       
   755 
       
   756         if ( aCtxImpl.HtSupportedByNw() )
       
   757             {
       
   758             // set HT capabilities element
       
   759     
       
   760             const TUint8 htCapabilitiesIeLength( 
       
   761                 aCtxImpl.GetOurHtCapabilitiesIe().GetIeLength() );
       
   762     
       
   763             os_memcpy( 
       
   764                 buffer_ptr, 
       
   765                 &(aCtxImpl.GetOurHtCapabilitiesIe()), 
       
   766                 htCapabilitiesIeLength );
       
   767     
       
   768             buffer_ptr += htCapabilitiesIeLength;
       
   769 
       
   770             OsTracePrint( KUmacAssoc, (TUint8*)
       
   771                 ("UMAC: HT capabilities element added") );
       
   772             }
       
   773         
       
   774         // set extended supported rates IE if it's not empty 
       
   775         if ( aCtxImpl.GetOurExtendedSupportedRatesIE().GetElementLength() )
       
   776             {        
       
   777             const TUint8 extSupportedRatesIeLength( 
       
   778                 aCtxImpl.GetOurExtendedSupportedRatesIE().GetIeLength() );
       
   779 
       
   780             os_memcpy( 
       
   781                 buffer_ptr, 
       
   782                 &(aCtxImpl.GetOurExtendedSupportedRatesIE()), 
       
   783                 extSupportedRatesIeLength );
       
   784 
       
   785             buffer_ptr += extSupportedRatesIeLength;        
       
   786             }
       
   787 
       
   788         // set any IEs possibly provided by management client
       
   789         const TUint8* ieData( aCtxImpl.IeData() );
       
   790         if ( ieData )
       
   791             {   
       
   792             const TUint16 ieDataLength( aCtxImpl.IeDataLength());
       
   793             
       
   794             os_memcpy( buffer_ptr, ieData, ieDataLength );
       
   795             buffer_ptr += ieDataLength;
       
   796 
       
   797             OsTracePrint( KUmacAssoc, (TUint8*)
       
   798                 ("UMAC: management client supplied IE(s) added") );                
       
   799             }
       
   800             
       
   801         // set WMM IE if needed
       
   802         if ( aCtxImpl.QosEnabled() )        
       
   803             {
       
   804             const TUint8 wmmIeLength( aCtxImpl.OurWmmIe().GetIeLength() );
       
   805 
       
   806             os_memcpy( 
       
   807                 buffer_ptr, 
       
   808                 &(aCtxImpl.OurWmmIe()),
       
   809                 wmmIeLength);
       
   810 
       
   811             buffer_ptr += wmmIeLength;        
       
   812 
       
   813             OsTracePrint( KUmacAssoc, (TUint8*)
       
   814                 ("UMAC: WMM IE added") );            
       
   815             }
       
   816 
       
   817         // length of frame
       
   818         lengthOfFrame = buffer_ptr - aStartOfFrame;
       
   819         }
       
   820     else
       
   821         {
       
   822         // we didn't get a Tx buffer. Zero will be returned as the frame length
       
   823         // to indicate that
       
   824 
       
   825         OsTracePrint( KUmacAssoc, (TUint8*)
       
   826             ("UMAC: WlanDot11ReassociationPending::ConstructReassociationRequestFrame: no internal Tx buffer available") );
       
   827         }
       
   828     
       
   829     return lengthOfFrame;
       
   830     }
       
   831 
       
   832 // -----------------------------------------------------------------------------
       
   833 // 
       
   834 // -----------------------------------------------------------------------------
       
   835 //
       
   836 void WlanDot11ReassociationPending::StartReassociationResponseTimer( 
       
   837     WlanContextImpl& aCtxImpl ) const
       
   838     {
       
   839     // start association response timeout timer
       
   840     const TUint32 timeout( dot11AssociateResponseTimeout * KTU );
       
   841     
       
   842     OsTracePrint( KUmacAssoc, (TUint8*)
       
   843         ("UMAC: WlanDot11ReassociationPending::StartReassociationResponseTimer: timeout in %d microseconds"), 
       
   844         timeout );
       
   845     
       
   846     aCtxImpl.iUmac.RegisterTimeout( timeout );
       
   847     }
       
   848 
       
   849 // -----------------------------------------------------------------------------
       
   850 // 
       
   851 // -----------------------------------------------------------------------------
       
   852 //
       
   853 void WlanDot11ReassociationPending::OnRxReassocResponseEvent( 
       
   854     WlanContextImpl& aCtxImpl )
       
   855     {
       
   856     switch ( iState )
       
   857         {
       
   858         case EWAIT4REASSOCIATIONRESPONSE:
       
   859             if ( iFlags & KConfigureAc )
       
   860                 {
       
   861                 ChangeInternalState( aCtxImpl, ECONFIGUREAC );                                
       
   862                 }
       
   863             else
       
   864                 {
       
   865                 ChangeInternalState( aCtxImpl, ECONTINUEDOT11TRAVERSE );                
       
   866                 }
       
   867             break;
       
   868         default:
       
   869             // this means that we have recieved a valid dot11 
       
   870             // reassociation response frame 
       
   871             // but we are not internally in the correct state
       
   872             // Either someone  has skipped to call the packet xfer method
       
   873             // that informs of associate request frame 
       
   874             // xfer to the WLAN device or
       
   875             // we have an internal error
       
   876 #ifndef NDEBUG
       
   877             OsTracePrint( KErrorLevel, (TUint8*)("UMAC: state:"));
       
   878             OsTracePrint( KErrorLevel, iStateName[iState] );
       
   879 #endif
       
   880             OsAssert( (TUint8*)("UMAC: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
   881         }
       
   882     }
       
   883 
       
   884 // -----------------------------------------------------------------------------
       
   885 // 
       
   886 // -----------------------------------------------------------------------------
       
   887 //
       
   888 T802Dot11ManagementStatusCode 
       
   889 WlanDot11ReassociationPending::IsRxReassociationSuccess( 
       
   890     WlanContextImpl& aCtxImpl,
       
   891     const void* aFrame,
       
   892     TUint32 aFlags )
       
   893     {
       
   894     OsTracePrint( KUmacAssoc, (TUint8*)
       
   895         ("UMAC: WlanDot11ReassociationPending::IsRxReassociationSuccess"));
       
   896 
       
   897     // get the fixed fields from association response    
       
   898     const SReassociationResponseFixedFields* fields = 
       
   899         HtcFieldPresent( aCtxImpl, aFrame, aFlags ) ?
       
   900             reinterpret_cast<const SReassociationResponseFixedFields*>
       
   901               (reinterpret_cast<const TUint8*>(aFrame) + 
       
   902                sizeof( SHtManagementFrameHeader )) :
       
   903             reinterpret_cast<const SReassociationResponseFixedFields*>
       
   904                   (reinterpret_cast<const TUint8*>(aFrame) + 
       
   905                    sizeof( SManagementFrameHeader ));
       
   906 
       
   907     // store AID 
       
   908     OsTracePrint( KUmacAssoc, (TUint8*)
       
   909         ("UMAC: WlanDot11ReassociationPending::IsRxReassociationSuccess: AID extracted from reassociation response: 0x%04x"), 
       
   910         fields->Aid() );
       
   911     aCtxImpl.Aid( fields->Aid() );
       
   912 
       
   913     return static_cast<T802Dot11ManagementStatusCode>(
       
   914         fields->StatusCode() );
       
   915     }
       
   916 
       
   917 // -----------------------------------------------------------------------------
       
   918 // 
       
   919 // -----------------------------------------------------------------------------
       
   920 //
       
   921 void WlanDot11ReassociationPending::OnTxCompleteEvent( 
       
   922     WlanContextImpl& aCtxImpl )
       
   923     {
       
   924     switch ( iState )
       
   925         {
       
   926         case ECONFIGUREAC:
       
   927             // continue state traversal
       
   928             ChangeInternalState( aCtxImpl, ECONTINUEDOT11TRAVERSE );
       
   929             break;
       
   930         default:
       
   931             // catch internal FSM programming error
       
   932             OsTracePrint( KErrorLevel, (TUint8*)("UMAC: state: %d"), iState);        
       
   933             OsAssert( (TUint8*)("UMAC: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
   934             break;
       
   935         }
       
   936     }
       
   937 
       
   938 // -----------------------------------------------------------------------------
       
   939 // 
       
   940 // -----------------------------------------------------------------------------
       
   941 //
       
   942 void WlanDot11ReassociationPending::OnTimeoutEvent( 
       
   943     WlanContextImpl& aCtxImpl )
       
   944     {
       
   945     // set completion code
       
   946     // as dot11idle state does the OID completion
       
   947     aCtxImpl.iStates.iIdleState.Set( KErrTimedOut );
       
   948     ChangeInternalState( aCtxImpl, ECONTINUEDOT11TRAVERSE );
       
   949     }
       
   950 
       
   951 // -----------------------------------------------------------------------------
       
   952 // Handler for scheduler full event upon trying to tx dot11-associate frame
       
   953 // -----------------------------------------------------------------------------
       
   954 //
       
   955 void WlanDot11ReassociationPending::OnTxSchedulerFullEvent( 
       
   956     WlanContextImpl& aCtxImpl )
       
   957     {
       
   958     // change state
       
   959     OsTracePrint( KWarningLevel | KUmacAssoc, (TUint8*)
       
   960         ("UMAC: packet scheduler full during association process") );
       
   961 
       
   962     ChangeInternalState( aCtxImpl, EWAIT4PUSHPACKET );
       
   963     }
       
   964 
       
   965 // -----------------------------------------------------------------------------
       
   966 // packet sceduler notification that a packet push is guaranteed to succeed 
       
   967 // -----------------------------------------------------------------------------
       
   968 //
       
   969 void WlanDot11ReassociationPending::OnPacketPushPossible( 
       
   970     WlanContextImpl& aCtxImpl )
       
   971     {
       
   972     // feed a critter to the fsm
       
   973     Fsm( aCtxImpl, EPUSHPACKET );
       
   974     }
       
   975 
       
   976 // -----------------------------------------------------------------------------
       
   977 // Handler for push packet to packet scheduler possible event
       
   978 // -----------------------------------------------------------------------------
       
   979 //
       
   980 void WlanDot11ReassociationPending::OnPushPacketEvent( 
       
   981     WlanContextImpl& aCtxImpl )
       
   982     {
       
   983     if ( iState == EWAIT4PUSHPACKET )
       
   984         {
       
   985         ChangeInternalState( aCtxImpl, ETXREASSOCIATIONFRAME );
       
   986         }
       
   987     }