static int
gotoStateStaKeySet(tSuppRsnFsm *fsm, 
                   tAniEapolKeyAvailEventData *data,
                   v_BOOL_t retransmit)
{
    int retVal=0;
    tAniEapolRsnKeyDesc txDesc;
    tAniEapolRsnKeyDesc *rxDesc = NULL;
    
    fsm->currentState = STA_KEY_SET;

    if (data == NULL) 
    {
        // We don't need to do anything
        return ANI_OK;
    }
    
    // Create a new EAPOL frame if we don't have to retransmit
    if (!retransmit) 
    {
        // First check the IE that the AP sent
        retVal = checkInfoElement(fsm, data);
        if (retVal != ANI_OK) 
        {
            //FIX_RSN aagSetSuppFailureAndCleanup(fsm->suppCtx);

            // FSM does not exist after this...

            return retVal;
        }

        // Create a new EAPOL frame

        rxDesc = data->keyDesc;
        if( NULL == rxDesc )
            return ANI_E_NULL_VALUE;

        aniAsfPacketEmptyExplicit(fsm->lastEapol, 
                                  EAPOL_TX_HEADER_SIZE );

        vos_mem_zero( &txDesc, sizeof(txDesc) );

        // The Key Information bits...
        if (fsm->suppCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) 
        {
            txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES;
        }

        txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE;
        txDesc.info.micFlag = eANI_BOOLEAN_TRUE;
        txDesc.info.secureFlag = eANI_BOOLEAN_TRUE;
        txDesc.keyLen = 0; //RSN_80211_KEY_LEN;

        // Send back the same replayCtr that the authenticator sent
        vos_mem_copy(txDesc.replayCounter, 
               rxDesc->replayCounter, 
               sizeof(txDesc.replayCounter));

        retVal = aniEapolWriteKey(fsm->cryptHandle,
                                  fsm->lastEapol,
                                  fsm->suppCtx->authMac,
                                  fsm->suppCtx->suppMac,
                                  ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW,
                                  &txDesc,
                                  fsm->suppCtx->ptk,
                                  CSR_AES_KEY_LEN);
        if( !ANI_IS_STATUS_SUCCESS( retVal ) )
        {
            return retVal;
        }
    }
    gReadToSetKey = BAP_SET_RSN_KEY;
    if( !VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) )
    {
        /* making it global to access in bapTxRx file */
#if 0
        tCsrRoamSetKey setKeyInfo;


        vos_mem_zero( &setKeyInfo, sizeof( tCsrRoamSetKey ) );
        setKeyInfo.encType = eCSR_ENCRYPT_TYPE_AES;
        setKeyInfo.keyDirection = eSIR_TX_RX;
        vos_mem_copy( setKeyInfo.peerMac, fsm->suppCtx->authMac, 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->suppCtx->ptk + (2 * CSR_AES_KEY_LEN ), CSR_AES_KEY_LEN );
        //fsm->suppCtx->ptk contains the 3 16-bytes keys. We need the last one.
        /*
          We will move the Set key to EAPOL Completion handler. We found a race condition betweem
          sending EAPOL frame and setting Key */


        if( !VOS_IS_STATUS_SUCCESS( bapSetKey( fsm->ctx->pvosGCtx, &setKeyInfo ) ) )
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, " Supp: gotoStateStaKeySet fail to set key\n" );
            retVal = ANI_ERROR;
        }
#endif
        gReadToSetKey = BAP_RESET_RSN_KEY;
        retVal = ANI_ERROR;
    }

    return retVal;
}
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;
}