/*
 * Copyright (c) 2012-2013 Qualcomm Atheros, Inc.
 * All Rights Reserved.
 * Qualcomm Atheros Confidential and Proprietary.
 */
/*
 * Woodside Networks, Inc proprietary. All rights reserved.
 * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xAuthRsnFsm.c $
 *
 * Contains definitions for the RSN EAPOL-Key FSM on the
 * authenticator side. This is based on 802.11i.
 *
 * Author:      Mayank D. Upadhyay
 * Date:        19-December-2002
 * History:-
 * Date         Modified by     Modification Information
 * ------------------------------------------------------
 *
 */
#include "vos_types.h"
#include "bapRsnSsmServices.h"
#include "bapRsnSsmEapol.h"
#include "bapRsnErrors.h"
#include "bapInternal.h"
#include "bapRsn8021xFsm.h"
#include "bapRsn8021xAuthFsm.h"
#include "vos_utils.h"
#include "vos_memory.h"
#include "vos_timer.h"
#include "bapRsnTxRx.h"
#include "bapRsnSsmAesKeyWrap.h"
#include "btampFsm.h"

// The different states that this FSM transitions through
#define DISCONNECT           0
#define DISCONNECTED         1
#define INITIALIZE           2
#define AUTHENTICATION       3
#define AUTHENTICATION_2     4
#define GET_PSK              5   
#define GET_EAP_KEY          6
#define PTK_START            7
#define PTK_INIT_NEGO        8
#define PTK_INIT_NEGO_TX     9
#define PTK_INIT_DONE       10
#define UPDATE_KEYS_REQ     11
#define INTEG_FAILURE       12
#define KEY_UPDATE          13
#define NUM_STATES (KEY_UPDATE + 1)



static tAuthRsnFsmConsts authConsts = { 2000, 3 };  //timeout, retry limit
static v_U8_t aniSsmIeRsnOui[] = ANI_SSM_IE_RSN_OUI;


/**************************************
 * Static functions in this module
 **************************************/

static 
int zeroOutPtk(tAuthRsnFsm *fsm);
static 
int stopAllTimers(tAuthRsnFsm *fsm);

static
int checkMic(tAuthRsnFsm *fsm, 
             tAniEapolKeyAvailEventData *data);

static 
int checkLocalReplayCounter(tAuthRsnFsm *fsm, 
                            tAniEapolKeyAvailEventData *data);
static 
int checkPeerReplayCounter(tAuthRsnFsm *fsm, 
                           tAniEapolKeyAvailEventData *data);

static int checkInfoElement(tAuthRsnFsm *fsm,
                            tAniEapolKeyAvailEventData *data);

static
int derivePtk(tAuthRsnFsm *fsm, 
              tAniEapolKeyAvailEventData *data);


static int checkTransition(tAuthRsnFsm *fsm, void *arg);

static int
gotoStateInit(tAuthRsnFsm *fsm);

static void msg2TimerCallback( void * );
static void msg4TimerCallback( void * );

static int authRsnRxFrameHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket );
static int authRsnTxCompleteHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus );

/********************************
 * Functions Forward Declarations
 ********************************/

int authRsnAuthStartEventHandler( tAuthRsnFsm *fsm );
int authRsnAuthDisconEventHandler( tAuthRsnFsm *fsm );

/*************************
 * The exported functions
 *************************/

/**
 * authRsnFsmInit
 *
 * FUNCTION:
 * Initializes the constants and the callbacks needed by this FSM
 * module.
 *
 * @param consts the various constant values needed by this FSM
 * @param cb callbacks to the various procedures needed by this FSM
 *
 * @return ANI_OK if the operation succeeds
 */
int
authRsnFsmInit(tAuthRsnFsmConsts *constsIn)
{
    // TODO: Read the constants in from config
    // authConsts = *constsIn;
    authConsts.timeoutPeriod = 2000;    //ms
    authConsts.maxTries = 3;

    return ANI_OK;
}

/**
 * authRsnFsmCreate
 *
 * FUNCTION
 * Allocates and initializes the state of an RSN key FSM instance for
 * the given STA context.
 * 
 * @parm staCtx the STA context whose instance is being created
 * @param pskBased pass in eANI_BOOLEAN_TRUE is this STA is to be
 * authenticated based on a pre-shared key as opposed to EAP.
 *
 * @return ANI_OK if the operation succeeds
 */
int
authRsnFsmCreate(tBtampContext *ctx)
{
    int retVal = ANI_OK;
    tAuthRsnFsm *fsm = &ctx->uFsm.authFsm;

    // First, clear everything out
    vos_mem_zero( fsm, sizeof(tAuthRsnFsm));

    if( !VOS_IS_STATUS_SUCCESS( bapRsnRegisterTxRxCallbacks( authRsnTxCompleteHandler,
                                            authRsnRxFrameHandler ) ) )
    {
        return ANI_ERROR;
    }

    if( !VOS_IS_STATUS_SUCCESS( bapRsnRegisterRxCallback( ctx->pvosGCtx ) ) )
    {
        return ANI_ERROR;
    }

    // Allocate the station context
    fsm->staCtx = (tStaContext *)vos_mem_malloc( sizeof(tStaContext) );
    if (fsm->staCtx == NULL) 
    {
        retVal = ANI_E_MALLOC_FAILED;
        VOS_ASSERT( 0 );
        goto error;
    }
    // Clear out the station context
    vos_mem_zero( fsm->staCtx, sizeof(tStaContext) );
    
    fsm->ctx = ctx;
    fsm->staCtx->authRsnFsm = fsm;
    //Only support CCMP
    fsm->staCtx->pwCipherType = eCSR_ENCRYPT_TYPE_AES;

    if( !VOS_IS_STATUS_SUCCESS( vos_timer_init( &fsm->msg2Timer, VOS_TIMER_TYPE_SW, msg2TimerCallback, fsm ) ) )
    {
        retVal = ANI_E_MALLOC_FAILED;
        VOS_ASSERT( 0 );
        goto error;
    }

    if( !VOS_IS_STATUS_SUCCESS( vos_timer_init( &fsm->msg4Timer, VOS_TIMER_TYPE_SW, msg4TimerCallback, fsm ) ) )
    {
        retVal = ANI_E_MALLOC_FAILED;
        VOS_ASSERT( 0 );
        goto error;
    }

    retVal = aniAsfPacketAllocateExplicit(&fsm->lastEapol,
                                          RSN_MAX_PACKET_SIZE,
                                          EAPOL_TX_HEADER_SIZE );
    if (retVal != ANI_OK) 
    {
        VOS_ASSERT( 0 );
        goto error;
    }

    aniAsfPacketAllocate(&fsm->staCtx->pmk);
    if (fsm->staCtx->pmk == NULL) 
    {
        retVal = ANI_E_MALLOC_FAILED;
        VOS_ASSERT( 0 );
        goto error;
    }

    aniAsfPacketAllocateExplicit(&fsm->staCtx->ieSta,
                                 RSN_IE_MAX_PACKET_SIZE,
                                 RSN_IE_HEADER_SIZE );
    if (fsm->staCtx->ieSta == NULL) 
    {
        retVal = ANI_E_MALLOC_FAILED;
        VOS_ASSERT( 0 );
        goto error;
    }

    fsm->cryptHandle = 0;
    if( !VOS_IS_STATUS_SUCCESS( vos_crypto_init( &fsm->cryptHandle ) ) )
    {
        retVal = ANI_E_FAILED;
        VOS_ASSERT( 0 );
        goto error;
    }

    fsm->currentState = INITIALIZE;
    gotoStateInit(fsm);

    //We can call this function here because it is connected at this time
    authRsnFsmProcessEvent( fsm, RSN_FSM_AUTH_START, NULL );

    return ANI_OK;

 error:
    authRsnFsmFree(ctx);

    return retVal;
    
}

/**
 * authRsnFsmFree
 *
 * FUNCTION
 * Frees a previously allocated RSN Key FSM in a STA context. If the
 * RSN Key FSM is not yet allocated, then this is an error.
 * 
 * @param ctx the STA context whose FSM instance is to be freed
 *
 * @return ANI_OK if the operation succeeds
 */
int
authRsnFsmFree(tBtampContext *ctx)
{
    tAuthRsnFsm *fsm = &ctx->uFsm.authFsm;

    VOS_ASSERT(fsm);

    if( fsm->cryptHandle)
    {
        vos_crypto_deinit( fsm->cryptHandle );
    }
     
    bapRsnClearTxRxCallbacks(); 

    if ( fsm->staCtx )
    {
        fsm->staCtx->authRsnFsm = NULL;
    }

    if ( VOS_TIMER_STATE_UNUSED != fsm->msg2Timer.state ) vos_timer_destroy( &fsm->msg2Timer );
    if ( VOS_TIMER_STATE_UNUSED != fsm->msg4Timer.state ) vos_timer_destroy( &fsm->msg4Timer );

    if (fsm->lastEapol)
    {    
        aniAsfPacketFree(fsm->lastEapol);
        fsm->lastEapol = NULL; 
    }

    if( fsm->staCtx )
    {
        if( fsm->staCtx->pmk )
        {
            aniAsfPacketFree( fsm->staCtx->pmk );
            fsm->staCtx->pmk = NULL;
        }
       vos_mem_free(fsm->staCtx);
       fsm->staCtx = NULL; 
    }

    vos_mem_zero( fsm, sizeof(tAuthRsnFsm) );

    return ANI_OK;
}

/**
 * authRsnFsmProcessEvent
 *
 * FUNCTION
 * Passes an event to the RSN key FSM instance for immediate processing.
 * 
 * @param fsm the RSN Key FSM instance
 * @param eventId the AAG event to process
 * @param arg an optional argument for this event
 *
 * @return ANI_OK if the operation succeeds
 */
int
authRsnFsmProcessEvent(tAuthRsnFsm *fsm, tRsnFsmEvent eventId, void *arg)
{
    VOS_ASSERT(fsm);

    switch (eventId) {
    case RSN_FSM_TIMER_EXPIRED:
        // Proceed straight to checkTransition
        break;
    case RSN_FSM_AUTH_START:
        fsm->authReq = eANI_BOOLEAN_TRUE;
        authRsnAuthStartEventHandler(fsm);
        break;
    case RSN_FSM_EAPOL_FRAME_AVAILABLE:
        fsm->eapolAvail = eANI_BOOLEAN_TRUE;
        break;
    case RSN_FSM_DISCONNECT:
        fsm->disconnect = eANI_BOOLEAN_TRUE;
        authRsnAuthDisconEventHandler(fsm);
        break;
    case RSN_FSM_INTEG_FAILED:
        fsm->integFailed = eANI_BOOLEAN_TRUE;
        break;
    default:
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, 
            "Unknown event for Auth RSN Key Fsm: %d\n", eventId);
        VOS_ASSERT( 0 );
        return ANI_E_ILLEGAL_ARG;
        break;
    }

    checkTransition(fsm, arg);

    return ANI_OK;
}


int
authRsnAuthStartEventHandler(tAuthRsnFsm *fsm)
{
    static v_U8_t btampStaRSNIE[] = {0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 
        0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00 };
    // Copy required info
    vos_mem_copy( &fsm->staCtx->authMac, fsm->ctx->self_mac_addr, 6);
    vos_mem_copy( &fsm->staCtx->suppMac, fsm->ctx->peer_mac_addr, 6);
    aniAsfPacketAppendBuffer( fsm->staCtx->pmk, fsm->ctx->key_material, fsm->ctx->key_length);

    aniAsfPacketAppendBuffer( fsm->staCtx->ieSta, btampStaRSNIE, sizeof(btampStaRSNIE));
    return ANI_OK;
}

int
authRsnAuthDisconEventHandler(tAuthRsnFsm *fsm)
{
    // Free Stactx .?
    return ANI_OK;
}

/***********************
 * The static functions
 ***********************/

static int
gotoStateInit(tAuthRsnFsm *fsm)
{
    fsm->currentState = INITIALIZE;

    // TODO: Move this to a global position which applies to WEP as
    // well 
    //initGlobalKeys = eANI_BOOLEAN_FALSE; 

    fsm->authReq = eANI_BOOLEAN_FALSE;
    fsm->eapolAvail = eANI_BOOLEAN_FALSE;
    fsm->disconnect = eANI_BOOLEAN_FALSE;
    fsm->integFailed = eANI_BOOLEAN_FALSE;

    fsm->numTries = 0;

    // Create two replay counter's..one for our requests, and another
    // for STA's requests. Initialize the first one randomly.
    aniSsmReplayCtrCreate(fsm->cryptHandle, &fsm->staCtx->localReplayCtr, 
                          ANI_EAPOL_KEY_RSN_RSC_SIZE, 0);
    aniSsmReplayCtrCreate(fsm->cryptHandle, &fsm->staCtx->peerReplayCtr, 
                          ANI_EAPOL_KEY_RSN_RSC_SIZE, 0);

    return ANI_OK;
}

static int
gotoStateAuthentication(tAuthRsnFsm *fsm)
{
    fsm->currentState = AUTHENTICATION;

    zeroOutPtk(fsm);
    fsm->authReq = eANI_BOOLEAN_FALSE;

    checkTransition(fsm, NULL); // UCT rule

    return ANI_OK;
}

static int
gotoStateAuthentication2(tAuthRsnFsm *fsm)
{
    fsm->currentState = AUTHENTICATION_2;

    if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( fsm->cryptHandle, fsm->aNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE ) ) )
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
            "gotoStateAuthentication2 fail to get random number. Disconnect\n" );
        bapAuthDisconnect( fsm->ctx );
        return ANI_ERROR;
    }
    fsm->numTries = 0;

    checkTransition(fsm, NULL); // UCT rule

    return ANI_OK;
}


static int
gotoStateGetPsk(tAuthRsnFsm *fsm)
{
    //This is simply a transaction because we already have the PMK. We always do.
    fsm->currentState = GET_PSK;

    fsm->numTries = 0;
    
    checkTransition(fsm, NULL);
    
    return ANI_OK;
}

static int
gotoStatePtkStart(tAuthRsnFsm *fsm)
{
    tAniEapolRsnKeyDesc txDesc;
    int retVal;

    fsm->msg2TimeOut = VOS_FALSE;
    fsm->currentState = PTK_START;

    // Create a new packet if we don't have one to retransmit
    //if (aniAsfPacketGetLen(fsm->lastEapol) == 0) 
#if 0    
    if( fsm->lastEapol )
    {
        aniAsfPacketFree( fsm->lastEapol );
        fsm->lastEapol = NULL;

    retVal = aniAsfPacketAllocateExplicit(&fsm->lastEapol,
                                          RSN_MAX_PACKET_SIZE,
                                          EAPOL_TX_HEADER_SIZE );
#endif    
    aniAsfPacketEmptyExplicit(fsm->lastEapol, 
                              EAPOL_TX_HEADER_SIZE);
    //}
   // if (1) 
    //{

        vos_mem_zero( &txDesc, sizeof(txDesc) );

        // The Key Information bits...
        if (fsm->staCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) 
        {
            txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES;
        } 
        else {
            return ANI_E_ILLEGAL_ARG;
        }
        txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE;
        txDesc.info.ackFlag = eANI_BOOLEAN_TRUE;

        // The other fields...
        txDesc.keyLen = aagGetKeyMaterialLen(fsm->staCtx->pwCipherType);
        aniSsmReplayCtrNext(fsm->staCtx->localReplayCtr, txDesc.replayCounter);
        vos_mem_copy(txDesc.keyNonce, fsm->aNonce, sizeof(txDesc.keyNonce));

        retVal = aniEapolWriteKey(fsm->cryptHandle,
                                  fsm->lastEapol,
                                  fsm->staCtx->suppMac,
                                  fsm->staCtx->authMac,
                                  ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW,
                                  &txDesc,
                                  NULL, 0);
        if( !ANI_IS_STATUS_SUCCESS( retVal ) )
        {
            return retVal;
        }
#if 0
    } 
    else {
        retransmit = eANI_BOOLEAN_TRUE;
    }
#endif    

    if( VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) )
    {
        retVal = ANI_OK;
    }
    else
    {
        //we fail to send the eapol frame disconnect
        bapAuthDisconnect( fsm->ctx );
        retVal = ANI_ERROR;
    }

    return retVal;
}

static int
gotoStatePtkInitNego(tAuthRsnFsm *fsm, void *arg)
{
    fsm->currentState = PTK_INIT_NEGO;

    // Replay counter will be automatically updated when we create a
    // new packet

    fsm->numTries = 0;
    aniAsfPacketEmptyExplicit(fsm->lastEapol, 
                              EAPOL_TX_HEADER_SIZE);

    checkTransition(fsm, arg);

    return ANI_OK;
}

// Use this only with trusted IE like the one we generated locally
static int
getRsnIeFromAdvertizedIes(tAuthRsnFsm *fsm, v_U8_t **rsnIe)
{
    int retVal = ANI_E_ILLEGAL_ARG;
    v_U8_t *ptr = fsm->advertizedRsnIe;

    if (*ptr == ANI_SSM_IE_RSN_ELEM_ID) 
    {
        retVal = *(ptr + 1) + 2; // The L field from the TLV + 2B TL
        *rsnIe = ptr;
    }

    return retVal;
}

// Use this only with trusted IE like the one we generated locally
static void
addPad( 
    v_U8_t *dataBytes,
    int dataLen,
    int padLen)
{
    int i;

    // The first byte of padding is 0xdd.  The rest are 0x00's
    // See 802.11i section 8.5.2 subsection "Key Data Encapsulation"

    for ( i=dataLen ; i < dataLen+padLen; i++) 
    {
        if ( i == dataLen ) 
        {
            dataBytes[i] = 0xdd;
        } 
        else {
            dataBytes[i] = 0x00;
        }
    }

    return;
}

/**
 * aagAppendGroupKeyForRsn
 *
 * Appends the group key to the packet in the RSN key encapulation format.
 *
 * @param packet - the packet to append to
 * @param radioId - the radio whose group key needs to be appended
 *
 * @return ANI_OK if the operation succeeds
 */
#define STATIC_WEP_KEY_LEN 16
#define GROUP_KEY_ID 0
#define ANI_SSM_IE_RSN_KEY_DATA_ENCAPS_ID       0xDD
#define ANI_SSM_IE_RSN_GROUP_KEY_DATA_ENCAPS_ID 1

int
aagAppendGroupKeyForRsn(tAniPacket *packet)
{
#if 0
    tAniPacket *groupKey = NULL;
#else
    tANI_U8 groupKey[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                          0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15};
#endif
    tANI_U8 *groupKeyBytes = NULL;
    tANI_U8 *lenPtr = NULL;
    tANI_U8 *endPtr = NULL;
    int groupKeyLen;
    int retVal;

#if 0
    groupKey = AAG_GROUP_KEY(radioId);
    if (groupKey == NULL) {
        ANI_AAG_LOG_E("Group key is not yet set on radio %d, id %d!",
                      radioId, AAG_GROUP_KEY_ID(radioId));
        assert(0 && "Group key is still NULL!");
        return ANI_E_FAILED;
    }

    groupKeyLen = aniAsfPacketGetBytes(groupKey, &groupKeyBytes);
    CHECK_NO_ERROR(groupKeyLen);

    if (aagConfig.logLevel >= LOG_INFO) {
        ANI_AAG_LOG_D("Will encapsulate group key bytes %s",
                      aniAsfHexStr(groupKeyBytes, groupKeyLen));
    }
#else
    groupKeyBytes = groupKey;

    groupKeyLen = STATIC_WEP_KEY_LEN;
#endif

    /*
     * Add the key data encapsulation needed for RSN/WPA2
     */

    // The IE ID
    retVal = aniAsfPacketAppend8(packet, ANI_SSM_IE_RSN_KEY_DATA_ENCAPS_ID);
    //CHECK_NO_ERROR(retVal);

    // Obtain the position for the length
    aniAsfPacketGetBytesFromTail(packet, &lenPtr);

    // Write out a dummy length - we'll fill this in later. It will be 
    // 6 bytes more than the length of the GTK
    retVal = aniAsfPacketAppend8(packet, 0);
    //CHECK_NO_ERROR(retVal);

    // Copy the RSN OUI
    retVal = aniAsfPacketAppendBuffer(packet, aniSsmIeRsnOui, sizeof(aniSsmIeRsnOui));
    //CHECK_NO_ERROR(retVal);

    // Indicate that the key type is group key
    retVal = aniAsfPacketAppend8(packet, ANI_SSM_IE_RSN_GROUP_KEY_DATA_ENCAPS_ID);
    //CHECK_NO_ERROR(retVal);
 
    // Copy the key-id to the first two bits of the next byte
    // Copy the Tx bit the third bit of the same byte
    // (Here, I assume the Group Key is to be used for both STA Tx and Rx)
    retVal = aniAsfPacketAppend8(
            packet,
            GROUP_KEY_ID );
            //AAG_GROUP_KEY_ID(radioId) );
    //CHECK_NO_ERROR(retVal);

    retVal = aniAsfPacketMoveRight(packet, 1); // Reserved bits (1 byte)
    //CHECK_NO_ERROR(retVal);

    // Copy the real key bytes
    retVal = aniAsfPacketAppendBuffer(packet, groupKeyBytes, groupKeyLen);
    //CHECK_NO_ERROR(retVal);
    
    // Calculate and enter the length of the entire encoding
    aniAsfPacketGetBytesFromTail(packet, &endPtr);
    *lenPtr = endPtr - (lenPtr + 1) ; // subtract one to avoid tail

    return retVal;
}

static int
gotoStatePtkInitNegoTx(tAuthRsnFsm *fsm)
{
    tAniEapolRsnKeyDesc txDesc;
    v_BOOL_t retransmit = eANI_BOOLEAN_FALSE;
    v_U8_t *rsnWpaIe = NULL;
    int rsnWpaIeLen;
    static tAniPacket *keyData;
    // The longest length...the extra 8 bytes account for RSN key data
    // encapsulation
    v_U8_t paddedGroupKeyEncaps[1024];
    int padLen = 0;
    v_U8_t *groupKeyBytes;
    int groupKeyLen;
    v_U8_t *wrappedKey = NULL;
    // Variables used for RC4 GTK wrap
    //v_U8_t keyIv[ANI_EAPOL_KEY_RSN_IV_SIZE];
    //v_U32_t keyIvLsb;
    int retVal = 0;

    //invalidate this
    fsm->msg4TimeOut = VOS_FALSE;
    fsm->currentState = PTK_INIT_NEGO_TX ;

    if (keyData == NULL) 
    {
        // Allocate the packet the first time around that you enter
        retVal = aniAsfPacketAllocateExplicit(&keyData, 1024, 10);
        if( !ANI_IS_STATUS_SUCCESS( retVal ) )
        {
            return retVal;
        }
    } 
    else {
        // Just empty out the packet
        aniAsfPacketEmptyExplicit(keyData, 10);
    }

    do
    {
        // Create a new EAPOL frame if we don't have one to retransmit
        //if (aniAsfPacketGetLen(fsm->lastEapol) == 0) 
#if 0
        if( fsm->lastEapol )
         {
             aniAsfPacketFree( fsm->lastEapol );
             fsm->lastEapol = NULL;

             retVal = aniAsfPacketAllocateExplicit(&fsm->lastEapol,
                                          RSN_MAX_PACKET_SIZE,
                                          EAPOL_TX_HEADER_SIZE );
#endif     
             aniAsfPacketEmptyExplicit(fsm->lastEapol, 
                              EAPOL_TX_HEADER_SIZE);
      //  }

        if (1) 
        {

            vos_mem_zero( &txDesc, sizeof(txDesc) );

            // The Key Information bits...
            if (fsm->staCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) 
            {
                txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES;
            } 
            else {
                txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_RC4;
            }
            txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE;
            txDesc.info.installFlag = eANI_BOOLEAN_TRUE;
            txDesc.info.ackFlag = eANI_BOOLEAN_TRUE;
            txDesc.info.micFlag = eANI_BOOLEAN_TRUE;

            txDesc.keyLen = aagGetKeyMaterialLen(fsm->staCtx->pwCipherType);
            aniSsmReplayCtrNext(fsm->staCtx->localReplayCtr, txDesc.replayCounter);
            vos_mem_copy(txDesc.keyNonce, fsm->aNonce, sizeof(txDesc.keyNonce));

            // Add the RSN IE (but not any WPA IE)
            rsnWpaIeLen = getRsnIeFromAdvertizedIes(fsm, &rsnWpaIe);

            if( !ANI_IS_STATUS_SUCCESS( rsnWpaIeLen) ) break;

            retVal = aniAsfPacketAppendBuffer(keyData, rsnWpaIe, rsnWpaIeLen);
            if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break;

            // Add the RSN group key encapsulation
            retVal = aagAppendGroupKeyForRsn ( keyData );

            if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break;

            groupKeyLen = aniAsfPacketGetBytes(keyData, &groupKeyBytes);
            if( !ANI_IS_STATUS_SUCCESS( groupKeyLen ) ) 
            {
                retVal = ANI_E_FAILED;
                break;
            }

            txDesc.info.secureFlag = eANI_BOOLEAN_TRUE;
            txDesc.info.encKeyDataFlag = eANI_BOOLEAN_TRUE;

            if ( fsm->staCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES ) 
            {
                /*
                 * Use the AES key wrap algorithm if either one of the pairwise
                 * key or the group key is an AES key.
                 *
                 * If the key being sent is not a multiple of
                 * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, then pad it with
                 * zeroes. e.g., if we are sending a WEP key of 5 or 13
                 * bytes.
                 */
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                           "AES Key Wrap invoked. groupKeyLen = %d", groupKeyLen);

                padLen = groupKeyLen % ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE;
                if (padLen != 0) {
                    padLen = ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE - padLen;
            
                    VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                               "Before AES Key Wrap: padLen = %d", padLen);

                    if (groupKeyLen + padLen > sizeof(paddedGroupKeyEncaps)) {
#if 0
                        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                                   "Cannot encode group key encapsulation of len %d and cipher type %s "
                                   "to send to %s %s (aid %d, radio %d, user %s)",
                                   groupKeyLen,
                                   aniSsmIntGetCipherStr(AAG_GROUP_CIPHER(fsm->ctx->radioId)),
                                   (fsm->ctx->bpIndicator ? "BP" : "STA"),
                                   aniAsfHexStr(fsm->ctx->suppMac, sizeof(tAniMacAddr)),
                                   fsm->ctx->aid,
                                   fsm->ctx->radioId,
                                   aagGetStaUserId(fsm->ctx));
#endif
                         retVal = ANI_E_FAILED;
                    }
                    // OK, after you compute the pad length, you need to 
                    // add the padding  - 0xdd followed by 0x00's
                    addPad( groupKeyBytes , groupKeyLen , padLen );
                    // add the padding length
                    groupKeyLen += padLen;
                    // IMMEDIATELY adjust the packet size to reflect the pad 
                    aniAsfPacketMoveRight(keyData, padLen); 
                    if( !ANI_IS_STATUS_SUCCESS( retVal) ) break;
                }
            
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                           "Before AES Key Wrap: padded groupKeyLen = %d", groupKeyLen);

                retVal = aniSsmAesKeyWrap(fsm->cryptHandle, groupKeyBytes, groupKeyLen,
                                          fsm->staCtx->ptk + ANI_EAPOL_KEY_RSN_MIC_SIZE,
                                          ANI_EAPOL_KEY_RSN_ENC_KEY_SIZE,
                                          &wrappedKey);
                if( !ANI_IS_STATUS_SUCCESS( retVal) ) break;
                // This doesn't work...
                //groupKeyBytes = wrappedKey;
                //groupKeyLen += ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE;
                // ...here is the right way to do it
                // Add the length of the prepended IV A[0]
                if (NULL == wrappedKey)
                {
                    break;
                }
                groupKeyLen += ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE;
                memcpy( groupKeyBytes, wrappedKey, groupKeyLen);
                // Free the array used to hold the wrapped key
                if (wrappedKey) vos_mem_free( wrappedKey);
                // IMMEDIATELY adjust the packet size to reflect the IV 
                aniAsfPacketMoveRight(keyData, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE);
            } 
            else {
            
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                    "Auth RC4 Key Wrap invoked. groupKeyLen = %d", groupKeyLen);
            }
            txDesc.keyDataLen = aniAsfPacketGetBytes(keyData, &txDesc.keyData);

            retVal = aniEapolWriteKey(fsm->cryptHandle,
                                      fsm->lastEapol,
                                      fsm->staCtx->suppMac,
                                      fsm->staCtx->authMac,
                                      ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW,
                                      &txDesc,
                                      fsm->staCtx->ptk,
                                      CSR_AES_KEY_LEN);
            if( !ANI_IS_STATUS_SUCCESS( retVal) ) break;
        } 
        else {
            retransmit = eANI_BOOLEAN_TRUE;
        }

        if( VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) )
        {
            retVal = ANI_OK;
        }
        else
        {
            //we fail to send the eapol frame disconnect
            bapAuthDisconnect( fsm->ctx );
            retVal = ANI_ERROR;
        }

    }while( 0 );

    return retVal;
}

static int
gotoStatePtkInitDone(tAuthRsnFsm *fsm, tAniEapolKeyAvailEventData *data)
{
    int retVal;
    tAniEapolRsnKeyDesc *rxDesc;
    tCsrRoamSetKey setKeyInfo;

    fsm->currentState = PTK_INIT_DONE;

    rxDesc = data->keyDesc;

    vos_mem_zero( &setKeyInfo, sizeof( tCsrRoamSetKey ) );
    setKeyInfo.encType = eCSR_ENCRYPT_TYPE_AES;
    setKeyInfo.keyDirection = eSIR_TX_RX;
    vos_mem_copy( setKeyInfo.peerMac, fsm->staCtx->suppMac, sizeof( tAniMacAddr ) );
    setKeyInfo.paeRole = 0; //this is a supplicant
    setKeyInfo.keyId = 0;   //always
    setKeyInfo.keyLength = CSR_AES_KEY_LEN; 
    vos_mem_copy( setKeyInfo.Key, (v_U8_t *)fsm->staCtx->ptk + (2 * CSR_AES_KEY_LEN ), CSR_AES_KEY_LEN );
    //fsm->suppCtx->ptk contains the 3 16-bytes keys. We need the last one.
    if( VOS_IS_STATUS_SUCCESS( bapSetKey( fsm->ctx->pvosGCtx, &setKeyInfo ) ) )
    {
        //Done
        aniAsfPacketEmptyExplicit(fsm->lastEapol, EAPOL_TX_HEADER_SIZE);
        retVal = ANI_OK;
    }
    else
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Auth: gotoStatePtkInitDone fail to set key\n" );
        retVal = ANI_ERROR;
    }

    return retVal;
}

static int
gotoStateUpdateKeysReq(tAuthRsnFsm *fsm, tAniEapolKeyAvailEventData *data)
{
    tAniEapolRsnKeyDesc *rxDesc;

    fsm->currentState = UPDATE_KEYS_REQ;

    rxDesc = data->keyDesc;

    aniSsmReplayCtrUpdate(fsm->staCtx->peerReplayCtr, rxDesc->replayCounter);

    checkTransition(fsm, data);

    return ANI_OK;
}

static int
gotoStateIntegFailure(tAuthRsnFsm *fsm, tSirMicFailureInfo *micFailureInfo)
{
    fsm->currentState = INTEG_FAILURE;

    fsm->integFailed = eANI_BOOLEAN_FALSE;

    checkTransition(fsm, NULL); // UCT

    return ANI_OK;
}

static int
gotoStateKeyUpdate(tAuthRsnFsm *fsm)
{
    fsm->currentState = KEY_UPDATE;

    if( VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes(fsm->cryptHandle, fsm->aNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE) ) )
    {

        // Replay counter will be automatically updated when we create a
        // new packet
        
        checkTransition(fsm, NULL); // UCT

        return ANI_OK;
    }
    return ANI_ERROR;
}

static int
gotoStateDisconnect(tAuthRsnFsm *fsm)
{
    fsm->currentState = DISCONNECT;

    //What else do we need to clean up? Or BAP will call our vleanup function?

    // FSM does not exist after this...
    bapAuthDisconnect( fsm->ctx );

    return ANI_OK;
}

static 
int zeroOutPtk(tAuthRsnFsm *fsm)
{
    return ANI_OK;
}

static 
int stopAllTimers(tAuthRsnFsm *fsm)
{
    vos_timer_stop( &fsm->msg2Timer );
    vos_timer_stop( &fsm->msg4Timer );

    return ANI_OK;
}

static
int derivePtk(tAuthRsnFsm *fsm, tAniEapolKeyAvailEventData *data)
{
    v_U32_t prfLen;
    tAniEapolRsnKeyDesc *rxDesc;

    VOS_ASSERT(fsm->staCtx->pmk);

    switch (fsm->staCtx->pwCipherType) 
    {
    case eCSR_ENCRYPT_TYPE_AES:
        prfLen = AAG_RSN_PTK_PRF_LEN_CCMP;
        break;
    default:
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
            "Auth cannot generate PTK for invalid algorithm %d\n",
                      fsm->staCtx->pwCipherType);
        return ANI_E_ILLEGAL_ARG;
        break;
    };

    rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc;
    return aagPtkPrf(fsm->cryptHandle,
                     fsm->staCtx->ptk,
                     prfLen,
                     fsm->staCtx->pmk,
                     fsm->staCtx->authMac,
                     fsm->staCtx->suppMac,
                     fsm->aNonce,
                     rxDesc->keyNonce);
}

static int 
checkMic(tAuthRsnFsm *fsm, 
         tAniEapolKeyAvailEventData *data)
{
    int retVal;

    retVal = aniEapolKeyCheckMic(fsm->cryptHandle,
                                 data->eapolFrame,
                                 ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW,
                                 data->keyDesc,
                                 fsm->staCtx->ptk,
                                 CSR_AES_KEY_LEN);

    if (retVal == ANI_E_MIC_FAILED) 
    {

        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                     "Auth failed EAPOL-MIC check in pairwise key exchange!\n"); 
    }

    return retVal;
}

static int 
checkLocalReplayCounter(tAuthRsnFsm *fsm, 
                        tAniEapolKeyAvailEventData *data)
{
    int retVal = ANI_E_NULL_VALUE;
    int cmp;
    tAniEapolRsnKeyDesc *rxDesc;
    
    rxDesc = data->keyDesc;
    if( rxDesc )
    {
        cmp = aniSsmReplayCtrCmp(fsm->staCtx->localReplayCtr, rxDesc->replayCounter);

        // The STA should have sent back the same replay ctr as in our request
        if (cmp != 0) 
        {
            retVal = ANI_E_REPLAY_CHECK_FAILED;
        }
        else
        {
            retVal = ANI_OK;
        }
    }

    return retVal;
}

static 
int checkPeerReplayCounter(tAuthRsnFsm *fsm, 
                           tAniEapolKeyAvailEventData *data)
{
    int retVal = ANI_E_NULL_VALUE;
    int cmp;
    tAniEapolRsnKeyDesc *rxDesc;
    
    rxDesc = data->keyDesc;
    if( rxDesc )
    {
        cmp = aniSsmReplayCtrCmp(fsm->staCtx->peerReplayCtr, rxDesc->replayCounter);

        // The STA should have sent a newer replay ctr than its old
        // request. The first message is exempted from the check.
        if (fsm->staCtx->pastFirstPeerRequest && cmp >= 0) 
        {
            retVal = ANI_E_REPLAY_CHECK_FAILED;
        }

        fsm->staCtx->pastFirstPeerRequest = eANI_BOOLEAN_TRUE;
    }

    return retVal;
}

static int checkInfoElement(tAuthRsnFsm *fsm,
                            tAniEapolKeyAvailEventData *data)
{
    tAniEapolRsnKeyDesc *desc;
    v_U8_t *ieStaBytes;
    int ieStaLen;

    desc = (tAniEapolRsnKeyDesc *) data->keyDesc;
    if( desc )
    {
        ieStaLen = aniAsfPacketGetBytes(fsm->staCtx->ieSta, &ieStaBytes);
        if( !ANI_IS_STATUS_SUCCESS( ieStaLen ) )
        {
            return ieStaLen;
        }

        if ((desc->keyDataLen != ieStaLen) ||
            ( !vos_mem_compare(desc->keyData, ieStaBytes, ieStaLen-2) )) 
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                         "Auth STA sent inconsistent RSN IE!\n");
            return ANI_E_FAILED;
        }
        // Copy RSN IE
        //vos_mem_copy(fsm->advertizedRsnIe, desc->keyData, ieStaLen);
        vos_mem_copy(fsm->advertizedRsnIe, ieStaBytes, ieStaLen);

        return ANI_OK;
    }
    else
    {
        return ANI_E_NULL_VALUE;
    }

}

static 
int checkTransition(tAuthRsnFsm *fsm, void *arg)
{
    int retVal;
    tAniEapolKeyAvailEventData *data;
    tAniEapolRsnKeyDesc *rxDesc;
    tSirMicFailureInfo *micFailureInfo;

    if (fsm->disconnect) 
    {
        stopAllTimers(fsm);
        gotoStateDisconnect(fsm);
        return ANI_OK;
    }

    if (fsm->authReq) 
    {
        stopAllTimers(fsm);
        gotoStateAuthentication(fsm);
        return ANI_OK;
    }

    switch (fsm->currentState) 
    {
    case INITIALIZE:
        break;
    case AUTHENTICATION:
        gotoStateAuthentication2(fsm);
        break;
    case AUTHENTICATION_2:
        gotoStateGetPsk( fsm );
        break;
    case GET_PSK:
        //We always have PMK otherwise BAP won't let us here
        gotoStatePtkStart(fsm);
        break;
    case PTK_START:
        if ( fsm->eapolAvail ) 
        {
            fsm->eapolAvail = eANI_BOOLEAN_FALSE;
            if (NULL == arg)
            {
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                           "arg is NULL, exiting checkTransition()");
                return ANI_E_FAILED;
            }
            data = (tAniEapolKeyAvailEventData *) arg;
            retVal = checkLocalReplayCounter(fsm, data);
            if (retVal != ANI_OK)
                return ANI_OK; // Caller should not fail
            retVal = derivePtk(fsm, data);
            if( !ANI_IS_STATUS_SUCCESS( retVal ) )
            {
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                         "Auth derivePtk failed with code %d!\n", retVal);
                return retVal;
            }
            retVal = checkMic(fsm, data);
            if (retVal != ANI_OK) 
            {
                bapAuthDisconnect( fsm->ctx );
                return retVal;
            }
            retVal = gotoStatePtkInitNego(fsm, arg);
        } 
        else if ( fsm->msg2TimeOut ) 
        {
            if (fsm->numTries <= authConsts.maxTries) 
            {
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                             "Auth Retransmitting EAPOL-Key Msg1\n");
                // Stay in the same state but repeat actions
                gotoStatePtkStart(fsm);
            } 
            else {
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                             "Auth failed to recv EAPOL-Key Msg2 "
                             "Disconnecting...\n");

                gotoStateDisconnect(fsm);
            }
        }
        break;
    case PTK_INIT_NEGO:
        if (NULL == arg)
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                       "arg is NULL, exiting checkTransition()");
            return ANI_E_FAILED;
        }
        data = (tAniEapolKeyAvailEventData *) arg;
        retVal = checkInfoElement(fsm, data);
        if (retVal != ANI_OK) 
        {
            gotoStateDisconnect(fsm);
        } 
        else {
            gotoStatePtkInitNegoTx(fsm);
        }
        break;
    case PTK_INIT_NEGO_TX:
        if (fsm->eapolAvail) 
        {
            fsm->eapolAvail = eANI_BOOLEAN_FALSE;
            if (NULL == arg)
            {
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                           "arg is NULL, exiting checkTransition()");
                return ANI_E_FAILED;
            }
            data = (tAniEapolKeyAvailEventData *) arg;
            retVal = checkLocalReplayCounter(fsm, data);
            if (retVal != ANI_OK)
                return ANI_OK; // Caller should not fail
            retVal = checkMic(fsm, data);
            if (retVal != ANI_OK) 
            {
                bapAuthDisconnect( fsm->ctx );
                return retVal;
            }
            retVal = gotoStatePtkInitDone(fsm, data);
        } else if ( fsm->msg4TimeOut ) 
        {
            if (fsm->numTries <= authConsts.maxTries) 
            {
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                             "Auth retransmitting EAPOL-Key Msg3 \n");
                // Stay in the same state but repeat actions
                gotoStatePtkInitNegoTx(fsm);
            } 
            else {
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                             "Auth failed to recv EAPOL-Key Msg4 "
                             "Disconnecting...\n" );

                gotoStateDisconnect(fsm);
            }
        }
        break;
    case PTK_INIT_DONE:
        if (fsm->eapolAvail) {

            fsm->eapolAvail = eANI_BOOLEAN_FALSE;
            if (NULL == arg)
            {
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                           "arg is NULL, exiting checkTransition()");
                return ANI_E_FAILED;
            }
            data = (tAniEapolKeyAvailEventData *) arg;
            rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc;

            if (rxDesc->info.requestFlag) 
            {

                retVal = checkPeerReplayCounter(fsm, data);
                if (retVal != ANI_OK)
                    return ANI_OK; // Caller should not fail

                retVal = checkMic(fsm, data);
                if (retVal != ANI_OK) 
                {
                    bapAuthDisconnect( fsm->ctx->pvosGCtx );
                    return retVal;
                }

                retVal = gotoStateUpdateKeysReq(fsm, arg);
            }
        } 
        else if (fsm->integFailed) {

            micFailureInfo = (tSirMicFailureInfo *) arg;
            gotoStateIntegFailure(fsm, arg);

        }
        break;
    case UPDATE_KEYS_REQ:

        if (NULL == arg)
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                       "arg is NULL, exiting checkTransition()");
            return ANI_E_FAILED;
        }
        data = (tAniEapolKeyAvailEventData *) arg;
        rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc;

        if (rxDesc->info.errorFlag) 
        {

            /*
             * This was generated by a unicast packet sent from the AP to the STA/BP.
             * The TX address is the AP's address. The src address is lost.
             * If the STA is a BP, then the true dst is lost. We will treat
             * the dst field as the address of the reporter of the MIC failure.
             */

            micFailureInfo = (tSirMicFailureInfo *) vos_mem_malloc( sizeof(tSirMicFailureInfo) );
            if( NULL == micFailureInfo )
            {
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                    "Fail to allocate memory for AuthRsnFsm: %d\n",
                      fsm->currentState);
                return ANI_E_MALLOC_FAILED;
            }

            vos_mem_copy(micFailureInfo->taMacAddr, fsm->staCtx->authMac, sizeof(tAniMacAddr));
            vos_mem_copy(micFailureInfo->dstMacAddr, fsm->staCtx->suppMac, sizeof(tAniMacAddr));
            micFailureInfo->multicast = eANI_BOOLEAN_FALSE;
            // Copy whatever sequence number came in the EAPOL-key message
            vos_mem_copy(micFailureInfo->TSC, rxDesc->keyRecvSeqCounter, SIR_CIPHER_SEQ_CTR_SIZE);
            gotoStateIntegFailure(fsm, micFailureInfo);
            vos_mem_free(micFailureInfo);
        } 
        else {
            // TBD: Untested. Why are local aNonce and local replyCtr not incremented in spec?
            gotoStatePtkStart(fsm);
        }
        break;
    case INTEG_FAILURE:
        gotoStateKeyUpdate(fsm);
        break;
    case KEY_UPDATE:
        gotoStatePtkStart(fsm);
        break;
    default:
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
            "Nothing to do in this state for AuthRsnFsm: %d\n",
                      fsm->currentState);
        // Catch all for states that need no change:
        //        assert(eANI_BOOLEAN_FALSE && "Illegal AuthRsnFsm state!");
        return ANI_E_FAILED;
    }

    return ANI_OK;
}


static void msg2TimerCallback( void *pv )
{
    tAuthRsnFsm *fsm = (tAuthRsnFsm *)pv;
    if (NULL == fsm) 
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                     "fsm is NULL in %s", __func__);

        return;
    }

    //Only when waiting for msg2
    if( PTK_START == fsm->currentState )
    {
        fsm->msg2TimeOut = eANI_BOOLEAN_TRUE;
    }
    //We may need to synchronize this call
    authRsnFsmProcessEvent( fsm, RSN_FSM_TIMER_EXPIRED, NULL );
}

static void msg4TimerCallback( void *pv )
{
    tAuthRsnFsm *fsm = (tAuthRsnFsm *)pv;
    if (NULL == fsm) 
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                     "fsm is NULL in %s", __func__);

        return;
    }

    //Only when we are waiting for msg4
    if( PTK_INIT_NEGO_TX == fsm->currentState )
    {
        fsm->msg4TimeOut = eANI_BOOLEAN_TRUE;
    }
    //We may need to synchronize this call
    authRsnFsmProcessEvent( fsm, RSN_FSM_TIMER_EXPIRED, NULL );
}


//
//This function alwasy assume the incoming vos_packet is 802_3 frame.
static int authRsnRxFrameHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket )
{
    int retVal = ANI_ERROR;
    tAniPacket *pAniPacket;
    tBtampContext *ctx;
    tAuthRsnFsm *fsm;

    /* Validate params */ 
    if ((pvosGCtx == NULL) || (NULL == pPacket))
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                     "param is NULL in %s", __func__);

        return retVal;
    }

    ctx = (tBtampContext *)VOS_GET_BAP_CB( pvosGCtx );
    if (NULL == ctx) 
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                     "ctx is NULL in %s", __func__);

        return retVal;
    }

    fsm = &ctx->uFsm.authFsm;
    if (NULL == fsm) 
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                     "fsm is NULL in %s", __func__);

        return retVal;
    }

    do
    {
        //ToDO: We need to synchronize this. For now, use the simplest form, drop the packet comes later.
        if( fsm->fReceiving )
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                " ******authRsnRxFrameHandler receive eapol packet while processing. Drop the new comer\n" );
            break;
        }
        fsm->fReceiving = VOS_TRUE;
        retVal = bapRsnFormPktFromVosPkt( &pAniPacket, pPacket );
        if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break;
        //Now we can process the eapol frame
        //handler will free the pAniPacket
        bapRsnEapolHandler( fsm, pAniPacket, VOS_TRUE );
    }while( 0 );

    fsm->fReceiving = VOS_FALSE;
    vos_pkt_return_packet( pPacket );

    return retVal;
}


static int authRsnTxCompleteHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus )
{
    tBtampContext *ctx = (tBtampContext *)VOS_GET_BAP_CB( pvosGCtx );
    tAuthRsnFsm *fsm;

    vos_pkt_return_packet( pPacket );
    if (NULL == ctx) 
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                     "ctx is NULL in %s", __func__);

        return ANI_ERROR;
    }

    fsm = &ctx->uFsm.authFsm;
    if (NULL == fsm) 
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                     "fsm is NULL in %s", __func__);

        return ANI_ERROR;
    }

    if(!VOS_IS_STATUS_SUCCESS( retStatus ) )
    {
        //No need to do anything. Retransmit is handled by timeout
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
            "Auth: TL Tx complete with error %d current state is %d \n", retStatus, fsm->currentState );
    }
    if( PTK_START == fsm->currentState )
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO,
            " Auth: start msg2 timer\n" );
        //Start msg2Timer
        fsm->numTries++;
        vos_timer_stop( &fsm->msg2Timer );
        vos_timer_start(&fsm->msg2Timer, authConsts.timeoutPeriod);
    }
    else if( ( PTK_INIT_NEGO == fsm->currentState ) || 
        ( PTK_INIT_NEGO_TX == fsm->currentState ) )
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO,
            " Auth: start msg4 timer\n" );
        fsm->numTries++;
        vos_timer_stop( &fsm->msg4Timer );
        vos_timer_start(&fsm->msg4Timer, authConsts.timeoutPeriod);
    }

    return ANI_OK;
}


static int
authEapolKeyHandler( tAuthRsnFsm *fsm, tAniPacket *eapolFrame, tAniMacAddr staMac )
{
    int retVal;

    int descType;
    void *keyDesc;
    tAniEapolRsnKeyDesc *rsnDesc;
    tAniEapolKeyAvailEventData data;

    do
    {
        retVal = aniEapolParseKey(eapolFrame, &descType, &keyDesc);
        if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break;

        if ((descType == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW) 
                || (descType == ANI_EAPOL_KEY_DESC_TYPE_RSN)) 
        {
            rsnDesc = (tAniEapolRsnKeyDesc *) keyDesc;
            data.keyDesc = keyDesc;
            data.eapolFrame = eapolFrame;
            // Pass on the event to the RSN FSM only if it is for a pairwise key
            if (rsnDesc->info.unicastFlag) 
            {
                retVal = authRsnFsmProcessEvent(fsm, 
                                                RSN_FSM_EAPOL_FRAME_AVAILABLE,
                                                &data);
            } 
            else {
                //Not worry about GTK stuff
            }
        } 
        else {

            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                    "Got unexpected legacy 802.1x RC4 Key message \n" );
            retVal = ANI_E_FAILED;
            break;
        }
    }while( 0 );

    aniEapolKeyFreeDesc(descType, keyDesc);
    return retVal;
}


void authEapolHandler( tAuthRsnFsm *fsm, tAniPacket *eapolFrame,
                 tAniMacAddr dstMac, 
                 tAniMacAddr srcMac,
                 v_U8_t *type)
{
    switch (*type) 
    {
    case ANI_EAPOL_TYPE_START:
        //No doing anything because we only support WPA2-PSK
        break;
    case ANI_EAPOL_TYPE_LOGOFF:
        //ignore
        break;
    case ANI_EAPOL_TYPE_KEY:
        authEapolKeyHandler(fsm, eapolFrame, srcMac);
        break;
    default:
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
            "Auth: EAPOL type not implemented: 0x%.2x\n", *type);
        break;
    }
}
