/*
 * Copyright (c) 2012-2013, 2017-2018, 2020 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/*
 * This file limProcessAssocReqFrame.cc contains the code
 * for processing Re/Association Request Frame.
 * Author:        Chandra Modumudi
 * Date:          03/18/02
 * History:-
 * Date           Modified by    Modification Information
 * --------------------------------------------------------------------
 * 05/26/10       js             WPA handling in (Re)Assoc frames
 *
 */
#include "palTypes.h"
#include "aniGlobal.h"
#include "wniCfg.h"
#include "sirApi.h"
#include "cfgApi.h"

#include "schApi.h"
#include "pmmApi.h"
#include "utilsApi.h"
#include "limTypes.h"
#include "limUtils.h"
#include "limAssocUtils.h"
#include "limSecurityUtils.h"
#include "limSerDesUtils.h"
#include "limStaHashApi.h"
#include "limAdmitControl.h"
#include "palApi.h"
#include "limSessionUtils.h"


#include "vos_types.h"

#define RSN_CAP_MFP_ENABLED     0x80

/**
 * limConvertSupportedChannels
 *
 *FUNCTION:
 * This function is called by limProcessAssocReqFrame() to
 * parse the channel support IE in the Assoc/Reassoc Request
 * frame, and send relevant information in the SME_ASSOC_IND
 *
 *NOTE:
 *
 * @param  pMac         - A pointer to Global MAC structure
 * @param  pMlmAssocInd - A pointer to SME ASSOC/REASSOC IND
 * @param  assocReq     - A pointer to ASSOC/REASSOC Request frame
 *
 * @return None
 */
static void
limConvertSupportedChannels(tpAniSirGlobal pMac,
                            tpLimMlmAssocInd pMlmAssocInd,
                            tSirAssocReq *assocReq)
{

    tANI_U16   i, j, index=0;
    tANI_U8    firstChannelNumber;
    tANI_U8    numberOfChannel;
    tANI_U8    nextChannelNumber;

    if(assocReq->supportedChannels.length >= SIR_MAX_SUPPORTED_CHANNEL_LIST)
    {
        limLog(pMac, LOG1, FL("Number of supported channels:%d is more than "
               "MAX"), assocReq->supportedChannels.length);
        pMlmAssocInd->supportedChannels.numChnl = 0;
        return;
    }

    for(i=0; i < (assocReq->supportedChannels.length); i++)
    {
        // Get First Channel Number
        firstChannelNumber = assocReq->supportedChannels.supportedChannels[i];
        pMlmAssocInd->supportedChannels.channelList[index] = firstChannelNumber;
        i++;
        index++;
        if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST)
        {
            pMlmAssocInd->supportedChannels.numChnl = 0;
            return;
        }
        // Get Number of Channels in a Subband
        numberOfChannel = assocReq->supportedChannels.supportedChannels[i];
        PELOG2(limLog(pMac, LOG2, FL("Rcv AssocReq: chnl=%d, numOfChnl=%d "),
                              firstChannelNumber, numberOfChannel);)

        if (numberOfChannel > 1)
        {
            nextChannelNumber = firstChannelNumber;
            if(SIR_BAND_5_GHZ == limGetRFBand(firstChannelNumber))
            {
                for (j=1; j < numberOfChannel; j++)
                {
                    nextChannelNumber += SIR_11A_FREQUENCY_OFFSET;
                    pMlmAssocInd->supportedChannels.channelList[index] = nextChannelNumber;
                    index++;
                    if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST)
                    {
                        pMlmAssocInd->supportedChannels.numChnl = 0;
                        return;
                    }
                }
            }
            else if(SIR_BAND_2_4_GHZ == limGetRFBand(firstChannelNumber))
            {
                for (j=1; j < numberOfChannel; j++)
                {
                    nextChannelNumber += SIR_11B_FREQUENCY_OFFSET;
                    pMlmAssocInd->supportedChannels.channelList[index] = nextChannelNumber;
                    index++;
                    if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST)
                    {
                        pMlmAssocInd->supportedChannels.numChnl = 0;
                        return;
                    }
                }
            }
        }
    }

    pMlmAssocInd->supportedChannels.numChnl = (tANI_U8) index;
   PELOG2(limLog(pMac, LOG2,
        FL("Send AssocInd to WSM: spectrum ON, minPwr %d, maxPwr %d, "
           "numChnl %d"),
        pMlmAssocInd->powerCap.minTxPower,
        pMlmAssocInd->powerCap.maxTxPower,
        pMlmAssocInd->supportedChannels.numChnl);)
}

void lim_process_assoc_cleanup(tpAniSirGlobal pMac, tpPESession psessionEntry,
                               tpSirAssocReq pAssocReq, tpDphHashNode pStaDs,
                               bool assoc_req_copied)
{
    tpSirAssocReq    pTempAssocReq;

    if (pAssocReq != NULL) {
        if (pAssocReq->assocReqFrame) {
                vos_mem_free(pAssocReq->assocReqFrame);
                pAssocReq->assocReqFrame = NULL;
                pAssocReq->assocReqFrameLength = 0;
        }
        vos_mem_free(pAssocReq);
        if (assoc_req_copied && pStaDs && psessionEntry->parsedAssocReq)
                /* to avoid double free */
                psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL;
    }

        /* If it is not duplicate Assoc request then only free the memory */
        if ((pStaDs != NULL) &&
            (pStaDs->mlmStaContext.mlmState != eLIM_MLM_WT_ADD_STA_RSP_STATE)) {
                if (psessionEntry->parsedAssocReq != NULL) {
                        pTempAssocReq =
                                psessionEntry->parsedAssocReq[pStaDs->assocId];
                        if (pTempAssocReq != NULL) {
                                if (pTempAssocReq->assocReqFrame) {
                                        vos_mem_free(
                                                pTempAssocReq->assocReqFrame);
                                        pTempAssocReq->assocReqFrame = NULL;
                                        pTempAssocReq->assocReqFrameLength = 0;
                                }
                                vos_mem_free(pTempAssocReq);
                                psessionEntry->parsedAssocReq[pStaDs->assocId] =
                                                                            NULL;
                        }
               }
        }
}

/**
 * lim_defer_sme_indication() - Defer assoc indication to SME
 * @mac_ctx: Pointer to Global MAC structure
 * @session: pe session entry
 * @sub_type: Indicates whether it is Association Request(=0) or Reassociation
 *	      Request(=1) frame
 * @hdr: A pointer to the MAC header
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @pmf_connection: flag indicating pmf connection
 * @assoc_req_copied: boolean to indicate if assoc req was copied to tmp above
 *
 * Defer Initialization of PE data structures and wait for an external event.
 * lim_send_assoc_ind_to_sme() will be called to initialize PE data structures
 * when the expected event is received.
 *
 * @Return: void
 */
static void lim_defer_sme_indication(tpAniSirGlobal mac_ctx,
                                    tpPESession session,
                                    uint8_t sub_type,
                                    tpSirMacMgmtHdr hdr,
                                    tpSirAssocReq assoc_req,
                                    bool pmf_connection,
                                    bool assoc_req_copied,
                                    tpDphHashNode sta_ds)
{
    struct tLimPreAuthNode  *sta_pre_auth_ctx;

    /* Extract pre-auth context for the STA, if any. */
    sta_pre_auth_ctx = limSearchPreAuthList(mac_ctx, hdr->sa);
    sta_pre_auth_ctx->assoc_req.present = true;
    sta_pre_auth_ctx->assoc_req.sub_type = sub_type;
    vos_mem_copy(&sta_pre_auth_ctx->assoc_req.hdr, hdr,
                    sizeof(tSirMacMgmtHdr));
    sta_pre_auth_ctx->assoc_req.assoc_req = assoc_req;
    sta_pre_auth_ctx->assoc_req.pmf_connection = pmf_connection;
    sta_pre_auth_ctx->assoc_req.assoc_req_copied = assoc_req_copied;
    sta_pre_auth_ctx->assoc_req.sta_ds = sta_ds;
}

/**
  * lim_check_sae_pmf_cap() - check pmf capability for SAE STA
  * @session: pointer to pe session entry
  * @rsn: pointer to RSN
  *
  * This function checks if SAE STA is pmf capable when SAE SAP is pmf
  * capable. Reject with eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION
  * if SAE STA is pmf disable.
  *
  * Return: mac_status_code
  */
#ifdef WLAN_FEATURE_SAE
static enum eSirMacStatusCodes lim_check_sae_pmf_cap(tpPESession session,
                                                    tDot11fIERSN *rsn)
{
    enum eSirMacStatusCodes status = eSIR_MAC_SUCCESS_STATUS;

    if (session->pLimStartBssReq->pmfCapable &&
        (rsn->RSN_Cap[0] & RSN_CAP_MFP_ENABLED) == 0)
            status = eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION_STATUS;

    return status;
}
#else
static enum eSirMacStatusCodes lim_check_sae_pmf_cap(tpPESession session,
                                                    tDot11fIERSN *rsn)
{
    return eSIR_MAC_SUCCESS_STATUS;
}
#endif

bool lim_send_assoc_ind_to_sme(tpAniSirGlobal pMac,
                            tpPESession psessionEntry,
                            uint8_t subType,
                            tpSirMacMgmtHdr pHdr,
                            tpSirAssocReq pAssocReq,
                            enum ani_akm_type akm_type,
                            bool pmfConnection,
                            bool *assoc_req_copied)
{
    uint16_t                    peerIdx;
    tANI_U8                     updateContext = false;
    tpDphHashNode               pStaDs;
    tHalBitVal                  qosMode;
    struct tLimPreAuthNode      *pStaPreAuthContext;
    tAniAuthType                authType;
    tANI_U16                    prevAuthSeqno = 0xFFFF;
    tHalBitVal                  wsmMode, wmeMode;
    tANI_U32                    val;
#ifdef WLAN_FEATURE_11W
    tPmfSaQueryTimerId          timerId;
    tANI_U32                    retryInterval;
#endif
    tLimMlmStates               mlmPrevState;

    limGetQosMode(psessionEntry, &qosMode);

    /**
     * Extract 'associated' context for STA, if any.
     * This is maintained by DPH and created by LIM.
     */
    pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &peerIdx, &psessionEntry->dph.dphHashTable);

    /// Extract pre-auth context for the STA, if any.
    pStaPreAuthContext = limSearchPreAuthList(pMac, pHdr->sa);

    if (pStaDs == NULL)
    {
        /// Requesting STA is not currently associated
        if (peGetCurrentSTAsCount(pMac) == pMac->lim.maxStation)
        {
               /**
                * Maximum number of STAs that AP can handle reached.
                * Send Association response to peer MAC entity
                */
                limLog(pMac, LOGE, FL("Max Sta count reached : %d"),
                        pMac->lim.maxStation);
                limRejectAssociation(pMac, pHdr->sa,
                                    subType, false,
                                    (tAniAuthType) 0, 0,
                                    false,
                                    (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS,
                                    psessionEntry);

                return false;
        }

        /// Check if STA is pre-authenticated.
        if ((pStaPreAuthContext == NULL) ||
            (pStaPreAuthContext &&
            (pStaPreAuthContext->mlmState !=
                                eLIM_MLM_AUTHENTICATED_STATE)))
        {
             /**
              * STA is not pre-authenticated yet requesting
              * Re/Association before Authentication.
              * OR STA is in the process of getting authenticated
              * and sent Re/Association request.
              * Send Deauthentication frame with 'prior
              * authentication required' reason code.
              */
              limSendDeauthMgmtFrame(pMac,
                            eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON, //=9
                            pHdr->sa, psessionEntry, FALSE);

              limLog(pMac, LOGE, FL("received %s req on sessionid: %d from STA "
                    "that does not have pre-auth context"MAC_ADDRESS_STR),
                    (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
                    psessionEntry->peSessionId,
                    MAC_ADDR_ARRAY(pHdr->sa));
                    return false;
        }

        /// Delete 'pre-auth' context of STA
        authType = pStaPreAuthContext->authType;
        if (pStaPreAuthContext->authType == eSIR_AUTH_TYPE_SAE)
            pAssocReq->is_sae_authenticated = true;

        /// Store the previous auth frame's seq no
        prevAuthSeqno = pStaPreAuthContext->seqNo;

        limDeletePreAuthNode(pMac, pHdr->sa);

        // All is well. Assign AID (after else part)

    } // if (pStaDs == NULL)
    else
    {
        // STA context does exist for this STA
        if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)
        {
            /**
             * Requesting STA is in some 'transient' state?
             * Ignore the Re/Assoc Req frame by incrementing
             * debug counter & logging error.
             */
            if (subType == LIM_ASSOC)
            {
#ifdef WLAN_DEBUG
                pMac->lim.gLimNumAssocReqDropInvldState++;
#endif
                limLog(pMac, LOGE, FL("received Assoc req in state "
                        "%d from "), pStaDs->mlmStaContext.mlmState);
            }
            else
            {
#ifdef WLAN_DEBUG
                pMac->lim.gLimNumReassocReqDropInvldState++;
#endif
                limLog(pMac, LOGE, FL("received ReAssoc req in state %d"
                        " from "), pStaDs->mlmStaContext.mlmState);
            }
            limPrintMacAddr(pMac, pHdr->sa, LOG1);
            limPrintMlmState(pMac, LOG1,
                            (tLimMlmStates) pStaDs->mlmStaContext.mlmState);

            return false;
        } // if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)

        /* STA sent association Request frame while already in
         * 'associated' state */

#ifdef WLAN_FEATURE_11W
        limLog(pMac, LOG1, FL("Re/Assoc request from station that is already associated"));
        limLog(pMac, LOG1, FL("PMF enabled %d, SA Query state %d"), pStaDs->rmfEnabled,
                pStaDs->pmfSaQueryState);
        if (pStaDs->rmfEnabled)
        {
            switch (pStaDs->pmfSaQueryState)
            {
                // start SA Query procedure, respond to Association Request
                // with try again later
                case DPH_SA_QUERY_NOT_IN_PROGRESS:
                       /*
                        * We should reset the retry counter before we start
                        * the SA query procedure, otherwise in next set of SA query
                        * procedure we will end up using the stale value.
                        */
                        pStaDs->pmfSaQueryRetryCount = 0;
                        limSendAssocRspMgmtFrame(pMac, eSIR_MAC_TRY_AGAIN_LATER, 1,
                                                pHdr->sa, subType, pStaDs,
                                                psessionEntry, NULL);
                        limSendSaQueryRequestFrame(pMac,
                                (tANI_U8 *)&(pStaDs->pmfSaQueryCurrentTransId),
                                pHdr->sa, psessionEntry);
                        pStaDs->pmfSaQueryStartTransId = pStaDs->pmfSaQueryCurrentTransId;
                        pStaDs->pmfSaQueryCurrentTransId++;

                        // start timer for SA Query retry
                        if (tx_timer_activate(&pStaDs->pmfSaQueryTimer) != TX_SUCCESS)
                        {
                            limLog(pMac, LOGE, FL("PMF SA Query timer activation failed!"));
                            return false;
                        }

                        pStaDs->pmfSaQueryState = DPH_SA_QUERY_IN_PROGRESS;
                        return false;

                // SA Query procedure still going, respond to Association
                // Request with try again later
                case DPH_SA_QUERY_IN_PROGRESS:
                        limSendAssocRspMgmtFrame(pMac, eSIR_MAC_TRY_AGAIN_LATER, 1,
                                                pHdr->sa, subType, 0, psessionEntry,
                                                NULL);
                        return false;

                // SA Query procedure timed out, accept Association Request
                // normally
                case DPH_SA_QUERY_TIMED_OUT:
                        pStaDs->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
                        break;
            }
        }
#endif
                /* no change in the capability so drop the frame */
                if ((VOS_TRUE == vos_mem_compare(&pStaDs->mlmStaContext.capabilityInfo,
                                                &pAssocReq->capabilityInfo,
                                                sizeof(tSirMacCapabilityInfo)))&&
                                                (subType == LIM_ASSOC))
                {
                    limLog(pMac, LOGE, FL(" Received Assoc req in state %d STAid=%d"),
                                            pStaDs->mlmStaContext.mlmState,peerIdx);
                    return false;
                }
                else
                {
                  /*
                   * STA sent Re/association Request frame while already in
                   * 'associated' state. Update STA capabilities and
                   * send Association response frame with same AID
                   */
                    limLog(pMac, LOG1, FL("Received Assoc req from STA already connected"
                                        " UpdateConext"));
                    pStaDs->mlmStaContext.capabilityInfo = pAssocReq->capabilityInfo;
                    if (pStaPreAuthContext &&
                        (pStaPreAuthContext->mlmState ==
                                                eLIM_MLM_AUTHENTICATED_STATE))
                    {
                        /// STA has triggered pre-auth again
                        authType = pStaPreAuthContext->authType;
                        limDeletePreAuthNode(pMac, pHdr->sa);
                    }
                    else
                        authType = pStaDs->mlmStaContext.authType;

                    updateContext = true;
                    if (dphInitStaState(pMac, pHdr->sa, peerIdx, true, &psessionEntry->dph.dphHashTable)
                                            == NULL)
                    {
                        limLog(pMac, LOGE, FL("could not Init STAid=%d"), peerIdx);
                        return false;
                    }
                }
                goto sendIndToSme;
            } // end if (lookup for STA in perStaDs fails)

            // check if sta is allowed per QoS AC rules
            //if (pMac->dph.gDphQosEnabled || pMac->dph.gDphWmeEnabled)
            limGetWmeMode(psessionEntry, &wmeMode);
            if ((qosMode == eHAL_SET) || (wmeMode == eHAL_SET))
            {
                // for a qsta, check if the requested Traffic spec
                // is admissible
                // for a non-qsta check if the sta can be admitted
                if (pAssocReq->addtsPresent)
                {
                    tANI_U8 tspecIdx = 0; //index in the sch tspec table.
                    if (limAdmitControlAddTS(pMac, pHdr->sa, &(pAssocReq->addtsReq),
                                              &(pAssocReq->qosCapability), 0,
                                              false, NULL, &tspecIdx, psessionEntry) != eSIR_SUCCESS)
                    {
                        limLog(pMac, LOGE, FL("AdmitControl: TSPEC rejected"));
                        limSendAssocRspMgmtFrame(
                                        pMac,
                                        eSIR_MAC_QAP_NO_BANDWIDTH_REASON,
                                        1,
                                        pHdr->sa,
                                        subType, 0,psessionEntry, NULL);
#ifdef WLAN_DEBUG
                        pMac->lim.gLimNumAssocReqDropACRejectTS++;
#endif
                        return false;
                    }
                }
                else if (limAdmitControlAddSta(pMac, pHdr->sa, false)
                                                != eSIR_SUCCESS)
                {
                    limLog(pMac, LOGE, FL("AdmitControl: Sta rejected"));
                    limSendAssocRspMgmtFrame(
                            pMac,
                            eSIR_MAC_QAP_NO_BANDWIDTH_REASON,
                            1,
                            pHdr->sa,
                            subType, 0,psessionEntry, NULL);
#ifdef WLAN_DEBUG
                    pMac->lim.gLimNumAssocReqDropACRejectSta++;
#endif
                    return false;
                }

                // else all ok
                limLog(pMac, LOG1, FL("AdmitControl: Sta OK!"));
            }

            /**
             * STA is Associated !
             */
            limLog(pMac, LOGE, FL("Received %s Req  successful from "MAC_ADDRESS_STR),
            (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", MAC_ADDR_ARRAY(pHdr->sa));

            /**
             * AID for this association will be same as the peer Index used in DPH table.
             * Assign unused/least recently used peer Index from perStaDs.
             * NOTE: limAssignPeerIdx() assigns AID values ranging
             * between 1 - cfg_item(WNI_CFG_ASSOC_STA_LIMIT)
             */

            peerIdx = limAssignPeerIdx(pMac, psessionEntry);
            if (!peerIdx)
            {
                // Could not assign AID
                // Reject association
                limLog(pMac, LOGE, FL("PeerIdx not avaialble. Reject associaton"));

                limRejectAssociation(pMac, pHdr->sa,
                                    subType, true, authType,
                                    peerIdx, false,
                                    (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);

                return false;
            }
            /**
             * Add an entry to hash table maintained by DPH module
             */
            pStaDs = dphAddHashEntry(pMac, pHdr->sa, peerIdx, &psessionEntry->dph.dphHashTable);

            if (pStaDs == NULL)
            {
                // Could not add hash table entry at DPH
                limLog(pMac, LOGE,
                    FL("could not add hash entry at DPH for aid=%d, MacAddr:"
                    MAC_ADDRESS_STR),
                    peerIdx,MAC_ADDR_ARRAY(pHdr->sa));

                // Release AID
                limReleasePeerIdx(pMac, peerIdx, psessionEntry);

                limRejectAssociation(pMac, pHdr->sa,
                                    subType, true, authType, peerIdx, false,
                                    (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);
                return false;
            }

            /// Store the previous auth frame's seq no
            if (prevAuthSeqno != 0xFFFF)
            {
                pStaDs->PrevAuthSeqno = prevAuthSeqno;
            }
            /// Store the current assoc seq no
            pStaDs->PrevAssocSeqno = ((pHdr->seqControl.seqNumHi << 4) |
                                    (pHdr->seqControl.seqNumLo));
            limLog(pMac, LOG1, FL("Prev auth seq no %d Prev Assoc seq no. %d"),
                    pStaDs->PrevAuthSeqno, pStaDs->PrevAssocSeqno);

        sendIndToSme:

            psessionEntry->parsedAssocReq[pStaDs->assocId] = pAssocReq;
            pStaDs->mlmStaContext.htCapability = pAssocReq->HTCaps.present;
#ifdef WLAN_FEATURE_11AC
            pStaDs->mlmStaContext.vhtCapability = pAssocReq->VHTCaps.present;
#endif
            pStaDs->qos.addtsPresent = (pAssocReq->addtsPresent==0) ? false : true;
            pStaDs->qos.addts	     = pAssocReq->addtsReq;
            pStaDs->qos.capability   = pAssocReq->qosCapability;
            pStaDs->versionPresent   = 0;
            /* short slot and short preamble should be updated before doing limaddsta */
            pStaDs->shortPreambleEnabled = (tANI_U8)pAssocReq->capabilityInfo.shortPreamble;
            pStaDs->shortSlotTimeEnabled = (tANI_U8)pAssocReq->capabilityInfo.shortSlotTime;

            if (pAssocReq->propIEinfo.versionPresent) //update STA version info
            {
                pStaDs->versionPresent = 1;
                pStaDs->version = pAssocReq->propIEinfo.version;
            }
            pStaDs->propCapability = 0;
            if (pAssocReq->propIEinfo.capabilityPresent)
            {
                if (sirGetCfgPropCaps(pMac, &pStaDs->propCapability))
                    pStaDs->propCapability &= pAssocReq->propIEinfo.capability;
            }

            pStaDs->valid = 0;
            pStaDs->mlmStaContext.authType = authType;
            pStaDs->mlmStaContext.akm_type = akm_type;
            pStaDs->staType = STA_ENTRY_PEER;

            limLog(pMac, LOGE, FL("auth_type = %d, akm_type = %d"),
                    authType, akm_type);

            //TODO: If listen interval is more than certain limit, reject the association.
            //Need to check customer requirements and then implement.
            pStaDs->mlmStaContext.listenInterval = pAssocReq->listenInterval;
            pStaDs->mlmStaContext.capabilityInfo = pAssocReq->capabilityInfo;

            /* The following count will be used to knock-off the station if it doesn't
             * come back to receive the buffered data. The AP will wait for numTimSent number
             * of beacons after sending TIM information for the station, before assuming that
             * the station is no more associated and disassociates it
             */

            /** timWaitCount is used by PMM for monitoring the STA's in PS for LINK*/
            pStaDs->timWaitCount = (tANI_U8)GET_TIM_WAIT_COUNT(pAssocReq->listenInterval);

            /** Initialise the Current successful MPDU's tranfered to this STA count as 0 */
            pStaDs->curTxMpduCnt = 0;

            if(IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
                (pAssocReq->HTCaps.present))
            {
                pStaDs->htGreenfield = (tANI_U8)pAssocReq->HTCaps.greenField;
                pStaDs->htAMpduDensity = pAssocReq->HTCaps.mpduDensity;
                pStaDs->htDsssCckRate40MHzSupport = (tANI_U8)pAssocReq->HTCaps.dsssCckMode40MHz;
                pStaDs->htLsigTXOPProtection = (tANI_U8)pAssocReq->HTCaps.lsigTXOPProtection;
                pStaDs->htMaxAmsduLength = (tANI_U8)pAssocReq->HTCaps.maximalAMSDUsize;
                pStaDs->htMaxRxAMpduFactor = pAssocReq->HTCaps.maxRxAMPDUFactor;
                pStaDs->htMIMOPSState = pAssocReq->HTCaps.mimoPowerSave;

                /* pAssocReq will be copied to psessionEntry->parsedAssocReq later */
                /* check whether AP is enabled with shortGI */
                if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_20MHZ, &val) !=
                                    eSIR_SUCCESS) {
                    limLog(pMac, LOGE,
                            FL("could not retrieve shortGI 20Mhz CFG"));
                    return false;
                }
                if (val) {
                    pStaDs->htShortGI20Mhz = (tANI_U8)pAssocReq->HTCaps.shortGI20MHz;
                } else {
                    /* Unset htShortGI20Mhz in ht_caps*/
                    pAssocReq->HTCaps.shortGI20MHz = 0;
                    pStaDs->htShortGI20Mhz = 0;
                }

                if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_40MHZ, &val) !=
                                    eSIR_SUCCESS) {
                    limLog(pMac, LOGE,
                                FL("could not retrieve shortGI 40Mhz CFG"));
                    return false;
                }
                if (val) {
                    pStaDs->htShortGI40Mhz = (tANI_U8)pAssocReq->HTCaps.shortGI40MHz;
                } else {
                    /* Unset htShortGI40Mhz in ht_caps */
                    pAssocReq->HTCaps.shortGI40MHz = 0;
                    pStaDs->htShortGI40Mhz = 0;
                }
                pStaDs->htSupportedChannelWidthSet = (tANI_U8)pAssocReq->HTCaps.supportedChannelWidthSet;
                /* peer just follows AP; so when we are softAP/GO, we just store our session entry's secondary channel offset here in peer INFRA STA
                 * However, if peer's 40MHz channel width support is disabled then secondary channel will be zero
                 */
                pStaDs->htSecondaryChannelOffset = (pStaDs->htSupportedChannelWidthSet)?psessionEntry->htSecondaryChannelOffset:0;
#ifdef WLAN_FEATURE_11AC
                if(pAssocReq->operMode.present)
                {
                    pStaDs->vhtSupportedChannelWidthSet = (tANI_U8)((pAssocReq->operMode.chanWidth == eHT_CHANNEL_WIDTH_80MHZ) ? WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ : WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ);
                    pStaDs->htSupportedChannelWidthSet	= (tANI_U8)(pAssocReq->operMode.chanWidth ? eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ);
                }
                else if (pAssocReq->VHTCaps.present)
                {
                    // Check if STA has enabled it's channel bonding mode.
                    // If channel bonding mode is enabled, we decide based on SAP's current configuration.
                    // else, we set it to VHT20.
                    pStaDs->vhtSupportedChannelWidthSet = (tANI_U8)((pStaDs->htSupportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) ?
                                                            WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ :
                                                            psessionEntry->vhtTxChannelWidthSet );
                }

                // Lesser among the AP and STA bandwidth of operation.
                pStaDs->htSupportedChannelWidthSet =
                        (pStaDs->htSupportedChannelWidthSet < psessionEntry->htSupportedChannelWidthSet) ?
                        pStaDs->htSupportedChannelWidthSet : psessionEntry->htSupportedChannelWidthSet ;

#endif
                pStaDs->baPolicyFlag = 0xFF;
                pStaDs->htLdpcCapable = (tANI_U8)pAssocReq->HTCaps.advCodingCap;
            }

            if(pAssocReq->VHTCaps.present)
            {
                pStaDs->vhtLdpcCapable = (tANI_U8)pAssocReq->VHTCaps.ldpcCodingCap;
            }

#ifdef WLAN_FEATURE_11AC
            if (limPopulateMatchingRateSet(pMac,
                                        pStaDs,
                                        &(pAssocReq->supportedRates),
                                        &(pAssocReq->extendedRates),
                                        pAssocReq->HTCaps.supportedMCSSet,
                                        &(pAssocReq->propIEinfo.propRates),
                                        psessionEntry , &pAssocReq->VHTCaps)
                                        != eSIR_SUCCESS)
#else
            if (limPopulateMatchingRateSet(pMac,
                                        pStaDs,
                                        &(pAssocReq->supportedRates),
                                        &(pAssocReq->extendedRates),
                                        pAssocReq->HTCaps.supportedMCSSet,
                                        &(pAssocReq->propIEinfo.propRates), psessionEntry) != eSIR_SUCCESS)
#endif
            {
                // Could not update hash table entry at DPH with rateset
                limLog(pMac, LOGE,
                    FL("could not update hash entry at DPH for aid=%d, MacAddr: "
                    MAC_ADDRESS_STR),
                    peerIdx, MAC_ADDR_ARRAY(pHdr->sa));

                // Release AID
                limReleasePeerIdx(pMac, peerIdx, psessionEntry);
                limRejectAssociation(pMac, pHdr->sa,
                                    subType, true, authType, peerIdx, true,
                                    (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);

                pAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId];
                return false;
            }

            vos_mem_copy((tANI_U8 *) &pStaDs->mlmStaContext.propRateSet,
                        (tANI_U8 *) &(pAssocReq->propIEinfo.propRates),
                        pAssocReq->propIEinfo.propRates.numPropRates + 1);

            /// Add STA context at MAC HW (BMU, RHP & TFP)

            pStaDs->qosMode    = eANI_BOOLEAN_FALSE;
            pStaDs->lleEnabled = eANI_BOOLEAN_FALSE;
            if (pAssocReq->capabilityInfo.qos && (qosMode == eHAL_SET))
            {
                pStaDs->lleEnabled = eANI_BOOLEAN_TRUE;
                pStaDs->qosMode    = eANI_BOOLEAN_TRUE;
            }

            pStaDs->wmeEnabled = eANI_BOOLEAN_FALSE;
            pStaDs->wsmEnabled = eANI_BOOLEAN_FALSE;
            limGetWmeMode(psessionEntry, &wmeMode);
            //if ((! pStaDs->lleEnabled) && assoc.wmeInfoPresent && pMac->dph.gDphWmeEnabled)
            if ((! pStaDs->lleEnabled) && pAssocReq->wmeInfoPresent && (wmeMode == eHAL_SET))
            {
                pStaDs->wmeEnabled = eANI_BOOLEAN_TRUE;
                pStaDs->qosMode = eANI_BOOLEAN_TRUE;
                limGetWsmMode(psessionEntry, &wsmMode);
                /* WMM_APSD - WMM_SA related processing should be separate; WMM_SA and WMM_APSD
                can coexist */
                if( pAssocReq->WMMInfoStation.present)
                {
                    /* check whether AP supports or not */
                    if ((psessionEntry->limSystemRole == eLIM_AP_ROLE)
                        && (psessionEntry->apUapsdEnable == 0) && (pAssocReq->WMMInfoStation.acbe_uapsd
                            || pAssocReq->WMMInfoStation.acbk_uapsd
                            || pAssocReq->WMMInfoStation.acvo_uapsd
                            || pAssocReq->WMMInfoStation.acvi_uapsd))
                    {
                        /**
                         * Received Re/Association Request from
                         * STA when UPASD is not supported.
                         */
                        limLog( pMac, LOGE, FL( "AP do not support UAPSD so reply "
                                "to STA accordingly" ));
                        /* update UAPSD and send it to LIM to add STA */
                        pStaDs->qos.capability.qosInfo.acbe_uapsd = 0;
                        pStaDs->qos.capability.qosInfo.acbk_uapsd = 0;
                        pStaDs->qos.capability.qosInfo.acvo_uapsd = 0;
                        pStaDs->qos.capability.qosInfo.acvi_uapsd = 0;
                        pStaDs->qos.capability.qosInfo.maxSpLen =   0;
                    }
                    else
                    {
                        /* update UAPSD and send it to LIM to add STA */
                        pStaDs->qos.capability.qosInfo.acbe_uapsd = pAssocReq->WMMInfoStation.acbe_uapsd;
                        pStaDs->qos.capability.qosInfo.acbk_uapsd = pAssocReq->WMMInfoStation.acbk_uapsd;
                        pStaDs->qos.capability.qosInfo.acvo_uapsd = pAssocReq->WMMInfoStation.acvo_uapsd;
                        pStaDs->qos.capability.qosInfo.acvi_uapsd = pAssocReq->WMMInfoStation.acvi_uapsd;
                        pStaDs->qos.capability.qosInfo.maxSpLen = pAssocReq->WMMInfoStation.max_sp_length;
                    }
                }
                //if (assoc.wsmCapablePresent && pMac->dph.gDphWsmEnabled)
                if (pAssocReq->wsmCapablePresent && (wsmMode == eHAL_SET))
                    pStaDs->wsmEnabled = eANI_BOOLEAN_TRUE;
            }

            // Re/Assoc Response frame to requesting STA
            pStaDs->mlmStaContext.subType = subType;

            if (pAssocReq->propIEinfo.aniIndicator)
                pStaDs->aniPeer = 1;

#ifdef WLAN_FEATURE_11W
            pStaDs->rmfEnabled = (pmfConnection) ? 1 : 0;
            pStaDs->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
            timerId.fields.sessionId = psessionEntry->peSessionId;
            timerId.fields.peerIdx = peerIdx;
            if (wlan_cfgGetInt(pMac, WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
                    &retryInterval) != eSIR_SUCCESS)
            {
                limLog(pMac, LOGE, FL("Could not retrieve PMF SA Query retry interval value"));
                limRejectAssociation(pMac, pHdr->sa,
                                    subType, true, authType,
                                    peerIdx, false,
                                    (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);
                return false;
            }
            if (WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMIN > retryInterval)
            {
                retryInterval = WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STADEF;
            }
            if (tx_timer_create(&pStaDs->pmfSaQueryTimer, "PMF SA Query timer",
                                limPmfSaQueryTimerHandler, timerId.value,
                                SYS_MS_TO_TICKS((retryInterval * 1024) / 1000),
                                0, TX_NO_ACTIVATE) != TX_SUCCESS)
            {
                limLog(pMac, LOGE, FL("could not create PMF SA Query timer"));
                limRejectAssociation(pMac, pHdr->sa,
                                    subType, true, authType,
                                    peerIdx, false,
                                    (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);
                return false;
            }
#endif
            // BTAMP: Storing the parsed assoc request in the psessionEntry array
            psessionEntry->parsedAssocReq[pStaDs->assocId] = pAssocReq;

            /* BTAMP: If STA context already exist (ie. updateContext = 1)
             * for this STA, then we should delete the old one, and add
             * the new STA. This is taken care of in the limDelSta() routine.
             *
             * Prior to BTAMP, we were setting this flag so that when
             * PE receives SME_ASSOC_CNF, and if this flag is set, then
             * PE shall delete the old station and then add. But now in
             * BTAMP, we're directly adding station before waiting for
             * SME_ASSOC_CNF, so we can do this now.
             */
            if (!updateContext)
            {
                pStaDs->mlmStaContext.updateContext = 0;
                // BTAMP: Add STA context at HW - issue WDA_ADD_STA_REQ to HAL
                if (limAddSta(pMac, pStaDs, false, psessionEntry) != eSIR_SUCCESS)
                {
                    limLog(pMac, LOGE, FL("could not Add STA with assocId=%d"),
                            pStaDs->assocId);
                    limRejectAssociation( pMac, pStaDs->staAddr, pStaDs->mlmStaContext.subType,
                            true, pStaDs->mlmStaContext.authType, pStaDs->assocId, true,
                            (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);
                    pAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId];
                    return false;
                }
            }
            else
            {
                pStaDs->mlmStaContext.updateContext = 1;
                mlmPrevState = pStaDs->mlmStaContext.mlmState;

                /* As per the HAL/FW needs the reassoc req need not be calling limDelSta */
                if(subType != LIM_REASSOC)
                {
                    //we need to set the mlmState here in order differentiate in limDelSta.
                    pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE;
                    if(limDelSta(pMac, pStaDs, true, psessionEntry) != eSIR_SUCCESS)
                    {
                        limLog(pMac, LOGE, FL("could not DEL STA with assocId=%d staId %d"),
                                pStaDs->assocId, pStaDs->staIndex);
                        limRejectAssociation( pMac, pStaDs->staAddr, pStaDs->mlmStaContext.subType, true, pStaDs->mlmStaContext.authType,
                                pStaDs->assocId, true,(tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);
                        //Restoring the state back.
                        pStaDs->mlmStaContext.mlmState = mlmPrevState;
                        pAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId];
                        return false;
                    }
                }
                else
                {
                    /* mlmState is changed in limAddSta context */
                    /* use the same AID, already allocated */
                    if (limAddSta(pMac, pStaDs, false, psessionEntry) != eSIR_SUCCESS)
                    {
                            limLog(pMac, LOGE, FL( "Could not AddSta with assocId= %d staId %d"),
                                    pStaDs->assocId, pStaDs->staIndex);
                            limRejectAssociation( pMac, pStaDs->staAddr, pStaDs->mlmStaContext.subType, true, pStaDs->mlmStaContext.authType,
                                    pStaDs->assocId, true,(tSirResultCodes) eSIR_MAC_WME_REFUSED_STATUS, psessionEntry);
                            //Restoring the state back.
                            pStaDs->mlmStaContext.mlmState = mlmPrevState;
                            pAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId];
                            return false;
                    }
                }
            }
    return true;
}

/**---------------------------------------------------------------
\fn     limProcessAssocReqFrame
\brief  This function is called by limProcessMessageQueue()
\       upon Re/Association Request frame reception in
\       BTAMP AP or Soft AP role.
\
\param pMac
\param *pRxPacketInfo    - A pointer to Buffer descriptor + associated PDUs
\param subType - Indicates whether it is Association Request(=0)
\                or Reassociation Request(=1) frame
\return None
------------------------------------------------------------------*/
void
limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
                        tANI_U8 subType, tpPESession psessionEntry)
{
    tANI_U8                 *pBody;
    tANI_U16                peerIdx, temp;
    tANI_U32                val;
    tANI_S32                framelen;
    tSirRetStatus           status;
    tpSirMacMgmtHdr         pHdr;
    struct tLimPreAuthNode  *pStaPreAuthContext;
    tSirMacCapabilityInfo   localCapabilities;
    tpDphHashNode           pStaDs = NULL;
    tpSirAssocReq           pAssocReq;
    tDot11fIERSN            Dot11fIERSN;
    tDot11fIEWPA            Dot11fIEWPA;
    tANI_U32 phyMode;
    tHalBitVal qosMode;
#ifdef WMM_APSD
    tHalBitVal              wmeMode;
#endif
    tANI_U8    *wpsIe = NULL;
    tSirMacRateSet  basicRates;
    tANI_U8 i = 0, j = 0;
    tANI_BOOLEAN pmfConnection = eANI_BOOLEAN_FALSE;
    bool assoc_req_copied = false;
    enum ani_akm_type akm_type = ANI_AKM_TYPE_NONE;

    limGetPhyMode(pMac, &phyMode, psessionEntry);

    limGetQosMode(psessionEntry, &qosMode);

    pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
    framelen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);

    limLog(pMac, LOG1, FL("Received %s Req Frame on sessionid: %d systemrole %d"
          " limMlmState %d from: "MAC_ADDRESS_STR),
          (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
          psessionEntry->peSessionId, psessionEntry->limSystemRole,
          psessionEntry->limMlmState, MAC_ADDR_ARRAY(pHdr->sa));

    if (psessionEntry->limSystemRole == eLIM_STA_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE )
    {
        limLog(pMac, LOGE, FL("received unexpected ASSOC REQ on sessionid: %d "
              "sys subType=%d for role=%d from: "MAC_ADDRESS_STR),
              psessionEntry->peSessionId,
              subType, psessionEntry->limSystemRole, MAC_ADDR_ARRAY(pHdr->sa));
        sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3,
        WDA_GET_RX_MPDU_DATA(pRxPacketInfo), framelen);
        return;
    }
    /*
     * If a STA is already present in DPH and it
     * is initiating a Assoc re-transmit, do not
     * process it. This can happen when first Assoc Req frame
     * is received but ACK lost at STA side. The ACK for this
     * dropped Assoc Req frame should be sent by HW. Host simply
     * does not process it once the entry for the STA is already
     * present in DPH.
     */
    pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &peerIdx,
                             &psessionEntry->dph.dphHashTable);
    if (NULL != pStaDs)
    {
        if (pStaDs->PrevAssocSeqno == ((pHdr->seqControl.seqNumHi << 4) |
                                        (pHdr->seqControl.seqNumLo)))
        {
            /* Ignore the Retry */
            limLog(pMac, LOGE,
                    FL("STA is initiating Assoc Req after ACK lost. "
                        "So, do not Process sessionid: %d sys subType=%d "
                        "for role=%d from: "MAC_ADDRESS_STR),
                    psessionEntry->peSessionId, subType,
                    psessionEntry->limSystemRole,
                    MAC_ADDR_ARRAY(pHdr->sa));
            return;
        }
        else
        {
#ifdef WLAN_FEATURE_11W
            /* Do not send Assoc rsp for duplicate assoc req in case of PMF
             * enabled STA, as driver needs to start SA Querry in this case
             */
            if (!pStaDs->rmfEnabled)
#endif
            {
               /* STA might have missed the assoc response,
                * so it is sending assoc request frame again.
                */
                limSendAssocRspMgmtFrame( pMac, eSIR_SUCCESS,
                    pStaDs->assocId, pStaDs->staAddr,
                    pStaDs->mlmStaContext.subType, pStaDs,
                    psessionEntry, NULL);
                limLog(pMac, LOGE,
                    FL("DUT already received an assoc request frame "
                        "and STA is sending another assoc req.So, do not "
                        "Process sessionid: %d sys subType=%d for role=%d "
                        "from: "MAC_ADDRESS_STR),
                    psessionEntry->peSessionId, subType,
                    psessionEntry->limSystemRole,
                    MAC_ADDR_ARRAY(pHdr->sa));
                return;
            }
        }
    }

    // Get pointer to Re/Association Request frame body
    pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);

    if (limIsGroupAddr(pHdr->sa))
    {
        // Received Re/Assoc Req frame from a BC/MC address
        // Log error and ignore it
        limLog(pMac, LOGE, FL("Received %s Req on sessionid: %d frame from a "
        "BC/MC address"MAC_ADDRESS_STR),
        (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
        psessionEntry->peSessionId,
        MAC_ADDR_ARRAY(pHdr->sa));
        return;
    }

    sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, (tANI_U8 *) pBody, framelen);

    if (vos_mem_compare((tANI_U8* ) pHdr->sa, (tANI_U8 *) pHdr->da,
                        (tANI_U8) (sizeof(tSirMacAddr))))
    {
        limLog(pMac, LOGE, FL("Rejected Assoc Req frame Since same mac as"
                              " SAP/GO"));
        limSendAssocRspMgmtFrame(pMac,
                    eSIR_MAC_UNSPEC_FAILURE_STATUS,
                    1,
                    pHdr->sa,
                    subType, 0,psessionEntry, NULL);
        return ;
    }

    // If TKIP counter measures active send Assoc Rsp frame to station with eSIR_MAC_MIC_FAILURE_REASON
    if ((psessionEntry->bTkipCntrMeasActive) && (psessionEntry->limSystemRole == eLIM_AP_ROLE))
    {
        limLog(pMac, LOGE, FL("TKIP counter measure is active"));
        limSendAssocRspMgmtFrame(pMac,
                                    eSIR_MAC_MIC_FAILURE_REASON,
                                    1,
                                    pHdr->sa,
                                    subType, 0, psessionEntry, NULL);
        return;
    }

    // Allocate memory for the Assoc Request frame
    pAssocReq = vos_mem_malloc(sizeof(*pAssocReq));
    if (NULL == pAssocReq)
    {
        limLog(pMac, LOGP, FL("Allocate Memory failed in AssocReq"));
        return;
    }
    vos_mem_set((void *)pAssocReq , sizeof(*pAssocReq), 0);

    // Parse Assoc Request frame
    if (subType == LIM_ASSOC)
        status = sirConvertAssocReqFrame2Struct(pMac, pBody, framelen, pAssocReq);
    else
        status = sirConvertReassocReqFrame2Struct(pMac, pBody, framelen, pAssocReq);

    if (status != eSIR_SUCCESS)
    {
        limLog(pMac, LOGW,
               FL("Parse error AssocRequest, length=%d from "MAC_ADDRESS_STR),
                             framelen, MAC_ADDR_ARRAY(pHdr->sa));
        limSendAssocRspMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_STATUS, 1,
                                 pHdr->sa, subType, 0, psessionEntry, NULL);
        goto error;
    }

    pAssocReq->assocReqFrame = vos_mem_malloc(framelen);
    if ( NULL == pAssocReq->assocReqFrame )
    {
        limLog(pMac, LOGE, FL("Unable to allocate memory for the assoc req, "
                              "length=%d from "),framelen);
        goto error;
    }
    
    vos_mem_copy((tANI_U8 *) pAssocReq->assocReqFrame,
                  (tANI_U8 *) pBody, framelen);
    pAssocReq->assocReqFrameLength = framelen;    

    if (cfgGetCapabilityInfo(pMac, &temp,psessionEntry) != eSIR_SUCCESS)
    {
        limLog(pMac, LOGP, FL("could not retrieve Capabilities"));
        goto error;
    }
    limCopyU16((tANI_U8 *) &localCapabilities, temp);

    if (limCompareCapabilities(pMac,
                               pAssocReq,
                               &localCapabilities,psessionEntry) == false)
    {
        limLog(pMac, LOGE, FL("local caps mismatch received caps"));
        limLog(pMac, LOGE, FL("Received %s Req with unsupported "
        "capabilities from"MAC_ADDRESS_STR),
        (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
        MAC_ADDR_ARRAY(pHdr->sa));
        /**
         * Capabilities of requesting STA does not match with
         * local capabilities. Respond with 'unsupported capabilities'
         * status code.
         */
        limSendAssocRspMgmtFrame(
                        pMac,
                        eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
                        1,
                        pHdr->sa,
                        subType, 0,psessionEntry ,NULL);

        goto error;
    }

    if (limCmpSSid(pMac, &pAssocReq->ssId, psessionEntry) == false)
    {
        limLog(pMac, LOGE, FL("Received %s Req with unmatched ssid ( Received"
        " SSID: %.*s current SSID: %.*s ) from "MAC_ADDRESS_STR),
        (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", pAssocReq->ssId.length,
        pAssocReq->ssId.ssId, psessionEntry->ssId.length,
        psessionEntry->ssId.ssId, MAC_ADDR_ARRAY(pHdr->sa));

        /**
         * Received Re/Association Request with either
         * Broadcast SSID OR with SSID that does not
         * match with local one.
         * Respond with unspecified status code.
         */
        limSendAssocRspMgmtFrame(pMac,
                             eSIR_MAC_UNSPEC_FAILURE_STATUS,
                             1,
                             pHdr->sa,
                             subType, 0,psessionEntry, NULL);

        goto error;
    }

    /***************************************************************
      ** Verify if the requested rates are available in supported rate
      ** set or Extended rate set. Some APs are adding basic rates in
      ** Extended rateset IE
      ***************************************************************/
    basicRates.numRates = 0;

    for(i = 0; i < pAssocReq->supportedRates.numRates && (i < SIR_MAC_RATESET_EID_MAX); i++)
    {
        basicRates.rate[i] = pAssocReq->supportedRates.rate[i];
        basicRates.numRates++;
    }

    for(j = 0; (j < pAssocReq->extendedRates.numRates) && (i < SIR_MAC_RATESET_EID_MAX); i++,j++)
    {
        basicRates.rate[i] = pAssocReq->extendedRates.rate[j];
        basicRates.numRates++;
    }
    if (limCheckRxBasicRates(pMac, basicRates, psessionEntry) == false)
    {
        limLog(pMac, LOGE, FL("Received %s Req with unsupported "
        "rates from"MAC_ADDRESS_STR),
        (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
        MAC_ADDR_ARRAY(pHdr->sa));
        /**
         * Requesting STA does not support ALL BSS basic
         * rates. Respond with 'basic rates not supported'
         * status code.
         */
        limSendAssocRspMgmtFrame(
                    pMac,
                    eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS,
                    1,
                    pHdr->sa,
                    subType, 0,psessionEntry, NULL);

        goto error;
    }


    if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) &&
       (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11G_ONLY) &&
       ((!pAssocReq->extendedRatesPresent ) || (pAssocReq->HTCaps.present)))
    {
        limLog(pMac, LOGE, FL("SOFTAP was in 11G only mode, rejecting legacy "
                              "STA : "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));
        limSendAssocRspMgmtFrame( pMac, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, 
                                  1, pHdr->sa, subType, 0, psessionEntry, NULL);
        goto error;

    }//end if phyMode == 11G_only
 
    if((psessionEntry->limSystemRole == eLIM_AP_ROLE) && 
       (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11N_ONLY) && 
       (!pAssocReq->HTCaps.present))
    {
        limLog(pMac, LOGE, FL("SOFTAP was in 11N only mode, rejecting legacy "
                              "STA : "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));
        limSendAssocRspMgmtFrame( pMac, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, 
                                  1, pHdr->sa, subType, 0, psessionEntry, NULL);
        goto error;
    }//end if PhyMode == 11N_only


    /* Spectrum Management (11h) specific checks */
    if (localCapabilities.spectrumMgt)
    {
        tSirRetStatus status = eSIR_SUCCESS;

        /* If station is 11h capable, then it SHOULD send all mandatory 
         * IEs in assoc request frame. Let us verify that
         */
        if (pAssocReq->capabilityInfo.spectrumMgt)
        {
            if (!((pAssocReq->powerCapabilityPresent) && (pAssocReq->supportedChannelsPresent)))
            {
                /* One or more required information elements are missing, log the peers error */
                if (!pAssocReq->powerCapabilityPresent)
                {
                    limLog(pMac, LOG1, FL("LIM Info: Missing Power capability "
                    "IE in %s Req from "MAC_ADDRESS_STR),
                    (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
                    MAC_ADDR_ARRAY(pHdr->sa));
                }
                if (!pAssocReq->supportedChannelsPresent)
                {
                    limLog(pMac, LOGW, FL("LIM Info: Missing Supported channel "
                    "IE in %s Req from "MAC_ADDRESS_STR),
                    (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
                    MAC_ADDR_ARRAY(pHdr->sa));

                }
            }
            else
            {
                /* Assoc request has mandatory fields */
                status = limIsDot11hPowerCapabilitiesInRange(pMac, pAssocReq, psessionEntry);
                if (eSIR_SUCCESS != status)
                {
                    limLog(pMac, LOGW, FL("LIM Info: MinTxPower(STA) > "
                    "MaxTxPower(AP) in %s Req from "MAC_ADDRESS_STR),
                    (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
                    MAC_ADDR_ARRAY(pHdr->sa));

                }
                status = limIsDot11hSupportedChannelsValid(pMac, pAssocReq);
                if (eSIR_SUCCESS != status)
                {
                    limLog(pMac, LOGW, FL("LIM Info: wrong supported "
                    "channels (STA) in %s Req from "MAC_ADDRESS_STR),
                    (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
                    MAC_ADDR_ARRAY(pHdr->sa));

                }
                /* IEs are valid, use them if needed */
            }
        } //if(assoc.capabilityInfo.spectrumMgt)
        else
        {
            /* As per the capabiities, the spectrum management is not enabled on the station
             * The AP may allow the associations to happen even if spectrum management is not
             * allowed, if the transmit power of station is below the regulatory maximum
             */

            /* TODO: presently, this is not handled. In the current implemetation, the AP would
             * allow the station to associate even if it doesn't support spectrum management.
             */
        }
    }// end of spectrum management related processing

    if ( (pAssocReq->HTCaps.present) && (limCheckMCSSet(pMac, pAssocReq->HTCaps.supportedMCSSet) == false))
    {
         limLog(pMac, LOGE, FL("received %s req with unsupported"
         "MCS Rate Set from "MAC_ADDRESS_STR),
         (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
         MAC_ADDR_ARRAY(pHdr->sa));

        /**
         * Requesting STA does not support ALL BSS MCS basic Rate set rates.
         * Spec does not define any status code for this scenario.
         */
        limSendAssocRspMgmtFrame(
                    pMac,
                    eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS,
                    1,
                    pHdr->sa,
                    subType, 0,psessionEntry, NULL);

        goto error;
    }

    //if (pMac->dph.gDphPhyMode == WNI_CFG_PHY_MODE_11G)
    if (phyMode == WNI_CFG_PHY_MODE_11G)
    {

        if (wlan_cfgGetInt(pMac, WNI_CFG_11G_ONLY_POLICY, &val) != eSIR_SUCCESS)
        {
            limLog(pMac, LOGP, FL("could not retrieve 11g-only flag"));
            goto error;
        }

        if (!pAssocReq->extendedRatesPresent && val)
        {
            limLog(pMac, LOGE, FL("Rejecting Re/Assoc req from 11b STA: "
            MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));
            /**
             * Received Re/Association Request from
             * 11b STA when 11g only policy option
             * is set.
             * Reject with unspecified status code.
             */
            limSendAssocRspMgmtFrame(
                           pMac,
                           eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS,
                           1,
                           pHdr->sa,
                           subType, 0,psessionEntry, NULL);

            
#ifdef WLAN_DEBUG    
            pMac->lim.gLim11bStaAssocRejectCount++;
#endif
            goto error;
        }
    }

#ifdef WMM_APSD
    // Save the QOS info element in assoc request..
    limGetWmeMode(pMac, &wmeMode);
    if (wmeMode == eHAL_SET)
    {
        tpQosInfoSta qInfo;

        qInfo = (tpQosInfoSta) (pAssocReq->qosCapability.qosInfo);

        if ((pMac->lim.gWmmApsd.apsdEnable == 0) && (qInfo->ac_be || qInfo->ac_bk || qInfo->ac_vo || qInfo->ac_vi))
        {
            limLog(pMac, LOGW,
                   FL("Rejecting Re/Assoc req from STA: "MAC_ADDRESS_STR),
                   MAC_ADDR_ARRAY(pHdr->sa));
            limLog(pMac, LOGE, FL("APSD not enabled, qosInfo - 0x%x"), *qInfo);

            /**
             * Received Re/Association Request from
             * 11b STA when 11g only policy option
             * is set.
             * Reject with unspecified status code.
             */
            limSendAssocRspMgmtFrame(
                           pMac,
                           eSIR_MAC_WME_REFUSED_STATUS,
                           1,
                           pHdr->sa,
                           subType, 0,psessionEntry, NULL);

            goto error;
        }
    }
#endif

    // Check for 802.11n HT caps compatibility; are HT Capabilities
    // turned on in lim?
    if ( psessionEntry->htCapability )
    {
        // There are; are they turned on in the STA?
        if ( pAssocReq->HTCaps.present )
        {
            // The station *does* support 802.11n HT capability...

            limLog( pMac, LOG1, FL( "AdvCodingCap:%d ChaWidthSet:%d "
                                    "PowerSave:%d greenField:%d "
                                    "shortGI20:%d shortGI40:%d"
                                    "txSTBC:%d rxSTBC:%d delayBA:%d"
                                    "maxAMSDUsize:%d DSSS/CCK:%d "
                                    "PSMP:%d stbcCntl:%d lsigTXProt:%d"),
                    pAssocReq->HTCaps.advCodingCap,
                    pAssocReq->HTCaps.supportedChannelWidthSet,
                    pAssocReq->HTCaps.mimoPowerSave,
                    pAssocReq->HTCaps.greenField,
                    pAssocReq->HTCaps.shortGI20MHz,
                    pAssocReq->HTCaps.shortGI40MHz,
                    pAssocReq->HTCaps.txSTBC,
                    pAssocReq->HTCaps.rxSTBC,
                    pAssocReq->HTCaps.delayedBA,
                    pAssocReq->HTCaps.maximalAMSDUsize,
                    pAssocReq->HTCaps.dsssCckMode40MHz,
                    pAssocReq->HTCaps.psmp,
                    pAssocReq->HTCaps.stbcControlFrame,
                    pAssocReq->HTCaps.lsigTXOPProtection );

                // Make sure the STA's caps are compatible with our own:
                //11.15.2 Support of DSSS/CCK in 40 MHz
                //the AP shall refuse association requests from an HT STA that has the DSSS/CCK 
                //Mode in 40 MHz subfield set to 1;

            //FIXME_BTAMP_AP : Need to be enabled 
            /*
            if ( !pMac->lim.gHTDsssCckRate40MHzSupport && pAssocReq->HTCaps.dsssCckMode40MHz )
            {
                statusCode = eSIR_MAC_DSSS_CCK_RATE_NOT_SUPPORT_STATUS;
                limLog( pMac, LOGW, FL( "AP DSSS/CCK is disabled; "
                                        "STA rejected." ) );
                // Reject association
                limSendAssocRspMgmtFrame( pMac, statusCode, 1, pHdr->sa, subType, 0,psessionEntry);
                goto error;
            }
            */
        }
    } // End if on HT caps turned on in lim.

    /* Clear the buffers so that frame parser knows that there isn't a previously decoded IE in these buffers */
    vos_mem_set((tANI_U8*)&Dot11fIERSN, sizeof( Dot11fIERSN ), 0);
    vos_mem_set((tANI_U8*)&Dot11fIEWPA, sizeof( Dot11fIEWPA ), 0);

    /* if additional IE is present, check if it has WscIE */
    if( pAssocReq->addIEPresent && pAssocReq->addIE.length )
        wpsIe = limGetWscIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length);
    /* when wpsIe is present, RSN/WPA IE is ignored */
    if( wpsIe == NULL )
    {
        /** check whether as RSN IE is present */
        if(psessionEntry->limSystemRole == eLIM_AP_ROLE 
            && psessionEntry->pLimStartBssReq->privacy 
            && psessionEntry->pLimStartBssReq->rsnIE.length)
        {
            limLog(pMac, LOG1,
                   FL("RSN enabled auth, Re/Assoc req from STA: "MAC_ADDRESS_STR),
                       MAC_ADDR_ARRAY(pHdr->sa));
            if(pAssocReq->rsnPresent)
            {
                if(pAssocReq->rsn.length)
                {
                    // Unpack the RSN IE 
                    if (dot11fUnpackIeRSN(pMac,
                                        &pAssocReq->rsn.info[0], 
                                        pAssocReq->rsn.length, 
                                        &Dot11fIERSN) != DOT11F_PARSE_SUCCESS)
                    {
                        limLog(pMac, LOGE,
                               FL("Invalid RSNIE received"));
                        limSendAssocRspMgmtFrame(pMac,
                              eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS,
                              1, pHdr->sa, subType, 0,psessionEntry, NULL);
                        goto error;
                    }

                    /* Check RSN version is supported or not */
                    if(SIR_MAC_OUI_VERSION_1 == Dot11fIERSN.version)
                    {
                        /* check the groupwise and pairwise cipher suites */
                        if(eSIR_SUCCESS != (status = limCheckRxRSNIeMatch(pMac, Dot11fIERSN, psessionEntry,
                                                                          pAssocReq->HTCaps.present, &pmfConnection)))
                        {
                            limLog(pMac, LOGE, FL("RSN Mismatch. Rejecting Re/Assoc req from "
                                                  "STA: "MAC_ADDRESS_STR),
                                                    MAC_ADDR_ARRAY(pHdr->sa));

                            /* some IE is not properly sent */
                            /* received Association req frame with RSN IE but length is 0 */
                            limSendAssocRspMgmtFrame(
                                           pMac,
                                           status,
                                           1,
                                           pHdr->sa,
                                           subType, 0,psessionEntry, NULL);

                            goto error;

                        }
                    }
                    else
                    {
                        limLog(pMac, LOGE, FL("RSN Version mismatch. "
                                              "Rejecting Re/Assoc req from "
                                              "STA: "MAC_ADDRESS_STR),
                                              MAC_ADDR_ARRAY(pHdr->sa));

                        /* received Association req frame with RSN IE version wrong */
                        limSendAssocRspMgmtFrame(
                                       pMac,
                                       eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS,
                                       1,
                                       pHdr->sa,
                                       subType, 0,psessionEntry, NULL);
                        goto error;

                    }
                }
                else
                {
                    limLog(pMac, LOGW, FL("RSN length not correct. "
                                          "Rejecting Re/Assoc req from STA:"
                                          MAC_ADDRESS_STR),
                                          MAC_ADDR_ARRAY(pHdr->sa));
                    /* received Association req frame with RSN IE but length is 0 */
                    limSendAssocRspMgmtFrame(
                                   pMac,
                                   eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS,
                                   1,
                                   pHdr->sa,
                                   subType, 0,psessionEntry, NULL);

                    goto error;
                    
                }

                akm_type = lim_translate_rsn_oui_to_akm_type(
                                    Dot11fIERSN.akm_suite[0]);

                if (akm_type == ANI_AKM_TYPE_SAE) {
                    if (eSIR_SUCCESS != (status =
                        lim_check_sae_pmf_cap(psessionEntry, &Dot11fIERSN))) {
                        /* Reject pmf disable SAE STA */
                        limLog(pMac, LOGW, FL("Rejecting Re/Assoc req from STA:"
                                MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));
                        limSendAssocRspMgmtFrame(
                                    pMac,
                                    status,
                                    1,
                                    pHdr->sa,
                                    subType, 0,psessionEntry, NULL);
                        goto error;
                    }
                }

            } /* end - if(pAssocReq->rsnPresent) */
            if((!pAssocReq->rsnPresent) && pAssocReq->wpaPresent)
            {
                // Unpack the WPA IE 
                if(pAssocReq->wpa.length)
                {
                    if (dot11fUnpackIeWPA(pMac,
                                        &pAssocReq->wpa.info[4], //OUI is not taken care
                                        (pAssocReq->wpa.length - 4),
                                        &Dot11fIEWPA) != DOT11F_PARSE_SUCCESS)
                    {
                        limLog(pMac, LOGE, FL("Invalid WPA IE"));
                        limSendAssocRspMgmtFrame(pMac,
                            eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS,
                            1, pHdr->sa, subType, 0,psessionEntry, NULL);
                        goto error;
                    }
                    /* check the groupwise and pairwise cipher suites */
                    if(eSIR_SUCCESS != (status = limCheckRxWPAIeMatch(pMac, Dot11fIEWPA, psessionEntry, pAssocReq->HTCaps.present)))
                    {
                        limLog(pMac, LOGW, FL("WPA IE mismatch. "
                                              "Rejecting Re/Assoc req from "
                                              "STA: "MAC_ADDRESS_STR),
                                               MAC_ADDR_ARRAY(pHdr->sa));
                        /* received Association req frame with WPA IE but mismatch */
                        limSendAssocRspMgmtFrame(
                                       pMac,
                                       status,
                                       1,
                                       pHdr->sa,
                                       subType, 0,psessionEntry, NULL);
                        goto error;

                    }
                }
                else
                {
                    limLog(pMac, LOGW, FL("WPA len incorrect. "
                                          "Rejecting Re/Assoc req from STA: "
                                          MAC_ADDRESS_STR),
                                          MAC_ADDR_ARRAY(pHdr->sa));
                    /* received Association req frame with invalid WPA IE */
                    limSendAssocRspMgmtFrame(
                                   pMac,
                                   eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS,
                                   1,
                                   pHdr->sa,
                                   subType, 0,psessionEntry, NULL);

                    goto error;
                }/* end - if(pAssocReq->wpa.length) */

                akm_type = lim_translate_rsn_oui_to_akm_type(
                                Dot11fIEWPA.auth_suites[0]);

            } /* end - if(pAssocReq->wpaPresent) */
        } /* end of if(psessionEntry->pLimStartBssReq->privacy 
            && psessionEntry->pLimStartBssReq->rsnIE->length) */

    } /* end of     if( ! pAssocReq->wscInfo.present ) */
    else
    {
        limLog(pMac, LOG1, FL("Assoc req WSE IE is present"));
    }

    /* Extract pre-auth context for the STA, if any. */
    pStaPreAuthContext = limSearchPreAuthList(pMac, pHdr->sa);
    /* SAE authentication is offloaded to hostapd. Hostapd sends
     * authentication status to driver after completing SAE
     * authentication (after sending out 4/4 SAE auth frame).
     * There is a possible race condition where driver gets
     * assoc request from SAE station before getting authentication
     * status from hostapd. Don't reject the association in such
     * cases and defer the processing of assoc request frame by caching
     * the frame and process it when the auth status is received.
     */
    if (pStaPreAuthContext &&
        pStaPreAuthContext->authType == eSIR_AUTH_TYPE_SAE &&
        pStaPreAuthContext->mlmState == eLIM_MLM_WT_SAE_AUTH_STATE) {
        limLog(pMac, LOG1,
                FL("Received assoc request frame while SAE authentication is in progress; Defer association request handling till SAE auth status is re                ceived"));
        lim_defer_sme_indication(pMac, psessionEntry, subType, pHdr,
                                pAssocReq, pmfConnection,
                                assoc_req_copied, pStaDs);
        return;
    }

    if (!lim_send_assoc_ind_to_sme(pMac, psessionEntry, subType, pHdr,
                                  pAssocReq, akm_type, pmfConnection,
                                  &assoc_req_copied))
        goto error;

    return;

error:
    lim_process_assoc_cleanup(pMac, psessionEntry, pAssocReq, pStaDs,
                              assoc_req_copied);
    return;

} /*** end limProcessAssocReqFrame() ***/



/**---------------------------------------------------------------
\fn     limSendMlmAssocInd
\brief  This function sends either LIM_MLM_ASSOC_IND  
\       or LIM_MLM_REASSOC_IND to SME.
\
\param  pMac
\param  *pStaDs - Station DPH hash entry
\param  psessionEntry - PE session entry
\return tSirRetStatus

 * ?????? How do I get 
 *  - subtype   =====> psessionEntry->parsedAssocReq.reassocRequest
 *  - aid       =====> pStaDs->assocId
 *  - pHdr->sa  =====> pStaDs->staAddr
 *  - authType
 *  - pHdr->seqControl  =====> no longer needed
 *  - pStaDs
------------------------------------------------------------------*/
tSirRetStatus limSendMlmAssocInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry)
{
    tpLimMlmAssocInd        pMlmAssocInd = NULL;
    tpLimMlmReassocInd      pMlmReassocInd;
    tpSirAssocReq           pAssocReq;
    tANI_U16                temp;
    tANI_U32                phyMode;
    tANI_U8                 subType;
    tANI_U8                 *wpsIe = NULL;
    tANI_U32                tmp;
//    tANI_U16                statusCode;    
    tANI_U16                i, j=0;

    // Get a copy of the already parsed Assoc Request
    pAssocReq = (tpSirAssocReq) psessionEntry->parsedAssocReq[pStaDs->assocId];

    // Get the phyMode
    limGetPhyMode(pMac, &phyMode, psessionEntry);
    // Extract pre-auth context for the peer BTAMP-STA, if any.
 
    // Determiine if its Assoc or ReAssoc Request
    if (pAssocReq->reassocRequest == 1)
        subType = LIM_REASSOC;
    else 
        subType = LIM_ASSOC;

    limLog(pMac, LOG1, FL("Sessionid %d ssid %s subtype %d Associd %d staAddr "
    MAC_ADDRESS_STR), psessionEntry->peSessionId, pAssocReq->ssId.ssId,
    subType,pStaDs->assocId,MAC_ADDR_ARRAY(pStaDs->staAddr));

    if (subType == LIM_ASSOC || subType == LIM_REASSOC)
    {
        temp  = sizeof(tLimMlmAssocInd);

        pMlmAssocInd = vos_mem_malloc(temp);
        if (NULL == pMlmAssocInd)
        {
            limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry);
            limLog(pMac, LOGP, FL("AllocateMemory failed for pMlmAssocInd"));
            return eSIR_MEM_ALLOC_FAILED;
        }
        vos_mem_set(pMlmAssocInd, temp ,0);

        vos_mem_copy((tANI_U8 *)pMlmAssocInd->peerMacAddr,
                     (tANI_U8 *)pStaDs->staAddr, sizeof(tSirMacAddr));
 
        pMlmAssocInd->aid    = pStaDs->assocId;
        vos_mem_copy((tANI_U8 *)&pMlmAssocInd->ssId,
                     (tANI_U8 *)&(pAssocReq->ssId), pAssocReq->ssId.length + 1);
        pMlmAssocInd->sessionId = psessionEntry->peSessionId;
        pMlmAssocInd->authType =  pStaDs->mlmStaContext.authType;
        pMlmAssocInd->akm_type =  pStaDs->mlmStaContext.akm_type;
 
        pMlmAssocInd->capabilityInfo = pAssocReq->capabilityInfo;

        // Fill in RSN IE information
        pMlmAssocInd->rsnIE.length = 0;
        // if WPS IE is present, ignore RSN IE
        if (pAssocReq->addIEPresent && pAssocReq->addIE.length ) {
            wpsIe = limGetWscIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length);
        }
        if (pAssocReq->rsnPresent && (NULL == wpsIe))
        {
            limLog(pMac, LOG2, FL("Assoc Req RSN IE len = %d"),
                                    pAssocReq->rsn.length);
            pMlmAssocInd->rsnIE.length = 2 + pAssocReq->rsn.length;
            pMlmAssocInd->rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID;
            pMlmAssocInd->rsnIE.rsnIEdata[1] = pAssocReq->rsn.length;
            vos_mem_copy(&pMlmAssocInd->rsnIE.rsnIEdata[2],
                         pAssocReq->rsn.info,
                         pAssocReq->rsn.length);
        }

        // Fill in 802.11h related info
        if (pAssocReq->powerCapabilityPresent && pAssocReq->supportedChannelsPresent)
        {
            pMlmAssocInd->spectrumMgtIndicator = eSIR_TRUE;
            pMlmAssocInd->powerCap.minTxPower = pAssocReq->powerCapability.minTxPower;
            pMlmAssocInd->powerCap.maxTxPower = pAssocReq->powerCapability.maxTxPower;
            limConvertSupportedChannels(pMac, pMlmAssocInd, pAssocReq);
        }
        else
            pMlmAssocInd->spectrumMgtIndicator = eSIR_FALSE;


        /* This check is to avoid extra Sec IEs present incase of WPS */
        if (pAssocReq->wpaPresent && (NULL == wpsIe))
        {
            if((pMlmAssocInd->rsnIE.length + pAssocReq->wpa.length) >= SIR_MAC_MAX_IE_LENGTH)
            {
                PELOGE(limLog(pMac, LOGE, FL("rsnIEdata index out of bounds %d"),
                                              pMlmAssocInd->rsnIE.length);)
                vos_mem_free(pMlmAssocInd);
                return eSIR_FAILURE;
            }
            pMlmAssocInd->rsnIE.rsnIEdata[pMlmAssocInd->rsnIE.length] = SIR_MAC_WPA_EID;
            pMlmAssocInd->rsnIE.rsnIEdata[pMlmAssocInd->rsnIE.length + 1] = pAssocReq->wpa.length;
            vos_mem_copy(&pMlmAssocInd->rsnIE.rsnIEdata[pMlmAssocInd->rsnIE.length + 2],
                         pAssocReq->wpa.info,
                         pAssocReq->wpa.length);
            pMlmAssocInd->rsnIE.length += 2 + pAssocReq->wpa.length;
        }


       pMlmAssocInd->addIE.length = 0;
       if (pAssocReq->addIEPresent)
       {
            vos_mem_copy(&pMlmAssocInd->addIE.addIEdata,
                          pAssocReq->addIE.addIEdata,
                          pAssocReq->addIE.length);

            pMlmAssocInd->addIE.length = pAssocReq->addIE.length;
       }

        if(pAssocReq->wmeInfoPresent)
        {

            if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WME_ENABLED, &tmp) != eSIR_SUCCESS)
                 limLog(pMac, LOGP, FL("wlan_cfgGetInt failed for id %d"),
                                                WNI_CFG_WME_ENABLED );

            /* check whether AP is enabled with WMM */
            if(tmp)
            {
                pMlmAssocInd->WmmStaInfoPresent = 1;
            }
            else
            {
                pMlmAssocInd->WmmStaInfoPresent= 0;
            }
            /* Note: we are not rejecting association here because IOT will fail */

        }
#ifdef WLAN_FEATURE_AP_HT40_24G
        if(pAssocReq->HTCaps.present)
        {
            limLog(pMac, LOGW, FL("HT40MHzInto: %d"),
                         pAssocReq->HTCaps.stbcControlFrame);
            pMlmAssocInd->HT40MHzIntoPresent =
                         pAssocReq->HTCaps.stbcControlFrame;
        }
#endif

        // Required for indicating the frames to upper layer
        pMlmAssocInd->assocReqLength = pAssocReq->assocReqFrameLength;
        pMlmAssocInd->assocReqPtr = pAssocReq->assocReqFrame;
        
        pMlmAssocInd->beaconPtr = psessionEntry->beacon;
        pMlmAssocInd->beaconLength = psessionEntry->bcnLen;

        pMlmAssocInd->chan_info.chan_id = psessionEntry->currentOperChannel;

        if (psessionEntry->limRFBand == SIR_BAND_2_4_GHZ) {
            if (psessionEntry->vhtCapability && pAssocReq->VHTCaps.present) {
                pMlmAssocInd->chan_info.info = MODE_11AC_VHT20_2G;
                pMlmAssocInd->VHTCaps = pAssocReq->VHTCaps;
            } else if (psessionEntry->htCapability &&
                                                 pAssocReq->HTCaps.present) {
                pMlmAssocInd->chan_info.info = MODE_11NG_HT20;
                pMlmAssocInd->HTCaps = pAssocReq->HTCaps;
            } else if (pStaDs->supportedRates.llaRates[0]) {
                pMlmAssocInd->chan_info.info = MODE_11G;
            } else {
                pMlmAssocInd->chan_info.info = MODE_11B;
            }
        } else {
            if (psessionEntry->vhtCapability && pAssocReq->VHTCaps.present) {
                if ((psessionEntry->vhtTxChannelWidthSet ==
                                                eHT_CHANNEL_WIDTH_80MHZ) &&
                                 pAssocReq->HTCaps.supportedChannelWidthSet) {
                    pMlmAssocInd->chan_info.info = MODE_11AC_VHT80;
                } else if ((psessionEntry->vhtTxChannelWidthSet ==
                                                eHT_CHANNEL_WIDTH_40MHZ) &&
                                  pAssocReq->HTCaps.supportedChannelWidthSet) {
                    pMlmAssocInd->chan_info.info = MODE_11AC_VHT40;
                } else
                    pMlmAssocInd->chan_info.info = MODE_11AC_VHT20;
                    pMlmAssocInd->VHTCaps = pAssocReq->VHTCaps;
            } else if (psessionEntry->htCapability &&
                                pAssocReq->HTCaps.present) {
                if ((psessionEntry->vhtTxChannelWidthSet ==
                                                eHT_CHANNEL_WIDTH_40MHZ) &&
                                  pAssocReq->HTCaps.supportedChannelWidthSet) {
                    pMlmAssocInd->chan_info.info = MODE_11NA_HT40;
                } else
                    pMlmAssocInd->chan_info.info = MODE_11NA_HT20;
                pMlmAssocInd->HTCaps = pAssocReq->HTCaps;
            } else
                pMlmAssocInd->chan_info.info = MODE_11A;
        }

        pMlmAssocInd->ch_width = eHT_CHANNEL_WIDTH_20MHZ;
        if (pStaDs->mlmStaContext.htCapability)
            pMlmAssocInd->ch_width = pStaDs->htSupportedChannelWidthSet ?
                            eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ;

        pMlmAssocInd->rate_flags =
            limGetMaxRateFlags(pStaDs, psessionEntry);
        pMlmAssocInd->is_sae_authenticated = pAssocReq->is_sae_authenticated;
        limPostSmeMessage(pMac, LIM_MLM_ASSOC_IND, (tANI_U32 *) pMlmAssocInd);
        vos_mem_free(pMlmAssocInd);
    }
    else
    {
        // If its of Reassociation Request, then post LIM_MLM_REASSOC_IND 
        temp  = sizeof(tLimMlmReassocInd);

        pMlmReassocInd = vos_mem_malloc(temp);
        if (NULL == pMlmReassocInd)
        {
            limLog(pMac, LOGP, FL("call to AllocateMemory failed for "
                                  "pMlmReassocInd"));
            limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry);
            return eSIR_MEM_ALLOC_FAILED;
        }
        vos_mem_set(pMlmReassocInd, temp, 0);

        vos_mem_copy((tANI_U8 *) pMlmReassocInd->peerMacAddr,
                     (tANI_U8 *)pStaDs->staAddr, sizeof(tSirMacAddr));
        vos_mem_copy((tANI_U8 *) pMlmReassocInd->currentApAddr,
                     (tANI_U8 *)&(pAssocReq->currentApAddr), sizeof(tSirMacAddr));
        pMlmReassocInd->aid = pStaDs->assocId;
        pMlmReassocInd->authType = pStaDs->mlmStaContext.authType;
        vos_mem_copy((tANI_U8 *)&pMlmReassocInd->ssId,
                     (tANI_U8 *)&(pAssocReq->ssId), pAssocReq->ssId.length + 1);

        if (pAssocReq->propIEinfo.aniIndicator)
            pStaDs->aniPeer = 1;

        pMlmReassocInd->capabilityInfo = pAssocReq->capabilityInfo;
        pMlmReassocInd->rsnIE.length = 0;

        if (pAssocReq->addIEPresent && pAssocReq->addIE.length )
            wpsIe = limGetWscIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length);

        if (pAssocReq->rsnPresent && (NULL == wpsIe))
        {
            limLog(pMac, LOG2, FL("Assoc Req: RSN IE length = %d"),
                                            pAssocReq->rsn.length);
            pMlmReassocInd->rsnIE.length = 2 + pAssocReq->rsn.length;
            pMlmReassocInd->rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID;
            pMlmReassocInd->rsnIE.rsnIEdata[1] = pAssocReq->rsn.length;
            vos_mem_copy(&pMlmReassocInd->rsnIE.rsnIEdata[2],
                          pAssocReq->rsn.info, pAssocReq->rsn.length);
        }

        // 802.11h support
        if (pAssocReq->powerCapabilityPresent && pAssocReq->supportedChannelsPresent)
        {
            pMlmReassocInd->spectrumMgtIndicator = eSIR_TRUE;
            pMlmReassocInd->powerCap.minTxPower = pAssocReq->powerCapability.minTxPower;
            pMlmReassocInd->powerCap.maxTxPower = pAssocReq->powerCapability.maxTxPower;
            pMlmReassocInd->supportedChannels.numChnl = (tANI_U8)(pAssocReq->supportedChannels.length / 2);

            limLog(pMac, LOG1,
                FL("Sending Reassoc Ind: spectrum ON, minPwr %d, "
                   "maxPwr %d, numChnl %d"),
                pMlmReassocInd->powerCap.minTxPower,
                pMlmReassocInd->powerCap.maxTxPower,
                pMlmReassocInd->supportedChannels.numChnl);

            for(i=0; i < pMlmReassocInd->supportedChannels.numChnl; i++)
            {
                pMlmReassocInd->supportedChannels.channelList[i] = pAssocReq->supportedChannels.supportedChannels[j];
                limLog(pMac, LOG1, FL("Sending ReassocInd: chn[%d] = %d "),
                       i, pMlmReassocInd->supportedChannels.channelList[i]);
                j+=2;
            }
        }
        else
            pMlmReassocInd->spectrumMgtIndicator = eSIR_FALSE;


        /* This check is to avoid extra Sec IEs present incase of WPS */
        if (pAssocReq->wpaPresent && (NULL == wpsIe))
        {
            limLog(pMac, LOG2, FL("Received WPA IE length in Assoc Req is %d"),
                                   pAssocReq->wpa.length);
            pMlmReassocInd->rsnIE.rsnIEdata[pMlmReassocInd->rsnIE.length] = SIR_MAC_WPA_EID;
            pMlmReassocInd->rsnIE.rsnIEdata[pMlmReassocInd->rsnIE.length + 1] = pAssocReq->wpa.length;
            vos_mem_copy(&pMlmReassocInd->rsnIE.rsnIEdata[pMlmReassocInd->rsnIE.length + 2],
                          pAssocReq->wpa.info,
                          pAssocReq->wpa.length);
            pMlmReassocInd->rsnIE.length += 2 + pAssocReq->wpa.length;
        }

       pMlmReassocInd->addIE.length = 0;
       if (pAssocReq->addIEPresent)
       {
            vos_mem_copy(&pMlmReassocInd->addIE.addIEdata,
                         pAssocReq->addIE.addIEdata,
                         pAssocReq->addIE.length);

            pMlmReassocInd->addIE.length = pAssocReq->addIE.length;
       }

        if(pAssocReq->wmeInfoPresent)
        {

            if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WME_ENABLED, &tmp) != eSIR_SUCCESS)
                 limLog(pMac, LOGP, FL("wlan_cfgGetInt failed for id %d"),
                                                    WNI_CFG_WME_ENABLED );

            /* check whether AP is enabled with WMM */
            if(tmp)
            {
                pMlmReassocInd->WmmStaInfoPresent = 1;
            }
            else
            {
                pMlmReassocInd->WmmStaInfoPresent = 0;
            }
            /* Note: we are not rejecting Re-association here because IOT will fail */

        }

#ifdef WLAN_FEATURE_AP_HT40_24G
        if(pAssocReq->HTCaps.present)
        {
            limLog(pMac, LOGW, FL("RASSOC HT40MHzInto: %d"),
                                   pAssocReq->HTCaps.stbcControlFrame);
            pMlmReassocInd->HT40MHzIntoPresent =
                            pAssocReq->HTCaps.stbcControlFrame;
        }
#endif

        // Required for indicating the frames to upper layer
        pMlmReassocInd->assocReqLength = pAssocReq->assocReqFrameLength;
        pMlmReassocInd->assocReqPtr = pAssocReq->assocReqFrame;

        pMlmReassocInd->beaconPtr = psessionEntry->beacon;
        pMlmReassocInd->beaconLength = psessionEntry->bcnLen;

        limPostSmeMessage(pMac, LIM_MLM_REASSOC_IND, (tANI_U32 *) pMlmReassocInd);
        vos_mem_free(pMlmReassocInd);
    }

    return eSIR_SUCCESS;

} /*** end limSendMlmAssocInd() ***/
