diff -r 000000000000 -r c40eb8fe8501 wlan_bearer/wlanldd/wlan_common/umac_common/src/UmacDot11SharedAuthPending.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlan_bearer/wlanldd/wlan_common/umac_common/src/UmacDot11SharedAuthPending.cpp Tue Feb 02 02:03:13 2010 +0200 @@ -0,0 +1,490 @@ +/* +* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of the WlanDot11SharedAuthPending class +* +*/ + +/* +* %version: 27 % +*/ + +#include "config.h" +#include "UmacDot11SharedAuthPending.h" +#include "UmacContextImpl.h" + +#ifndef NDEBUG +const TInt8 WlanDot11SharedAuthPending::iName[] + = "dot11-sharedauthpending"; +#endif // !NDEBUG + +// ================= MEMBER FUNCTIONS ======================= + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +#ifndef NDEBUG +const TInt8* WlanDot11SharedAuthPending::GetStateName( + TUint8& aLength ) const + { + aLength = sizeof( iName ); + return iName; + } +#endif + +// ----------------------------------------------------------------------------- +// set appropriate used algorithm number to authenticate request frame +// ----------------------------------------------------------------------------- +// +void WlanDot11SharedAuthPending::OnSetAlgorithmNumber( + WlanContextImpl& aCtxImpl ) + { + if ( aCtxImpl.HtSupportedByNw() ) + { + aCtxImpl.GetHtAuthenticationFrame().SetAlgorithmNmbr( + K802Dot11AuthModeShared ); + } + else + { + aCtxImpl.GetAuthenticationFrame().SetAlgorithmNmbr( + K802Dot11AuthModeShared ); + } + } + +// ----------------------------------------------------------------------------- +// Handler for state entry event. +// ----------------------------------------------------------------------------- +// +void WlanDot11SharedAuthPending::OnStateEntryEvent( + WlanContextImpl& aCtxImpl ) + { + TBool ret( ETrue ); + + switch ( iState ) + { + case EINIT: + // do all the synchronous + // composite state entry actions + StateEntryActions( aCtxImpl ); + // continue with the state traversal + Fsm( aCtxImpl, ECONTINUE ); + break; + case ETXAUTHFRAME: + // send correct authenticate frame + if ( aCtxImpl.GetAuthSeqNmbrExpected() + == E802Dot11AuthenticationSeqNmbr2 ) + { + ret = SendAuthSeqNbr1Frame( aCtxImpl ); + } + else + { + ret = SendAuthSeqNbr3Frame( aCtxImpl ); + } + + if (!ret ) + { + // tx of dot11-authenticate frame failed + // because packet scheduler was full + // or because we didn't get a Tx buffer + // so we enter to a wait state + Fsm( aCtxImpl, ETX_SCHEDULER_FULL ); + } + break; + case ECONTINUEDOT11TRAVERSE: + ContinueDot11StateTraversal( aCtxImpl ); + break; + case EWAIT4AUTHRESPONSE: + StartAuthenticationFrameResponseTimer( aCtxImpl ); + break; + case EWAIT4PUSHPACKET: + // nothing to do here than wait + break; + default: + // catch internal FSM programming error +#ifndef NDEBUG + OsTracePrint( KErrorLevel, (TUint8*)("UMAC: state:")); + OsTracePrint( KErrorLevel, iStateName[iState] ); +#endif + OsAssert( (TUint8*)("UMAC: panic"), + (TUint8*)(WLAN_FILE), __LINE__ ); + break; + } + } + +// ----------------------------------------------------------------------------- +// Handler for rx authentication response event. +// ----------------------------------------------------------------------------- +// +void WlanDot11SharedAuthPending::OnRxAuthResponseEvent( + WlanContextImpl& aCtxImpl ) + { + switch ( iState ) + { + case EWAIT4AUTHRESPONSE: + // check do we need to send an another authenticate frame or not + if ( // current authentication frame exchange was a success + ((iFlags & KAuthSuccess) + // AND authentication frame exchange is complete + && ( aCtxImpl.GetAuthSeqNmbrExpected() + == E802Dot11AuthenticationSeqNmbr4 )) + // OR current authentication frame exchange was a failure + || !(iFlags & KAuthSuccess) + ) + { + ChangeInternalState( aCtxImpl, ECONTINUEDOT11TRAVERSE ); + } + else + { + // current authentication frame exchange was a success + // but authentication frame exchange is NOT complete + + // incerement the seq.nmbr expected from AP counter + aCtxImpl.IncrementAuthSeqNmbrExpected(); + ChangeInternalState( aCtxImpl, ETXAUTHFRAME ); + } + break; + default: + // this means that we have recieved a valid dot11 + // authenticate response frame that we are waiting for + // but we are not internally in such a state + // only feasible situation for this is that + // someone has skipped a call to the packet xfer method + // that informs of authenticate request frame + // xfer to the WLAN device. + // other case is that our fsm is totally messed up + // so we catch this +#ifndef NDEBUG + OsTracePrint( KErrorLevel, (TUint8*)("state:")); + OsTracePrint( KErrorLevel, iStateName[iState] ); +#endif + OsAssert( (TUint8*)("UMAC: panic"), + (TUint8*)(WLAN_FILE), __LINE__ ); + break; + } + } + +// ----------------------------------------------------------------------------- +// Send authenticate seq. number 3 message +// ----------------------------------------------------------------------------- +// +TBool WlanDot11SharedAuthPending::SendAuthSeqNbr3Frame( + WlanContextImpl& aCtxImpl ) const + { + OsTracePrint( KUmacAuth, (TUint8*) + ("UMAC: WlanDot11SharedAuthPending::SendAuthSeqNbr3Frame") ); + + TBool status ( EFalse ); + + // client doesn't have to take care of the tx buffer header space + // as the method below does that by itself + TUint8* frame_ptr = aCtxImpl.TxBuffer( ETrue ); + + if ( frame_ptr ) + { + // store start of frame + const TUint8* start_of_frame = frame_ptr; + TUint32 txFrameHdrAndFixedPartLen ( 0 ); + // construct auth message seq. number 3 + + if ( aCtxImpl.HtSupportedByNw() && aCtxImpl.QosEnabled() ) + { + // set our seq. nbr in next authenticate Tx-frame + aCtxImpl.GetHtAuthenticationFrame().IncrementSeqNmbr(); + + // set the WEP bit, as that is the only thing that triggers + // the ecryption engine. Don't worry about clearing it here + // because we do it in WlanDot11AuthenticatePending::Entry() + aCtxImpl.GetHtAuthenticationFrame().SetWepBit(); + + OsTracePrint( KUmacAuth, (TUint8*)("UMAC: Algorithm number: %d"), + aCtxImpl.GetHtAuthenticationFrame().GetAlgorithmNumber()); + OsTracePrint( KUmacAuth, (TUint8*)("UMAC: Sequence number: %d"), + aCtxImpl.GetHtAuthenticationFrame().GetSeqNmbr()); + OsTracePrint( KUmacAuth, (TUint8*)("UMAC: Status code: %d"), + aCtxImpl.GetHtAuthenticationFrame().GetStatusCode()); + + // copy the dot11 authentication frame header to tx buffer + os_memcpy( frame_ptr, + &(aCtxImpl.GetHtAuthenticationFrame().iHeader), + sizeof( aCtxImpl.GetHtAuthenticationFrame().iHeader) ); + + // adjust to end of copy + frame_ptr + += sizeof( aCtxImpl.GetHtAuthenticationFrame().iHeader ); + + txFrameHdrAndFixedPartLen = sizeof( SHtAuthenticationFrame ); + } + else + { + // set our seq. nbr in next authenticate Tx-frame + aCtxImpl.GetAuthenticationFrame().IncrementSeqNmbr(); + + // set the WEP bit, as that is the only thing that triggers + // the ecryption engine. Don't worry about clearing it here + // because we do it in WlanDot11AuthenticatePending::Entry() + aCtxImpl.GetAuthenticationFrame().SetWepBit(); + + OsTracePrint( KUmacAuth, (TUint8*)("UMAC: Algorithm number: %d"), + aCtxImpl.GetAuthenticationFrame().GetAlgorithmNumber()); + OsTracePrint( KUmacAuth, (TUint8*)("UMAC: Sequence number: %d"), + aCtxImpl.GetAuthenticationFrame().GetSeqNmbr()); + OsTracePrint( KUmacAuth, (TUint8*)("UMAC: Status code: %d"), + aCtxImpl.GetAuthenticationFrame().GetStatusCode()); + + // copy the dot11 authentication frame header to tx buffer + os_memcpy( frame_ptr, + &(aCtxImpl.GetAuthenticationFrame().iHeader), + sizeof( aCtxImpl.GetAuthenticationFrame().iHeader) ); + + // adjust to end of copy + frame_ptr + += sizeof( aCtxImpl.GetAuthenticationFrame().iHeader ); + + txFrameHdrAndFixedPartLen = sizeof( SAuthenticationFrame ); + } + + // set the WEP IV field + // do a 16-bit fill + const TUint16 fill_value( 0 ); + fill( + reinterpret_cast(frame_ptr), + ( reinterpret_cast(frame_ptr) ) + + ( KWepIVLength / sizeof( fill_value ) ), + fill_value ); + + // adjust to begin of the authentication frame fixed fields + frame_ptr += KWepIVLength; + + if ( aCtxImpl.HtSupportedByNw() ) + { + // copy authentication frame fixed fields after WEP IV + os_memcpy( + frame_ptr, + &(aCtxImpl.GetHtAuthenticationFrame().iAuthenticationFields), + sizeof( + aCtxImpl.GetHtAuthenticationFrame().iAuthenticationFields) ); + + // adjust to end of copy + frame_ptr += sizeof( + aCtxImpl.GetHtAuthenticationFrame().iAuthenticationFields ); + + // copy challenge text from Rx-buffer to Tx-buffer + + const TUint KRxFramehdrAndFixedPartLen = + HtcFieldPresent( + aCtxImpl, + iLatestRxAuthRespPtr, + iLatestRxAuthRespFlags ) ? + sizeof( SHtAuthenticationFrame ) : + sizeof( SAuthenticationFrame ); + os_memcpy( frame_ptr, + iLatestRxAuthRespPtr + KRxFramehdrAndFixedPartLen, + KChallengeTextLength + KInfoElementHeaderLength ); + } + else + { + // copy authentication frame fixed fields after WEP IV + os_memcpy( + frame_ptr, + &(aCtxImpl.GetAuthenticationFrame().iAuthenticationFields), + sizeof( + aCtxImpl.GetAuthenticationFrame().iAuthenticationFields) ); + + // adjust to end of copy + frame_ptr += sizeof( + aCtxImpl.GetAuthenticationFrame().iAuthenticationFields ); + + // copy challenge text from Rx-buffer to Tx-buffer + os_memcpy( frame_ptr, + iLatestRxAuthRespPtr + sizeof( SAuthenticationFrame ), + KChallengeTextLength + KInfoElementHeaderLength ); + } + + // trace the frame critter + OsTracePrint( KUmacAuth, (TUint8*)("UMAC: dot11 authenticate frame tx:"), + *(reinterpret_cast(start_of_frame)) ); + + const WHA::TQueueId queue_id + = QueueId( aCtxImpl, start_of_frame ); + + // push the frame to packet scheduler for transmission + status = aCtxImpl.PushPacketToPacketScheduler( + start_of_frame, + txFrameHdrAndFixedPartLen + + KChallengeTextLength + + KInfoElementHeaderLength + + KWepIVLength + + KWEPICVLength, + queue_id, + E802Dot11FrameTypeAuthSeqNmbr3, + NULL, + EFalse, + EFalse, + ETrue ); + + if ( !status ) + { + // as we came here we did get an internal Tx buffer for the frame + // but packet push to scheduler failed. In this case we need to + // cancel the internal Tx buffer reservation as we will request it + // again when the Packet Scheduler is again ready for packet push + aCtxImpl.MarkInternalTxBufFree(); + } + } + else + { + // we didn't get a Tx buffer => frame not sent. EFalse will be returned + // to indicate that + OsTracePrint( KUmacAuth, (TUint8*) + ("UMAC: WlanDot11SharedAuthPending::SendAuthSeqNbr3Frame: no internal Tx buffer available") ); + } + + return status; + } + +// ----------------------------------------------------------------------------- +// If we land here it means that we have received a frame of somekind +// with a success status +// ----------------------------------------------------------------------------- +// +void WlanDot11SharedAuthPending::OnReceiveFrameSuccess( + WlanContextImpl& aCtxImpl, + const void* aFrame, + TUint16 /*aLength*/, + WHA::TRcpi /*aRcpi*/, + TUint32 aFlags, + TUint8* /*aBuffer*/ ) + { + // receive success + // parse frame in order to determine is it what we desire + const SManagementFrameHeader* frame_hdr + = static_cast(aFrame); + + TBool type_match( EFalse ); + + iFlags &= ~KAuthReceived; + iFlags &= ~KAuthSuccess; + + if (// can we accept this frame + // is this a management type + authentication subtype frame + IsRequestedFrameType( + frame_hdr->iFrameControl.iType, + E802Dot11FrameTypeAuthentication, type_match ) + // AND our MAC address is DA + && (frame_hdr->iDA == aCtxImpl.iWlanMib.dot11StationId) + // AND we are in correct state + && ( iState == EWAIT4AUTHRESPONSE ) + ) + { + + // this is a valid authentication frame targeted to us + // mark it so + iFlags |= KAuthReceived; + + // cancel authentication timer + aCtxImpl.CancelTimer(); + + // at this point we don't know is this a authentication success + // or failure scenario for this frame exchange + + if ( ResolveAuthMessage( + aCtxImpl, + K802Dot11AuthModeShared, + aFrame, + aFlags ) ) + { + // authentication frame exchange was a success + // mark it also + iFlags |= KAuthSuccess; + // store pointer to the received frame. We need it to extract + // the challenge text from the frame + iLatestRxAuthRespPtr = reinterpret_cast(aFrame); + // store also its receive flags for the same purpose + iLatestRxAuthRespFlags = aFlags; + + OsTracePrint( KUmacAuth, (TUint8*) + ("UMAC: dot11-sharedauthpending * authentication frame exchange success")); + OsTracePrint( KUmacAuth, (TUint8*)("UMAC: sequence number expected: %d"), + aCtxImpl.GetAuthSeqNmbrExpected()); + + if ( !((aCtxImpl.GetAuthSeqNmbrExpected() + == E802Dot11AuthenticationSeqNmbr2) + || (aCtxImpl.GetAuthSeqNmbrExpected() + == E802Dot11AuthenticationSeqNmbr4 )) + ) + { + // catch a programming error + OsTracePrint( KErrorLevel, + (TUint8*)("UMAC: sequence number expected"), + aCtxImpl.GetAuthSeqNmbrExpected()); + OsAssert( (TUint8*)("UMAC: panic"), + (TUint8*)(WLAN_FILE), __LINE__ ); + } + } + else + { + // authentication frame exchange was a failure + + OsTracePrint( KUmacAuth, (TUint8*) + ("UMAC: dot11-sharedauthpending * authentication failure")); + OsTracePrint( KUmacAuth, (TUint8*) + ("UMAC: sequence number expected: %d"), + aCtxImpl.GetAuthSeqNmbrExpected()); + + // authentication response message was NOT valid + // lets's see why that's the case + const SAuthenticationFixedFields* auth_fields + = reinterpret_cast + (reinterpret_cast(aFrame) + + sizeof( SManagementFrameHeader )); + + OsTracePrint( KWarningLevel | KUmacAuth, (TUint8*) + ("UMAC: dot11-sharedauthpending * authentication failure") ); + OsTracePrint( KWarningLevel | KUmacAuth, (TUint8*) + ("UMAC: authentication status code: %d"), + auth_fields->StatusCode() ); + + // set the completion (error) code value returned to user mode + // as the dot11idle state does the OID completion in this case + if ( auth_fields->StatusCode() == E802Dot11StatusSuccess ) + { + // network returned success code but still an error in the + // authentication sequence has occurred. + // Either an authentication frame was received out of + // sequence or the algorithm number wasn't the expected one + aCtxImpl.iStates.iIdleState.Set( KErrGeneral ); + } + else + { + // complete with the network returned error code + aCtxImpl.iStates.iIdleState.Set( auth_fields->StatusCode() ); + } + } + } + else + { + // incorrect frame type + // or we are not in correct state + // so we shall discard its processing + } + + if ( iFlags & KAuthReceived ) + { + // authentication response was received + // either success or failure + // we don't really care in this state + + Fsm( aCtxImpl, ERXAUTHRESPONSE ); + } + }