--- /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<TUint16*>(frame_ptr),
+ ( reinterpret_cast<TUint16*>(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<const Sdot11MacHeader*>(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<const SManagementFrameHeader*>(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<const TUint8*>(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<const SAuthenticationFixedFields*>
+ (reinterpret_cast<const TUint8*>(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 );
+ }
+ }