/*
 * Copyright (c) 2012-2017 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 schBeaconGen.cc contains beacon generation related
 * functions
 *
 * Author:      Sandesh Goel
 * Date:        02/25/02
 * History:-
 * Date            Modified by    Modification Information
 * --------------------------------------------------------------------
 *
 */

#include "palTypes.h"
#include "wni_cfg.h"
#include "aniGlobal.h"
#include "sirMacProtDef.h"

#include "limUtils.h"
#include "limApi.h"


#include "halMsgApi.h"
#include "cfgApi.h"
#include "pmmApi.h"
#include "schApi.h"

#include "parserApi.h"

#include "schDebug.h"

//
// March 15, 2006
// Temporarily (maybe for all of Alpha-1), assuming TIM = 0
//

const tANI_U8 P2pOui[] = {0x50, 0x6F, 0x9A, 0x9};


tSirRetStatus schGetP2pIeOffset(tANI_U8 *pExtraIe, tANI_U32 extraIeLen, tANI_U16 *pP2pIeOffset)
{
    tSirRetStatus status = eSIR_FAILURE;
    *pP2pIeOffset = 0;

    // Extra IE is not present
    if(0 == extraIeLen)
    {
        return status;
    }

    // Calculate the P2P IE Offset
    do
    {
        if(*pExtraIe == 0xDD)
        {
            if ( vos_mem_compare ( (void *)(pExtraIe+2), &P2pOui, sizeof(P2pOui) ) )
            {
                status = eSIR_SUCCESS;
                break;
            }
        }

        (*pP2pIeOffset)++;
        pExtraIe++;
     }while(--extraIeLen > 0);

     return status;
}

tSirRetStatus schAppendAddnIE(tpAniSirGlobal pMac, tpPESession psessionEntry,
                                     tANI_U8 *pFrame, tANI_U32 maxBeaconSize,
                                     tANI_U32 *nBytes, uint8_t *addn_ie,
                                     uint16_t addn_ielen)
{
    tSirRetStatus status = eSIR_FAILURE;
    tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN];

    if(addn_ielen <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && addn_ielen &&
      ((addn_ielen + *nBytes) <= maxBeaconSize))
    {

        vos_mem_copy(&addIE[0], addn_ie, addn_ielen);

        {
            tANI_U8* pP2pIe = limGetP2pIEPtr(pMac, &addIE[0], addn_ielen);
            if ((pP2pIe != NULL) && !pMac->beacon_offload)
            {
                tANI_U8 noaLen = 0;
                tANI_U8 noaStream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
                //get NoA attribute stream P2P IE
                noaLen = limGetNoaAttrStream(pMac, noaStream, psessionEntry);
                if(noaLen)
                {
                    if ((noaLen + addn_ielen) <=
                                    WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) {
                        vos_mem_copy(&addIE[addn_ielen], noaStream, noaLen);
                        addn_ielen += noaLen;
                        /* Update IE Len */
                        pP2pIe[1] += noaLen;
                    }
                    else
                    {
                        schLog(pMac, LOGE,
                           FL("Not able to insert NoA because of addn_ielength constraint"));
                    }
                }
            }
            if(addn_ielen <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN)
            {
                vos_mem_copy(pFrame, &addIE[0], addn_ielen);
                *nBytes = *nBytes + addn_ielen;
            }
            else
            {
                schLog(pMac, LOGW, FL("Not able to insert because of"
                    " addn_ielength constraint %d"), addn_ielen);
            }
        }
    }

    return status;
}

// --------------------------------------------------------------------
/**
 * schSetFixedBeaconFields
 *
 * FUNCTION:
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param None
 * @return None
 */

tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEntry)
{
    tpAniBeaconStruct pBeacon = (tpAniBeaconStruct)
                          psessionEntry->pSchBeaconFrameBegin;
    tpSirMacMgmtHdr mac;
    tANI_U16        offset;
    tANI_U8        *ptr;
    tDot11fBeacon1 *pBcn1;
    tDot11fBeacon2 *pBcn2;
    tANI_U32        i, nStatus, nBytes;
    tANI_U32        wpsApEnable=0, tmp;
    tDot11fIEWscProbeRes      *pWscProbeRes;
    tANI_U8  *pExtraIe = NULL;
    tANI_U32 extraIeLen =0;
    tANI_U16 extraIeOffset = 0;
    tANI_U16 p2pIeOffset = 0;
    tSirRetStatus status = eSIR_SUCCESS;
    tANI_BOOLEAN  isVHTEnabled = eANI_BOOLEAN_FALSE;
    uint16_t addn_ielen = 0;
    uint8_t *addn_ie = NULL;
    tDot11fIEExtCap extracted_extcap;
    bool extcap_present = true, addnie_present = false;

    pBcn1 = vos_mem_malloc(sizeof(tDot11fBeacon1));
    if ( NULL == pBcn1 )
    {
        schLog(pMac, LOGE, FL("Failed to allocate memory") );
        return eSIR_FAILURE;
    }

    pBcn2 = vos_mem_malloc(sizeof(tDot11fBeacon2));
    if ( NULL == pBcn2 )
    {
        schLog(pMac, LOGE, FL("Failed to allocate memory") );
        vos_mem_free(pBcn1);
        return eSIR_FAILURE;
    }

    pWscProbeRes = vos_mem_malloc(sizeof(tDot11fIEWscProbeRes));
    if ( NULL == pWscProbeRes )
    {
        schLog(pMac, LOGE, FL("Failed to allocate memory") );
        vos_mem_free(pBcn1);
        vos_mem_free(pBcn2);
        return eSIR_FAILURE;
    }

    PELOG1(schLog(pMac, LOG1, FL("Setting fixed beacon fields"));)

    /*
     * First set the fixed fields
     */

    // set the TFP headers

    // set the mac header
    vos_mem_set(( tANI_U8*) &pBeacon->macHdr, sizeof( tSirMacMgmtHdr ),0);
    mac = (tpSirMacMgmtHdr) &pBeacon->macHdr;
    mac->fc.type = SIR_MAC_MGMT_FRAME;
    mac->fc.subType = SIR_MAC_MGMT_BEACON;

    for (i=0; i<6; i++)
        mac->da[i] = 0xff;

    vos_mem_copy(mac->sa, psessionEntry->selfMacAddr, sizeof(psessionEntry->selfMacAddr));
    vos_mem_copy(mac->bssId, psessionEntry->bssId, sizeof (psessionEntry->bssId));

    mac->fc.fromDS = 0;
    mac->fc.toDS = 0;

    /*
     * Now set the beacon body
     */

    vos_mem_set(( tANI_U8*) pBcn1, sizeof( tDot11fBeacon1 ), 0);

    /* Skip over the time stamp (it'll be updated later). */

    pBcn1->BeaconInterval.interval = psessionEntry->beaconParams.beaconInterval;
    PopulateDot11fCapabilities( pMac, &pBcn1->Capabilities, psessionEntry );
    if (psessionEntry->ssidHidden)
    {
       pBcn1->SSID.present = 1; /* Rest of the fields are 0 for hidden ssid */
       if((psessionEntry->ssId.length) &&
          (psessionEntry->ssidHidden == eHIDDEN_SSID_ZERO_CONTENTS))
          pBcn1->SSID.num_ssid = psessionEntry->ssId.length;
    }
    else
    {
       PopulateDot11fSSID( pMac, &psessionEntry->ssId, &pBcn1->SSID );
    }


    PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, &pBcn1->SuppRates,psessionEntry);
    PopulateDot11fDSParams( pMac, &pBcn1->DSParams, psessionEntry->currentOperChannel, psessionEntry);
    PopulateDot11fIBSSParams( pMac, &pBcn1->IBSSParams,psessionEntry);

    offset = sizeof( tAniBeaconStruct );
    ptr    = psessionEntry->pSchBeaconFrameBegin + offset;

    if (LIM_IS_AP_ROLE(psessionEntry)) {
        /* Initialize the default IE bitmap to zero */
        vos_mem_set(( tANI_U8* )&(psessionEntry->DefProbeRspIeBitmap), (sizeof( tANI_U32 ) * 8), 0);

        /* Initialize the default IE bitmap to zero */
        vos_mem_set(( tANI_U8* )&(psessionEntry->probeRespFrame),
                    sizeof(psessionEntry->probeRespFrame), 0);

        if (vos_is_probe_rsp_offload_enabled()) {
            /* Can be efficiently updated whenever new IE added
             * in Probe response in future
             */
            if (limUpdateProbeRspTemplateIeBitmapBeacon1(pMac, pBcn1,
                   psessionEntry) != eSIR_SUCCESS) {
                       schLog(pMac, LOGE,
                           FL("Failed to build ProbeRsp template"));
            }
        }
    }

    nStatus = dot11fPackBeacon1( pMac, pBcn1, ptr,
                                 SCH_MAX_BEACON_SIZE - offset,
                                 &nBytes );
    if ( DOT11F_FAILED( nStatus ) )
    {
      schLog( pMac, LOGE, FL("Failed to packed a tDot11fBeacon1 (0x%0"
                             "8x.)."), nStatus );
      vos_mem_free(pBcn1);
      vos_mem_free(pBcn2);
      vos_mem_free(pWscProbeRes);
      return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( nStatus ) )
    {
      schLog( pMac, LOGE, FL("There were warnings while packing a tDo"
                             "t11fBeacon1 (0x%08x.)."), nStatus );
    }
    /*changed  to correct beacon corruption */
    vos_mem_set(( tANI_U8*) pBcn2, sizeof( tDot11fBeacon2 ), 0);
    psessionEntry->schBeaconOffsetBegin = offset + ( tANI_U16 )nBytes;
    schLog( pMac, LOG1, FL("Initialized beacon begin, offset %d"), offset );

    /*
     * Initialize the 'new' fields at the end of the beacon
     */

    if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) &&
       psessionEntry->dfsIncludeChanSwIe == VOS_TRUE) {
           if (!CHAN_HOP_ALL_BANDS_ENABLE ||
               psessionEntry->lim_non_ecsa_cap_num == 0)
                   populate_dot_11_f_ext_chann_switch_ann(
                       pMac, &pBcn2->ext_chan_switch_ann, psessionEntry);
           else
                   PopulateDot11fChanSwitchAnn(pMac, &pBcn2->ChanSwitchAnn,
                                               psessionEntry);
    }

    populate_dot11_supp_operating_classes(pMac, &pBcn2->SuppOperatingClasses,
                                          psessionEntry);
    PopulateDot11fCountry( pMac, &pBcn2->Country, psessionEntry);
    if(pBcn1->Capabilities.qos)
    {
        PopulateDot11fEDCAParamSet( pMac, &pBcn2->EDCAParamSet, psessionEntry);
    }

    if(psessionEntry->lim11hEnable)
    {
      PopulateDot11fPowerConstraints( pMac, &pBcn2->PowerConstraints );
      PopulateDot11fTPCReport( pMac, &pBcn2->TPCReport, psessionEntry);

      /* Need to insert channel switch announcement here */
      if ((LIM_IS_AP_ROLE(psessionEntry) ||
           LIM_IS_P2P_DEVICE_GO(psessionEntry)) &&
           psessionEntry->dfsIncludeChanSwIe == VOS_TRUE) {
         /* Channel switch announcement only if radar is detected
          * and SAP has instructed to announce channel switch IEs
          * in beacon and probe responses
          */
          if (!CHAN_HOP_ALL_BANDS_ENABLE)
                  PopulateDot11fChanSwitchAnn(pMac, &pBcn2->ChanSwitchAnn,
                                              psessionEntry);

#ifdef WLAN_FEATURE_11AC
         /* TODO: If in 11AC mode, wider bw channel switch announcement needs
          * to be called
          */
         /*PopulateDot11fWiderBWChanSwitchAnn(pMac, &pBcn2->WiderBWChanSwitchAnn,
                                            psessionEntry);*/
#endif
         /*
          * Populate the Channel Switch Wrapper Element if
          * SAP operates in 40/80 Mhz Channel Width.
          */
         if (VOS_TRUE == psessionEntry->dfsIncludeChanWrapperIe)
         {
            PopulateDot11fChanSwitchWrapper(pMac,
                                     &pBcn2->ChannelSwitchWrapper,
                                     psessionEntry);
         }
      }
    }

#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
    /* populate proprietary IE for MDM device operating in AP-MCC */
    populate_dot11f_avoid_channel_ie(pMac, &pBcn2->QComVendorIE, psessionEntry);
#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */

    populate_dot11f_sub_20_channel_width_ie(
        pMac, &pBcn2->QComVendorIE, psessionEntry);

    if (psessionEntry->dot11mode != WNI_CFG_DOT11_MODE_11B)
        PopulateDot11fERPInfo( pMac, &pBcn2->ERPInfo, psessionEntry );

    if(psessionEntry->htCapability)
    {
        PopulateDot11fHTCaps( pMac,psessionEntry, &pBcn2->HTCaps );
        PopulateDot11fHTInfo( pMac, &pBcn2->HTInfo, psessionEntry );
    }
#ifdef WLAN_FEATURE_11AC
    if(psessionEntry->vhtCapability)
    {
        schLog( pMac, LOGW, FL("Populate VHT IEs in Beacon"));
        PopulateDot11fVHTCaps( pMac, psessionEntry, &pBcn2->VHTCaps );
        PopulateDot11fVHTOperation( pMac, psessionEntry, &pBcn2->VHTOperation);
        isVHTEnabled = eANI_BOOLEAN_TRUE;
        // we do not support multi users yet
        //PopulateDot11fVHTExtBssLoad( pMac, &bcn2.VHTExtBssLoad);
        if(psessionEntry->gLimOperatingMode.present)
            PopulateDot11fOperatingMode( pMac, &pBcn2->OperatingMode, psessionEntry );
    }
#endif

    if (psessionEntry->limSystemRole != eLIM_STA_IN_IBSS_ROLE)
        PopulateDot11fExtCap(pMac, isVHTEnabled, &pBcn2->ExtCap, psessionEntry);

    PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
                                &pBcn2->ExtSuppRates, psessionEntry );

    if( psessionEntry->pLimStartBssReq != NULL )
    {
          PopulateDot11fWPA( pMac, &psessionEntry->pLimStartBssReq->rsnIE,
                       &pBcn2->WPA );
          PopulateDot11fRSNOpaque( pMac, &psessionEntry->pLimStartBssReq->rsnIE,
                       &pBcn2->RSNOpaque );
#ifdef SAP_AUTH_OFFLOAD
        /* Software AP Authentication Offload feature
         * only support WPA2-PSK AES and we
         * need to update RSNIE for beacon
         */
        sap_auth_offload_update_rsn_ie(pMac, &pBcn2->RSNOpaque);
#endif
    }

    if(psessionEntry->limWmeEnabled)
    {
        PopulateDot11fWMM( pMac, &pBcn2->WMMInfoAp, &pBcn2->WMMParams, &pBcn2->WMMCaps, psessionEntry);
    }
    if (LIM_IS_AP_ROLE(psessionEntry)) {
        if(psessionEntry->wps_state != SAP_WPS_DISABLED)
        {
            PopulateDot11fBeaconWPSIEs( pMac, &pBcn2->WscBeacon, psessionEntry);
        }
    }
    else
    {
        if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_ENABLE, &tmp) != eSIR_SUCCESS)
            schLog(pMac, LOGP,"Failed to cfg get id %d", WNI_CFG_WPS_ENABLE );

        wpsApEnable = tmp & WNI_CFG_WPS_ENABLE_AP;

        if (wpsApEnable)
        {
            PopulateDot11fWsc(pMac, &pBcn2->WscBeacon);
        }

        if (pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_BEGIN)
        {
            PopulateDot11fWscRegistrarInfo(pMac, &pBcn2->WscBeacon);
            pMac->lim.wscIeInfo.wscEnrollmentState = eLIM_WSC_ENROLL_IN_PROGRESS;
        }

        if (pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_END)
        {
            DePopulateDot11fWscRegistrarInfo(pMac, &pBcn2->WscBeacon);
            pMac->lim.wscIeInfo.wscEnrollmentState = eLIM_WSC_ENROLL_NOOP;
        }
    }

    if (LIM_IS_AP_ROLE(psessionEntry)) {
        if (vos_is_probe_rsp_offload_enabled()) {
            /* Can be efficiently updated whenever new IE added  in Probe response in future */
            limUpdateProbeRspTemplateIeBitmapBeacon2(pMac,pBcn2,&psessionEntry->DefProbeRspIeBitmap[0],
                                                     &psessionEntry->probeRespFrame);
        }

        /* update probe response WPS IE instead of beacon WPS IE
        * */
        if(psessionEntry->wps_state != SAP_WPS_DISABLED)
        {
            if(psessionEntry->APWPSIEs.SirWPSProbeRspIE.FieldPresent)
            {
                PopulateDot11fProbeResWPSIEs(pMac, pWscProbeRes, psessionEntry);
            }
            else
            {
                pWscProbeRes->present = 0;
            }
            if(pWscProbeRes->present)
            {
                SetProbeRspIeBitmap(&psessionEntry->DefProbeRspIeBitmap[0],SIR_MAC_WPA_EID);
                vos_mem_copy((void *)&psessionEntry->probeRespFrame.WscProbeRes,
                             (void *)pWscProbeRes,
                             sizeof(tDot11fIEWscProbeRes));
            }
        }

    }

    addnie_present = (psessionEntry->addIeParams.probeRespBCNDataLen != 0);
    if (addnie_present) {
        addn_ielen = psessionEntry->addIeParams.probeRespBCNDataLen;
        addn_ie = vos_mem_malloc(addn_ielen);
        if (!addn_ie) {
             schLog(pMac, LOGE, FL("addn_ie malloc failed"));
             vos_mem_free(pBcn1);
             vos_mem_free(pBcn2);
             vos_mem_free(pWscProbeRes);
             return eSIR_MEM_ALLOC_FAILED;
        }
        vos_mem_copy(addn_ie, psessionEntry->addIeParams.probeRespBCNData_buff,
                     addn_ielen);

        vos_mem_set((uint8_t *)&extracted_extcap, sizeof(tDot11fIEExtCap), 0);
        status = lim_strip_extcap_update_struct(pMac, addn_ie, &addn_ielen,
                                                &extracted_extcap);
        if (eSIR_SUCCESS != status) {
            extcap_present = false;
            schLog(pMac, LOG1, FL("extcap not extracted"));
        }
        /* merge extcap IE */
        if (extcap_present &&
            psessionEntry->limSystemRole != eLIM_STA_IN_IBSS_ROLE)
            lim_merge_extcap_struct(&pBcn2->ExtCap, &extracted_extcap, true);

    }

    nStatus = dot11fPackBeacon2( pMac, pBcn2,
                                 psessionEntry->pSchBeaconFrameEnd,
                                 SCH_MAX_BEACON_SIZE, &nBytes );
    if ( DOT11F_FAILED( nStatus ) )
    {
      schLog( pMac, LOGE, FL("Failed to packed a tDot11fBeacon2 (0x%0"
                             "8x.)."), nStatus );
      vos_mem_free(pBcn1);
      vos_mem_free(pBcn2);
      vos_mem_free(pWscProbeRes);
      vos_mem_free(addn_ie);
      return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( nStatus ) )
    {
      schLog( pMac, LOGE, FL("There were warnings while packing a tDo"
                             "t11fBeacon2 (0x%08x.)."), nStatus );
    }

    pExtraIe = psessionEntry->pSchBeaconFrameEnd + nBytes;
    extraIeOffset = nBytes;

    if (addn_ielen > 0)
        schAppendAddnIE(pMac, psessionEntry,
                    psessionEntry->pSchBeaconFrameEnd + nBytes,
                    SCH_MAX_BEACON_SIZE, &nBytes, addn_ie, addn_ielen);

    psessionEntry->schBeaconOffsetEnd = ( tANI_U16 )nBytes;

    extraIeLen = nBytes - extraIeOffset;

    //Get the p2p Ie Offset
    status = schGetP2pIeOffset(pExtraIe, extraIeLen, &p2pIeOffset);

    if(eSIR_SUCCESS == status)
    {
       //Update the P2P Ie Offset
       pMac->sch.schObject.p2pIeOffset =
                    psessionEntry->schBeaconOffsetBegin + TIM_IE_SIZE +
                    extraIeOffset + p2pIeOffset;
    }
    else
    {
       pMac->sch.schObject.p2pIeOffset = 0;
    }

    schLog( pMac, LOG1, FL("Initialized beacon end, offset %d"),
            psessionEntry->schBeaconOffsetEnd );

    pMac->sch.schObject.fBeaconChanged = 1;
    vos_mem_free(pBcn1);
    vos_mem_free(pBcn2);
    vos_mem_free(pWscProbeRes);
    vos_mem_free(addn_ie);
    return eSIR_SUCCESS;
}

tSirRetStatus limUpdateProbeRspTemplateIeBitmapBeacon1(tpAniSirGlobal pMac,
                                              tDot11fBeacon1* beacon1,
                                              tpPESession psessionEntry)
{
    tANI_U32* DefProbeRspIeBitmap;
    tDot11fProbeResponse* prb_rsp;

    if (!psessionEntry) {
        schLog(pMac, LOGE, FL("PESession is null!"));
        return eSIR_FAILURE;
    }

    DefProbeRspIeBitmap = &psessionEntry->DefProbeRspIeBitmap[0];
    prb_rsp = &psessionEntry->probeRespFrame;

    prb_rsp->BeaconInterval = beacon1->BeaconInterval;
    vos_mem_copy((void *)&prb_rsp->Capabilities, (void *)&beacon1->Capabilities,
                 sizeof(beacon1->Capabilities));

    /* SSID */
    if(beacon1->SSID.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_SSID_EID);
        /* populating it, because probe response has to go with
         * SSID even in hidden case
         */
        PopulateDot11fSSID(pMac, &psessionEntry->ssId, &prb_rsp->SSID);
    }
    /* supported rates */
    if(beacon1->SuppRates.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_RATESET_EID);
        vos_mem_copy((void *)&prb_rsp->SuppRates, (void *)&beacon1->SuppRates,
                     sizeof(beacon1->SuppRates));

    }
    /* DS Parameter set */
    if(beacon1->DSParams.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_DS_PARAM_SET_EID);
        vos_mem_copy((void *)&prb_rsp->DSParams, (void *)&beacon1->DSParams,
                      sizeof(beacon1->DSParams));

    }

    /* IBSS params will not be present in the Beacons transmitted by AP */

    return eSIR_SUCCESS;
}

void limUpdateProbeRspTemplateIeBitmapBeacon2(tpAniSirGlobal pMac,
                                              tDot11fBeacon2* beacon2,
                                              tANI_U32* DefProbeRspIeBitmap,
                                              tDot11fProbeResponse* prb_rsp)
{
    /* IBSS parameter set - will not be present in probe response tx by AP */
    /* country */
    if(beacon2->Country.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_COUNTRY_EID);
        vos_mem_copy((void *)&prb_rsp->Country, (void *)&beacon2->Country,
                     sizeof(beacon2->Country));

    }
    /* Power constraint */
    if(beacon2->PowerConstraints.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_PWR_CONSTRAINT_EID);
        vos_mem_copy((void *)&prb_rsp->PowerConstraints, (void *)&beacon2->PowerConstraints,
                     sizeof(beacon2->PowerConstraints));

    }
    /* Channel Switch Announcement SIR_MAC_CHNL_SWITCH_ANN_EID */
    if(beacon2->ChanSwitchAnn.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_CHNL_SWITCH_ANN_EID);
        vos_mem_copy((void *)&prb_rsp->ChanSwitchAnn, (void *)&beacon2->ChanSwitchAnn,
                     sizeof(beacon2->ChanSwitchAnn));

    }

    /* EXT Channel Switch Announcement CHNL_EXTENDED_SWITCH_ANN_EID*/
    if (beacon2->ext_chan_switch_ann.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,
               SIR_MAC_CHNL_EXTENDED_SWITCH_ANN_EID);
        vos_mem_copy((void *)&prb_rsp->ext_chan_switch_ann,
            (void *)&beacon2->ext_chan_switch_ann,
             sizeof(beacon2->ext_chan_switch_ann));
    }
    /* Supported operating class */
    if(beacon2->SuppOperatingClasses.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_OPERATING_CLASS_EID);
        vos_mem_copy((void *)&prb_rsp->SuppOperatingClasses,
                     (void *)&beacon2->SuppOperatingClasses,
                     sizeof(beacon2->SuppOperatingClasses));
    }

    if(beacon2->QComVendorIE.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap, SIR_MAC_QCOM_VENDOR_EID);
        vos_mem_copy((void *)&prb_rsp->QComVendorIE,
                     (void *)&beacon2->QComVendorIE,
                     sizeof(beacon2->QComVendorIE));
    }

    /* ERP information */
    if(beacon2->ERPInfo.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_ERP_INFO_EID);
        vos_mem_copy((void *)&prb_rsp->ERPInfo, (void *)&beacon2->ERPInfo,
                     sizeof(beacon2->ERPInfo));

    }
    /* Extended supported rates */
    if(beacon2->ExtSuppRates.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_EXTENDED_RATE_EID);
        vos_mem_copy((void *)&prb_rsp->ExtSuppRates, (void *)&beacon2->ExtSuppRates,
                     sizeof(beacon2->ExtSuppRates));

    }

    /* WPA */
    if(beacon2->WPA.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_WPA_EID);
        vos_mem_copy((void *)&prb_rsp->WPA, (void *)&beacon2->WPA,
                     sizeof(beacon2->WPA));

    }

    /* RSN */
    if(beacon2->RSNOpaque.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_RSN_EID);
        vos_mem_copy((void *)&prb_rsp->RSNOpaque, (void *)&beacon2->RSNOpaque,
                     sizeof(beacon2->RSNOpaque));
    }

    /* EDCA Parameter set */
    if(beacon2->EDCAParamSet.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_EDCA_PARAM_SET_EID);
        vos_mem_copy((void *)&prb_rsp->EDCAParamSet, (void *)&beacon2->EDCAParamSet,
                     sizeof(beacon2->EDCAParamSet));

    }
    /* Vendor specific - currently no vendor specific IEs added */
    /* Requested IEs - currently we are not processing this will be added later */
    //HT capability IE
    if(beacon2->HTCaps.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_HT_CAPABILITIES_EID);
        vos_mem_copy((void *)&prb_rsp->HTCaps, (void *)&beacon2->HTCaps,
                     sizeof(beacon2->HTCaps));
    }
    // HT Info IE
    if(beacon2->HTInfo.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_HT_INFO_EID);
        vos_mem_copy((void *)&prb_rsp->HTInfo, (void *)&beacon2->HTInfo,
                     sizeof(beacon2->HTInfo));
    }

#ifdef WLAN_FEATURE_11AC
    if(beacon2->VHTCaps.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_VHT_CAPABILITIES_EID);
        vos_mem_copy((void *)&prb_rsp->VHTCaps, (void *)&beacon2->VHTCaps,
                     sizeof(beacon2->VHTCaps));
    }
    if(beacon2->VHTOperation.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_VHT_OPERATION_EID);
        vos_mem_copy((void *)&prb_rsp->VHTOperation, (void *)&beacon2->VHTOperation,
                     sizeof(beacon2->VHTOperation));
    }
    if(beacon2->VHTExtBssLoad.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_VHT_EXT_BSS_LOAD_EID);
        vos_mem_copy((void *)&prb_rsp->VHTExtBssLoad, (void *)&beacon2->VHTExtBssLoad,
                     sizeof(beacon2->VHTExtBssLoad));
    }
#endif

    //WMM IE
    if(beacon2->WMMParams.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_WPA_EID);
        vos_mem_copy((void *)&prb_rsp->WMMParams, (void *)&beacon2->WMMParams,
                     sizeof(beacon2->WMMParams));
    }
    //WMM capability - most of the case won't be present
    if(beacon2->WMMCaps.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_WPA_EID);
        vos_mem_copy((void *)&prb_rsp->WMMCaps, (void *)&beacon2->WMMCaps,
                     sizeof(beacon2->WMMCaps));
    }

    /* Extended Capability */
    if (beacon2->ExtCap.present) {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap, DOT11F_EID_EXTCAP);
        vos_mem_copy((void *)&prb_rsp->ExtCap, (void *)&beacon2->ExtCap,
                     sizeof(beacon2->ExtCap));
    }

}

void SetProbeRspIeBitmap(tANI_U32* IeBitmap,tANI_U32 pos)
{
    tANI_U32 index,temp;

    index = pos >> 5;
    if(index >= 8 )
    {
        return;
    }
    temp = IeBitmap[index];

    temp |= 1 << (pos & 0x1F);

    IeBitmap[index] = temp;
}



// --------------------------------------------------------------------
/**
 * writeBeaconToMemory
 *
 * FUNCTION:
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param None
 * @param size    Size of the beacon to write to memory
 * @param length Length field of the beacon to write to memory
 * @return None
 */

void writeBeaconToMemory(tpAniSirGlobal pMac, tANI_U16 size, tANI_U16 length, tpPESession psessionEntry)
{
    tANI_U16          i;
    tpAniBeaconStruct pBeacon;

    // copy end of beacon only if length > 0
    if (length > 0)
    {
        for (i=0; i < psessionEntry->schBeaconOffsetEnd; i++)
            psessionEntry->pSchBeaconFrameBegin[size++] = psessionEntry->pSchBeaconFrameEnd[i];
    }

    // Update the beacon length
    pBeacon = (tpAniBeaconStruct) psessionEntry->pSchBeaconFrameBegin;
    // Do not include the beaconLength indicator itself
    if (length == 0)
    {
        pBeacon->beaconLength = 0;
        // Dont copy entire beacon, Copy length field alone
        size = 4;
    }
    else
        pBeacon->beaconLength = (tANI_U32) size - sizeof( tANI_U32 );

    // write size bytes from pSchBeaconFrameBegin
    PELOG2(schLog(pMac, LOG2, FL("Beacon size - %d bytes"), size);)
    PELOG2(sirDumpBuf(pMac, SIR_SCH_MODULE_ID, LOG2, psessionEntry->pSchBeaconFrameBegin, size);)

    if (! pMac->sch.schObject.fBeaconChanged)
        return;

    pMac->sch.gSchGenBeacon = 1;
    if (pMac->sch.gSchGenBeacon)
    {
        pMac->sch.gSchBeaconsSent++;

        //
        // Copy beacon data to SoftMAC shared memory...
        // Do this by sending a message to HAL
        //

        size = (size + 3) & (~3);
        if( eSIR_SUCCESS != schSendBeaconReq( pMac, psessionEntry->pSchBeaconFrameBegin,
                                              size, psessionEntry))
            PELOGE(schLog(pMac, LOGE, FL("schSendBeaconReq() returned an error (zsize %d)"), size);)
        else
        {
            pMac->sch.gSchBeaconsWritten++;
        }
    }
    pMac->sch.schObject.fBeaconChanged = 0;
}

// --------------------------------------------------------------------
/**
 * @function: SchProcessPreBeaconInd
 *
 * @brief : Process the PreBeacon Indication from the Lim
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param : pMac - tpAniSirGlobal
 *
 * @return None
 */

void
schProcessPreBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
{
    tpBeaconGenParams  pMsg = (tpBeaconGenParams)limMsg->bodyptr;
    tANI_U32 beaconSize;
    tpPESession psessionEntry;
    tANI_U8 sessionId;

    if((psessionEntry = peFindSessionByBssid(pMac,pMsg->bssId, &sessionId))== NULL)
    {
        PELOGE(schLog(pMac, LOGE, FL("session lookup fails"));)
        goto end;
    }


    beaconSize = psessionEntry->schBeaconOffsetBegin;

    // If SME is not in normal mode, no need to generate beacon
    if (psessionEntry->limSmeState  != eLIM_SME_NORMAL_STATE)
    {
        PELOGE(schLog(pMac, LOG1, FL("PreBeaconInd received in invalid state: %d"), psessionEntry->limSmeState);)
        goto end;
    }

    switch(GET_LIM_SYSTEM_ROLE(psessionEntry)) {
    case eLIM_STA_IN_IBSS_ROLE:
    case eLIM_BT_AMP_AP_ROLE:
    case eLIM_BT_AMP_STA_ROLE:
        /* Generate IBSS parameter set */
        if(psessionEntry->statypeForBss == STA_ENTRY_SELF)
            writeBeaconToMemory(pMac, (tANI_U16) beaconSize,
                               (tANI_U16)beaconSize, psessionEntry);
        else
            PELOGE(schLog(pMac, LOGE, FL("can not send beacon for PEER session entry"));)
        break;

    case eLIM_AP_ROLE: {
         tANI_U8 *ptr = &psessionEntry->pSchBeaconFrameBegin[psessionEntry->schBeaconOffsetBegin];
         tANI_U16 timLength = 0;

         if (psessionEntry->statypeForBss == STA_ENTRY_SELF) {
             pmmGenerateTIM(pMac, &ptr, &timLength, psessionEntry->dtimPeriod);
             beaconSize += 2 + timLength;
             writeBeaconToMemory(pMac, (tANI_U16) beaconSize,
                                (tANI_U16)beaconSize, psessionEntry);
         } else
             PELOGE(schLog(pMac, LOGE, FL("can not send beacon for PEER session entry"));)
         }
         break;

    default:
        PELOGE(schLog(pMac, LOGE,
               FL("Error-PE has Receive PreBeconGenIndication when System is in %d role"),
               GET_LIM_SYSTEM_ROLE(psessionEntry));)
    }

end:
      vos_mem_free(pMsg);

}
