/*
 * Copyright (c) 2012-2013, 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.
 */
/*
 * Copyright (c) 2012, 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.
 */



/*
 * Airgo Networks, Inc proprietary. All rights reserved.
 * 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 "wniCfgSta.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)
{
    tSirRetStatus status = eSIR_FAILURE;
    tANI_U32 present, len;
    tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN];
    
     if((status = wlan_cfgGetInt(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
                                 &present)) != eSIR_SUCCESS)
    {
        limLog(pMac, LOGP, FL("Unable to get WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
        return status;
    }

    if(present)
    {
        if((status = wlan_cfgGetStrLen(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA,
                                       &len)) != eSIR_SUCCESS)
        {
            limLog(pMac, LOGP,
                FL("Unable to get WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA length"));
            return status;
        }

        if(len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len && 
          ((len + *nBytes) <= maxBeaconSize))
        {
            if((status = wlan_cfgGetStr(pMac, 
                          WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0], &len))
                          == eSIR_SUCCESS)
            {
                tANI_U8* pP2pIe = limGetP2pIEPtr(pMac, &addIE[0], len);
                if(pP2pIe != NULL)
                {
                    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 + len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN)
                        {
                            vos_mem_copy(&addIE[len], noaStream, noaLen);
                            len += noaLen;
                            /* Update IE Len */
                            pP2pIe[1] += noaLen;
                        }
                        else
                        {
                            limLog(pMac, LOGE,
                               FL("Not able to insert NoA because of length constraint"));
                        }
                    }
                }
                vos_mem_copy(pFrame, &addIE[0], len);
                *nBytes = *nBytes + len;
            }
        }
    }

    return status;
}

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

tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEntry)
{
    tpAniBeaconStruct pBeacon = (tpAniBeaconStruct)
                                   pMac->sch.schObject.gSchBeaconFrameBegin;
    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;

    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;
    
    /* Knocking out Global pMac update */
    /* limGetMyMacAddr(pMac, mac->sa); */
    /* limGetBssid(pMac, mac->bssId); */

    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 timestamp (it'll be updated later).

    pBcn1->BeaconInterval.interval = pMac->sch.schObject.gSchBeaconInterval;
    PopulateDot11fCapabilities( pMac, &pBcn1->Capabilities, psessionEntry );
    if (psessionEntry->ssidHidden)
    {
       pBcn1->SSID.present = 1; //rest of the fileds are 0 for hidden ssid
    }
    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    = pMac->sch.schObject.gSchBeaconFrameBegin + offset;

    if((psessionEntry->limSystemRole == eLIM_AP_ROLE) 
        && (psessionEntry->proxyProbeRspEn))
    {
        /* 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);

        /* Can be efficiently updated whenever new IE added  in Probe response in future */
        limUpdateProbeRspTemplateIeBitmapBeacon1(pMac,pBcn1,&psessionEntry->DefProbeRspIeBitmap[0],
                                                &psessionEntry->probeRespFrame);
    }

    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);
    pMac->sch.schObject.gSchBeaconOffsetBegin = offset + ( tANI_U16 )nBytes;
    schLog( pMac, LOG1, FL("Initialized beacon begin, offset %d"), offset );

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

    
    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);
    }


    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)
    {        
        limLog( pMac, LOGW, FL("Populate VHT IEs in Beacon"));
        PopulateDot11fVHTCaps( pMac, &pBcn2->VHTCaps );
        PopulateDot11fVHTOperation( pMac, &pBcn2->VHTOperation);
        // we do not support multi users yet
        //PopulateDot11fVHTExtBssLoad( pMac, &bcn2.VHTExtBssLoad);
        PopulateDot11fExtCap( pMac, &pBcn2->ExtCap);
        if(psessionEntry->gLimOperatingMode.present)
            PopulateDot11fOperatingMode( pMac, &pBcn2->OperatingMode, psessionEntry );
    }
#endif

    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 );
    }

    if(psessionEntry->limWmeEnabled)
    {
        PopulateDot11fWMM( pMac, &pBcn2->WMMInfoAp, &pBcn2->WMMParams, &pBcn2->WMMCaps, psessionEntry);
    }
    if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
    {
        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)
            limLog(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((psessionEntry->limSystemRole == eLIM_AP_ROLE) 
        && (psessionEntry->proxyProbeRspEn))
    {
        /* 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));
            }
        }

    }

    nStatus = dot11fPackBeacon2( pMac, pBcn2,
                                 pMac->sch.schObject.gSchBeaconFrameEnd,
                                 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);
      return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( nStatus ) )
    {
      schLog( pMac, LOGE, FL("There were warnings while packing a tDo"
                             "t11fBeacon2 (0x%08x.)."), nStatus );
    }

    pExtraIe = pMac->sch.schObject.gSchBeaconFrameEnd + nBytes;
    extraIeOffset = nBytes;

    //TODO: Append additional IE here.
    schAppendAddnIE(pMac, psessionEntry, 
                    pMac->sch.schObject.gSchBeaconFrameEnd + nBytes,
                    SCH_MAX_BEACON_SIZE, &nBytes);

    pMac->sch.schObject.gSchBeaconOffsetEnd = ( 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 = 
                    pMac->sch.schObject.gSchBeaconOffsetBegin + TIM_IE_SIZE +
                    extraIeOffset + p2pIeOffset;
    }
    else
    {
       pMac->sch.schObject.p2pIeOffset = 0;
    }

    schLog( pMac, LOG1, FL("Initialized beacon end, offset %d"),
            pMac->sch.schObject.gSchBeaconOffsetEnd );

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

void limUpdateProbeRspTemplateIeBitmapBeacon1(tpAniSirGlobal pMac,
                                              tDot11fBeacon1* beacon1,
                                              tANI_U32* DefProbeRspIeBitmap,
                                              tDot11fProbeResponse* prb_rsp)
{
    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 */
        PopulateDot11fSSID2( pMac, &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 */
}

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 Annoouncement 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));

    }
    /* 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));
    }
/*
    // BSS load
    if(beacon2->QBSSLoad.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_QBSS_LOAD_EID);
    }
*/
    /* 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));
    }

}

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 < pMac->sch.schObject.gSchBeaconOffsetEnd; i++)
            pMac->sch.schObject.gSchBeaconFrameBegin[size++] = pMac->sch.schObject.gSchBeaconFrameEnd[i];
    }
    
    // Update the beacon length
    pBeacon = (tpAniBeaconStruct) pMac->sch.schObject.gSchBeaconFrameBegin;
    // 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 gSchBeaconFrameBegin
    PELOG2(schLog(pMac, LOG2, FL("Beacon size - %d bytes"), size);)
    PELOG2(sirDumpBuf(pMac, SIR_SCH_MODULE_ID, LOG2, pMac->sch.schObject.gSchBeaconFrameBegin, 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, pMac->sch.schObject.gSchBeaconFrameBegin,
                                              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 = pMac->sch.schObject.gSchBeaconOffsetBegin;
    tpPESession psessionEntry;
    tANI_U8 sessionId;

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


    // 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(psessionEntry->limSystemRole){

    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 = &pMac->sch.schObject.gSchBeaconFrameBegin[pMac->sch.schObject.gSchBeaconOffsetBegin];
         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"),
               psessionEntry->limSystemRole);)
    }

end:
      vos_mem_free(pMsg);

}
