/*
 * 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 "wniCfgAp.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};

#ifdef ANI_PRODUCT_TYPE_AP

static void
specialBeaconProcessing(tpAniSirGlobal pMac, tANI_U32 beaconSize);
#endif

#if defined(WLAN_FEATURE_P2P)
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(palEqualMemory(NULL, (void *)(pExtraIe+2), &P2pOui, sizeof(P2pOui)))
            {
                status = eSIR_SUCCESS;
                break;
            }
        }

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

     return status;
}
#endif

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)
            {
#ifdef WLAN_FEATURE_P2P
                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"));
                        }
                    }
                }
#endif
                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;
#ifdef WLAN_FEATURE_P2P
    tANI_U8  *pExtraIe = NULL;
    tANI_U32 extraIeLen =0;
    tANI_U16 extraIeOffset = 0;
    tANI_U16 p2pIeOffset = 0;
    tSirRetStatus status = eSIR_SUCCESS;
#endif

    status = palAllocateMemory(pMac->hHdd, (void **)&pBcn1, sizeof(tDot11fBeacon1));
    if(status != eSIR_SUCCESS)
    {
        schLog(pMac, LOGE, FL("Failed to allocate memory\n") );
        return eSIR_FAILURE;
    }

    status = palAllocateMemory(pMac->hHdd, (void **)&pBcn2, sizeof(tDot11fBeacon2));
    if(status != eSIR_SUCCESS)
    {
        schLog(pMac, LOGE, FL("Failed to allocate memory\n") );
        palFreeMemory(pMac->hHdd, pBcn1);
        return eSIR_FAILURE;
    }

    status = palAllocateMemory(pMac->hHdd, (void **)&pWscProbeRes, sizeof(tDot11fIEWscProbeRes));
    if(status != eSIR_SUCCESS)
    {
        schLog(pMac, LOGE, FL("Failed to allocate memory\n") );
        palFreeMemory(pMac->hHdd, pBcn1);
        palFreeMemory(pMac->hHdd, pBcn2);
        return eSIR_FAILURE;
    }

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

    /*
     * First set the fixed fields
     */

    // set the TFP headers

    // set the mac header
    palZeroMemory( pMac->hHdd, ( tANI_U8*) &pBeacon->macHdr, sizeof( tSirMacMgmtHdr ) );
    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); */

    palCopyMemory(pMac->hHdd, mac->sa, psessionEntry->selfMacAddr, sizeof(psessionEntry->selfMacAddr));
    palCopyMemory(pMac->hHdd, mac->bssId, psessionEntry->bssId, sizeof (psessionEntry->bssId));

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

    /*
     * Now set the beacon body
     */

    palZeroMemory( pMac->hHdd, ( tANI_U8*) pBcn1, sizeof( tDot11fBeacon1 ) );

    // 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 */
        palZeroMemory( pMac->hHdd, ( tANI_U8* )&(psessionEntry->DefProbeRspIeBitmap), (sizeof( tANI_U32 ) * 8));

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

        /* 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.).\n"), nStatus );
      palFreeMemory(pMac->hHdd, pBcn1);
      palFreeMemory(pMac->hHdd, pBcn2);
      palFreeMemory(pMac->hHdd, pWscProbeRes);
      return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( nStatus ) )
    {
      schLog( pMac, LOGE, FL("There were warnings while packing a tDo"
                             "t11fBeacon1 (0x%08x.).\n"), nStatus );
    }
    /*changed  to correct beacon corruption */
    palZeroMemory( pMac->hHdd, ( tANI_U8*) pBcn2, sizeof( tDot11fBeacon2 ) );
    pMac->sch.schObject.gSchBeaconOffsetBegin = offset + ( tANI_U16 )nBytes;
    schLog( pMac, LOG1, FL("Initialized beacon begin, offset %d\n"), 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);
    }

#ifdef ANI_PRODUCT_TYPE_AP
    if( psessionEntry->lim11hEnable && (eLIM_QUIET_RUNNING == psessionEntry->gLimSpecMgmt.quietState))
    {
      PopulateDot11fQuiet( pMac, &pBcn2->Quiet );
    }

    /* If 11h is enabled, and AP is in the state of changing either the
     * primary channel, or both primary & secondary channel, and the
     * channel switch count is still being decremented, then AP shall
     * populate the 802.11h channel switch IE in its Beacons and Probe
     * Responses.
     */
    if ( (psessionEntry->lim11hEnable) &&
         (psessionEntry->gLimChannelSwitch.switchCount != 0) &&
         (psessionEntry->gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING))

    {
      PopulateDot11fChanSwitchAnn( pMac, &pBcn2->ChanSwitchAnn,psessionEntry );
      PopulateDot11fExtChanSwitchAnn(pMac, &pBcn2->ExtChanSwitchAnn,psessionEntry);
#ifdef WLAN_FEATURE_11AC
      if(psessionEntry->vhtCapability)
          PopulateDot11fWiderBWChanSwitchAnn(pMac, &pBcn2->WiderBWChanSwitchAnn, psessionEntry );
#endif

    }
#endif

    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\n"));
        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 );
          PopulateDot11fRSN( pMac, &psessionEntry->pLimStartBssReq->rsnIE,
                       &pBcn2->RSN );
    }

    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\n", 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);
                palCopyMemory(pMac->hHdd,
                            (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.).\n"), nStatus );
      palFreeMemory(pMac->hHdd, pBcn1);
      palFreeMemory(pMac->hHdd, pBcn2);
      palFreeMemory(pMac->hHdd, pWscProbeRes);
      return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( nStatus ) )
    {
      schLog( pMac, LOGE, FL("There were warnings while packing a tDo"
                             "t11fBeacon2 (0x%08x.).\n"), nStatus );
    }

#if defined(WLAN_FEATURE_P2P)
    pExtraIe = pMac->sch.schObject.gSchBeaconFrameEnd + nBytes;
    extraIeOffset = nBytes;
#endif

    //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;

#if defined(WLAN_FEATURE_P2P)
    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;
    }
#endif

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

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

void limUpdateProbeRspTemplateIeBitmapBeacon1(tpAniSirGlobal pMac,
                                              tDot11fBeacon1* beacon1,
                                              tANI_U32* DefProbeRspIeBitmap,
                                              tDot11fProbeResponse* prb_rsp)
{
    prb_rsp->BeaconInterval = beacon1->BeaconInterval;
    palCopyMemory(pMac->hHdd,(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);
        palCopyMemory(pMac->hHdd,(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);
        palCopyMemory(pMac->hHdd,(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);
        palCopyMemory(pMac->hHdd,(void *)&prb_rsp->Country,
                            (void *)&beacon2->Country,
                            sizeof(beacon2->Country));

    }
    /* Power constraint */
    if(beacon2->PowerConstraints.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_PWR_CONSTRAINT_EID);
        palCopyMemory(pMac->hHdd,(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);
        palCopyMemory(pMac->hHdd,(void *)&prb_rsp->ChanSwitchAnn,
                            (void *)&beacon2->ChanSwitchAnn,
                            sizeof(beacon2->ChanSwitchAnn));

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

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

    }

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

    }

    /* RSN */
    if(beacon2->RSN.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_RSN_EID);
        palCopyMemory(pMac->hHdd,(void *)&prb_rsp->RSN,
                            (void *)&beacon2->RSN,
                            sizeof(beacon2->RSN));

    }
/*
    // 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);
        palCopyMemory(pMac->hHdd,(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);
        palCopyMemory(pMac->hHdd,(void *)&prb_rsp->HTCaps,
                            (void *)&beacon2->HTCaps,
                            sizeof(beacon2->HTCaps));
    }
    // HT Info IE
    if(beacon2->HTInfo.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_HT_INFO_EID);
        palCopyMemory(pMac->hHdd,(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);
        palCopyMemory(pMac->hHdd,(void *)&prb_rsp->VHTCaps,
                            (void *)&beacon2->VHTCaps,
                            sizeof(beacon2->VHTCaps));
    }
    if(beacon2->VHTOperation.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_VHT_OPERATION_EID);
        palCopyMemory(pMac->hHdd,(void *)&prb_rsp->VHTOperation,
                            (void *)&beacon2->VHTOperation,
                            sizeof(beacon2->VHTOperation));
    }
    if(beacon2->VHTExtBssLoad.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_VHT_EXT_BSS_LOAD_EID);
        palCopyMemory(pMac->hHdd,(void *)&prb_rsp->VHTExtBssLoad,
                            (void *)&beacon2->VHTExtBssLoad,
                            sizeof(beacon2->VHTExtBssLoad));
    }
#endif

    //WMM IE
    if(beacon2->WMMParams.present)
    {
        SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_WPA_EID);
        palCopyMemory(pMac->hHdd,(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);
        palCopyMemory(pMac->hHdd,(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;
}


#ifdef ANI_PRODUCT_TYPE_AP

//----------------------------
/**
  *     @function : schUpdateCfpParam
  *     @brief      : Generate the CFP Parameter Set
  *     
  *     @param    :  pMac - tpAniSirGlobal
  *                       ptr    - Pointer to the BeaconFrame
  *                       pbeaconSize - The beaconSize
  *
  *     @return    :  Return the Updated Ptrlocation
  */
static tANI_U8 *
__schUpdateCfpParam(tpAniSirGlobal pMac, tANI_U8 *ptr, tANI_U32 *pbeaconSize)
{  
    tANI_U32 val;

    *ptr++ = SIR_MAC_CF_PARAM_SET_EID;
    *ptr++ = SIR_MAC_CF_PARAM_SET_EID_MIN;

    wlan_cfgGetInt(pMac, WNI_CFG_CFP_PERIOD, &val);
    if (++pMac->sch.schObject.gSchCFPCount == val)
        pMac->sch.schObject.gSchCFPCount = 0;

    *ptr++ = pMac->sch.schObject.gSchCFPCount;
    *ptr++ = (tANI_U8)val;

    wlan_cfgGetInt(pMac, WNI_CFG_CFP_MAX_DURATION, &val);
    pMac->sch.schObject.gSchCFPMaxDuration = (tANI_U8)val;

    sirStoreU16(ptr, (tANI_U16)val);
    ptr += 2;

    if (pMac->sch.schObject.gSchCFPCount == 0)
        pMac->sch.schObject.gSchCFPDurRemaining = pMac->sch.schObject.gSchCFPMaxDuration;
    else if (pMac->sch.schObject.gSchCFPDurRemaining > pMac->sch.schObject.gSchBeaconInterval)
        pMac->sch.schObject.gSchCFPDurRemaining -= pMac->sch.schObject.gSchBeaconInterval;
    else
        pMac->sch.schObject.gSchCFPDurRemaining = 0;

    sirStoreU16(ptr, pMac->sch.schObject.gSchCFPDurRemaining);
    ptr += 2;

    (*pbeaconSize) += 2 + SIR_MAC_CF_PARAM_SET_EID_MIN;

    return ptr;
}

#endif

// --------------------------------------------------------------------
/**
 * 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\n"), 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)\n"), 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\n"));)
        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\n"), 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\n"));)
        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\n"));)
         }
     break;

#ifdef ANI_PRODUCT_TYPE_AP
    case eLIM_AP_ROLE: 
    {
        tANI_U8 *ptr = &pMac->sch.schObject.gSchBeaconFrameBegin[pMac->sch.schObject.gSchBeaconOffsetBegin];
        tANI_U16 timLength = 0;

        if (pMac->sch.schObject.gSchCFPEnabled)
          ptr = __schUpdateCfpParam( pMac, ptr, &beaconSize);

        // generate TIM
        pmmGenerateTIM(pMac, &ptr, &timLength);
        beaconSize += 2 + timLength;

        /**
        * Safe to call this each time.
        * Based on the requirement for updating the
        * fixed beacon fields, this routine will
        * appropriately update the fixed fields
        */
        specialBeaconProcessing(pMac, beaconSize);
        writeBeaconToMemory(pMac, beaconSize, beaconSize, psessionEntry);
        pmmHandleTimBasedDisassociation( pMac, psessionEntry );
    }
    break;
#endif

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

end:
    palFreeMemory(pMac->hHdd, (void*)pMsg);

}

/**-------------------------------------------------------------
 \fn       specialBeaconProcessing
 \brief   To add/update channel switch IE/ Quiet IE in beacons.
          And also to resume transmission and measurement after
          switching the channel.
      
 \param   pMac
 \param   beaconSize  Size of the beacon
 \return   NONE
 --------------------------------------------------------------*/
#ifdef ANI_PRODUCT_TYPE_AP

static void
specialBeaconProcessing( tpAniSirGlobal pMac, tANI_U32 beaconSize)
{

    tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
    tANI_BOOLEAN fBeaconChanged = eANI_BOOLEAN_FALSE;

    fBeaconChanged = limUpdateQuietIEInBeacons( pMac );

    if((pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_BEGIN) ||
       (pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_END))
    {
        fBeaconChanged = eANI_BOOLEAN_TRUE;
    }


    /*******************************
     * Processing Channel Switch IE
     *******************************/
    if (pMac->lim.gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING)
    {
        fBeaconChanged = eANI_BOOLEAN_TRUE;

#if 0
        // If the station doesn't support 11h or have link monitoring enabled,
        // AP has to send disassoc frame to indicate station before going
        // to new channel. Otherwise station wont connect to AP in new channel.
        if (pMac->lim.gLimChannelSwitch.switchCount == 1)
        {
            if((pMac->lim.gLimChannelSwitch.state
                == eLIM_CHANNEL_SWITCH_PRIMARY_ONLY) ||
                (pMac->lim.gLimChannelSwitch.state
                == eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY))
            {
                tSirMacAddr   bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

                limSendDisassocMgmtFrame(pMac,
                                   eSIR_MAC_DISASSOC_LEAVING_BSS_REASON,
                                   bcAddr);
            }
        }
#endif
        if (pMac->lim.gLimChannelSwitch.switchCount == 0)
        {
            
            /* length is set to 0, so that no beacon is transmitted without channel switch IE
                       * before switching  to new channel */
            pMac->sch.schObject.fBeaconChanged = 1;
            writeBeaconToMemory(pMac, beaconSize, 0, psessionEntry);
            schSetFixedBeaconFields(pMac,psessionEntry);

           PELOG3(limLog(pMac, LOG3, FL("Channel switch state = %d\n"), pMac->lim.gLimChannelSwitch.state);)
            switch(pMac->lim.gLimChannelSwitch.state)
            {
                case eLIM_CHANNEL_SWITCH_PRIMARY_ONLY:
                    limSwitchPrimaryChannel(pMac, pMac->lim.gLimChannelSwitch.primaryChannel);
                    break;
                case eLIM_CHANNEL_SWITCH_SECONDARY_ONLY:
                    limSwitchPrimarySecondaryChannel(pMac, psessionEntry,
                                             psessionEntry->currentOperChannel,
                                             pMac->lim.gLimChannelSwitch.secondarySubBand);
                    break;
                case eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY:
                    limSwitchPrimarySecondaryChannel(pMac, psessionEntry,
                                             pMac->lim.gLimChannelSwitch.primaryChannel,
                                             pMac->lim.gLimChannelSwitch.secondarySubBand);
                    break;
                case eLIM_CHANNEL_SWITCH_IDLE:
                    PELOGE(schLog(pMac, LOGE, FL("incorrect state - CHANNEL_SWITCH_IDLE\n"));)
                    break;

                default:
                    break;
            }
            pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_IDLE;

            limSendSmeRsp(pMac, eWNI_SME_SWITCH_CHL_RSP, eSIR_SME_SUCCESS);

            limFrameTransmissionControl(pMac, eLIM_TX_BSS_BUT_BEACON, eLIM_RESUME_TX);
            /* Flag to indicate 11h channel switch is done. */
            pMac->lim.gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_INIT;
            pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
            LIM_SET_RADAR_DETECTED(pMac, eANI_BOOLEAN_FALSE);
            
            if (pMac->lim.gpLimMeasReq)
                limReEnableLearnMode(pMac);

            return;
        }
    }

    if (fBeaconChanged)
    {
        schSetFixedBeaconFields(pMac,psessionEntry);

        if (pMac->lim.gLimChannelSwitch.switchCount > 0)
            pMac->lim.gLimChannelSwitch.switchCount--;
    }
}
#endif


