/*
 * Copyright (c) 2011-2015, 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 utilsParser.cc contains the code for parsing
 * 802.11 messages.
 * Author:        Pierre Vandwalle
 * Date:          03/18/02
 * History:-
 * Date           Modified by    Modification Information
 * --------------------------------------------------------------------
 *
 */

#include "aniGlobal.h"
#include "utilsParser.h"
#include "limSerDesUtils.h"

void ConvertSSID(tpAniSirGlobal pMac,
                       tSirMacSSid   *pOld,
                       tDot11fIESSID    *pNew)
{
    pOld->length = pNew->num_ssid;
    vos_mem_copy( pOld->ssId, pNew->ssid, pNew->num_ssid );
}

void ConvertSuppRates(tpAniSirGlobal   pMac,
                            tSirMacRateSet  *pOld,
                            tDot11fIESuppRates *pNew)
{
    pOld->numRates = pNew->num_rates;
    vos_mem_copy( pOld->rate, pNew->rates, pNew->num_rates );
}

void ConvertExtSuppRates(tpAniSirGlobal      pMac,
                               tSirMacRateSet     *pOld,
                               tDot11fIEExtSuppRates *pNew)
{
    pOld->numRates = pNew->num_rates;
    vos_mem_copy(  pOld->rate, pNew->rates, pNew->num_rates );
}


void ConvertQOSCaps(tpAniSirGlobal                pMac,
                          tSirMacQosCapabilityIE *pOld,
                          tDot11fIEQOSCapsAp     *pNew)
{
    pOld->type    = 46;
    pOld->length  = 1;

    pOld->qosInfo.count   = pNew->count;   
}


void ConvertQOSCapsStation(tpAniSirGlobal              pMac,
                           tSirMacQosCapabilityStaIE  *pOld,
                           tDot11fIEQOSCapsStation    *pNew)
{
    pOld->type    = 46;
    pOld->length  = 1;

    pOld->qosInfo.moreDataAck = pNew->more_data_ack;
    pOld->qosInfo.maxSpLen    = pNew->max_sp_length;
    pOld->qosInfo.qack        = pNew->qack;
    pOld->qosInfo.acbe_uapsd  = pNew->acbe_uapsd;
    pOld->qosInfo.acbk_uapsd  = pNew->acbk_uapsd;
    pOld->qosInfo.acvi_uapsd  = pNew->acvi_uapsd;
    pOld->qosInfo.acvo_uapsd  = pNew->acvo_uapsd;    
}

tSirRetStatus ConvertWPA(tpAniSirGlobal  pMac,
                               tSirMacWpaInfo *pOld,
                               tDot11fIEWPA      *pNew)
{
    // This is awful, I know, but the old code just rammed the IE into an
    // array...
    tANI_U8 buffer[257];
    tANI_U32 status, written = 0, nbuffer = 257;
    status = dot11fPackIeWPA( pMac, pNew, buffer, nbuffer, &written );
    if ( DOT11F_FAILED( status ) )
    {
        dot11fLog(pMac, LOG2, FL("Failed to re-pack the WPA IE (0x%0x"
                                 "8).\n"), status);
        return eSIR_FAILURE;
    }

    pOld->length = (tANI_U8)written - 2;
    vos_mem_copy( pOld->info, buffer + 2, pOld->length );

    return eSIR_SUCCESS;
}

tSirRetStatus ConvertWPAOpaque( tpAniSirGlobal      pMac,
                                tSirMacWpaInfo     *pOld,
                                tDot11fIEWPAOpaque *pNew )
{
    // This is awful, I know, but the old code just rammed the IE into
    // an opaque array.  Note that we need to explicitly add the OUI!
    pOld->length    = pNew->num_data + 4;
    pOld->info[ 0 ] = 0x00;
    pOld->info[ 1 ] = 0x50;
    pOld->info[ 2 ] = 0xf2;
    pOld->info[ 3 ] = 0x01;
    vos_mem_copy( pOld->info + 4, pNew->data, pNew->num_data );

    return eSIR_SUCCESS;
}

tSirRetStatus ConvertWscOpaque( tpAniSirGlobal      pMac,
                                tSirAddie           *pOld,
                                tDot11fIEWscIEOpaque *pNew )
{
    // This is awful, I know, but the old code just rammed the IE into
    // an opaque array.  Note that we need to explicitly add the vendorIE and OUI !
    tANI_U8 curAddIELen = pOld->length; 

    pOld->length    = curAddIELen + pNew->num_data + 6;
    pOld->addIEdata[ curAddIELen++ ] = 0xdd;
    pOld->addIEdata[ curAddIELen++ ] = pNew->num_data + 4;
    pOld->addIEdata[ curAddIELen++ ] = 0x00;
    pOld->addIEdata[ curAddIELen++ ] = 0x50;
    pOld->addIEdata[ curAddIELen++ ] = 0xf2;
    pOld->addIEdata[ curAddIELen++ ] = 0x04;
    vos_mem_copy( pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data );

    return eSIR_SUCCESS;
}

tSirRetStatus ConvertP2POpaque( tpAniSirGlobal      pMac,
                                tSirAddie           *pOld,
                                tDot11fIEP2PIEOpaque *pNew )
{
    // This is awful, I know, but the old code just rammed the IE into
    // an opaque array.  Note that we need to explicitly add the vendorIE and OUI !
    tANI_U8 curAddIELen = pOld->length; 

    pOld->length    = curAddIELen + pNew->num_data + 6;
    pOld->addIEdata[ curAddIELen++ ] = 0xdd;
    pOld->addIEdata[ curAddIELen++ ] = pNew->num_data + 4;
    pOld->addIEdata[ curAddIELen++ ] = 0x50;
    pOld->addIEdata[ curAddIELen++ ] = 0x6f;
    pOld->addIEdata[ curAddIELen++ ] = 0x9A;
    pOld->addIEdata[ curAddIELen++ ] = 0x09;
    vos_mem_copy( pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data );

    return eSIR_SUCCESS;
}

#ifdef WLAN_FEATURE_WFD
tSirRetStatus ConvertWFDOpaque( tpAniSirGlobal      pMac,
                                tSirAddie           *pOld,
                                tDot11fIEWFDIEOpaque *pNew )
{
    // This is awful, I know, but the old code just rammed the IE into
    // an opaque array.  Note that we need to explicitly add the vendorIE and OUI !
    tANI_U8 curAddIELen = pOld->length; 

    pOld->length    = curAddIELen + pNew->num_data + 6;
    pOld->addIEdata[ curAddIELen++ ] = 0xdd;
    pOld->addIEdata[ curAddIELen++ ] = pNew->num_data + 4;
    pOld->addIEdata[ curAddIELen++ ] = 0x50;
    pOld->addIEdata[ curAddIELen++ ] = 0x6f;
    pOld->addIEdata[ curAddIELen++ ] = 0x9A;
    pOld->addIEdata[ curAddIELen++ ] = 0x0a;
    vos_mem_copy( pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data );

    return eSIR_SUCCESS;
}
#endif

tSirRetStatus ConvertRSN(tpAniSirGlobal  pMac,
                               tSirMacRsnInfo *pOld,
                               tDot11fIERSN      *pNew)
{
    tANI_U8 buffer[257];
    tANI_U32 status, written = 0, nbuffer = 257;
    status = dot11fPackIeRSN( pMac, pNew, buffer, nbuffer, &written );
    if ( DOT11F_FAILED( status ) )
    {
        dot11fLog(pMac, LOG2, FL("Failed to re-pack the RSN IE (0x%0x"
                                 "8).\n"), status);
        return eSIR_FAILURE;
    }

    pOld->length = (tANI_U8)written - 2;
    vos_mem_copy( pOld->info, buffer + 2, pOld->length );

    return eSIR_SUCCESS;
}

tSirRetStatus ConvertRSNOpaque( tpAniSirGlobal      pMac,
                                tSirMacRsnInfo     *pOld,
                                tDot11fIERSNOpaque *pNew )
{
    // This is awful, I know, but the old code just rammed the IE into
    // an opaque array.
    pOld->length = pNew->num_data;
    vos_mem_copy( pOld->info, pNew->data, pOld->length );

    return eSIR_SUCCESS;
}

void ConvertPowerCaps(tpAniSirGlobal            pMac,
                            tSirMacPowerCapabilityIE *pOld,
                            tDot11fIEPowerCaps          *pNew)
{
    pOld->type       = 33;
    pOld->length     = 2;
    pOld->minTxPower = pNew->minTxPower;
    pOld->maxTxPower = pNew->maxTxPower;
}

void ConvertSuppChannels(tpAniSirGlobal             pMac,
                               tSirMacSupportedChannelIE *pOld,
                               tDot11fIESuppChannels        *pNew)
{
    pOld->type   = 36;
    pOld->length = ( pNew->num_bands * 2 );
    vos_mem_copy( ( tANI_U8* )pOld->supportedChannels, ( tANI_U8* )pNew->bands, pOld->length );
}

void ConvertCFParams(tpAniSirGlobal     pMac,
                           tSirMacCfParamSet *pOld,
                           tDot11fIECFParams    *pNew)
{
    pOld->cfpCount        = pNew->cfp_count;
    pOld->cfpPeriod       = pNew->cfp_period;
    pOld->cfpMaxDuration  = pNew->cfp_maxduration;
    pOld->cfpDurRemaining = pNew->cfp_durremaining;
}

void ConvertFHParams (tpAniSirGlobal        pMac,
                      tSirMacFHParamSet    *pOld,
                      tDot11fIEFHParamSet  *pNew)
{
    pOld->dwellTime   = pNew->dwell_time;
    pOld->hopSet      = pNew->hop_set;
    pOld->hopPattern  = pNew->hop_pattern;
    pOld->hopIndex    = pNew->hop_index;
}

void ConvertTIM(tpAniSirGlobal pMac,
                      tSirMacTim    *pOld,
                      tDot11fIETIM     *pNew)
{
    pOld->dtimCount     = pNew->dtim_count;
    pOld->dtimPeriod    = pNew->dtim_period;
    pOld->bitmapControl = pNew->bmpctl;
    pOld->bitmapLength  = pNew->num_vbmp;

    vos_mem_copy( pOld->bitmap, pNew->vbmp, pNew->num_vbmp );
}

void ConvertCountry(tpAniSirGlobal          pMac,
                          tSirCountryInformation *pOld,
                          tDot11fIECountry          *pNew)
{
    int i;

    vos_mem_copy( pOld->countryString, pNew->country, COUNTRY_STRING_LENGTH );

    pOld->numIntervals = pNew->num_triplets;

    for (i = 0; i < pNew->num_triplets; ++i)
    {
        pOld->channelTransmitPower[i].channelNumber    = pNew->triplets[i][0];
        pOld->channelTransmitPower[i].numChannel       = pNew->triplets[i][1];
        pOld->channelTransmitPower[i].maxTransmitPower = pNew->triplets[i][2];
    }
}

void ConvertWMMParams(tpAniSirGlobal         pMac,
                            tSirMacEdcaParamSetIE *pOld,
                            tDot11fIEWMMParams       *pNew)
{
    pOld->type = 221;
    pOld->length = 24;

    vos_mem_copy( ( tANI_U8* )&pOld->qosInfo, ( tANI_U8* )&pNew->qosInfo, 1 );

    pOld->acbe.aci.aifsn  = pNew->acbe_aifsn;
    pOld->acbe.aci.acm    = pNew->acbe_acm;
    pOld->acbe.aci.aci    = pNew->acbe_aci;
    pOld->acbe.cw.min     = pNew->acbe_acwmin;
    pOld->acbe.cw.max     = pNew->acbe_acwmax;
    pOld->acbe.txoplimit  = pNew->acbe_txoplimit;

    pOld->acbk.aci.aifsn  = pNew->acbk_aifsn;
    pOld->acbk.aci.acm    = pNew->acbk_acm;
    pOld->acbk.aci.aci    = pNew->acbk_aci;
    pOld->acbk.cw.min     = pNew->acbk_acwmin;
    pOld->acbk.cw.max     = pNew->acbk_acwmax;
    pOld->acbk.txoplimit  = pNew->acbk_txoplimit;

    pOld->acvi.aci.aifsn  = pNew->acvi_aifsn;
    pOld->acvi.aci.acm    = pNew->acvi_acm;
    pOld->acvi.aci.aci    = pNew->acvi_aci;
    pOld->acvi.cw.min     = pNew->acvi_acwmin;
    pOld->acvi.cw.max     = pNew->acvi_acwmax;
    pOld->acvi.txoplimit  = pNew->acvi_txoplimit;

    pOld->acvo.aci.aifsn  = pNew->acvo_aifsn;
    pOld->acvo.aci.acm    = pNew->acvo_acm;
    pOld->acvo.aci.aci    = pNew->acvo_aci;
    pOld->acvo.cw.min     = pNew->acvo_acwmin;
    pOld->acvo.cw.max     = pNew->acvo_acwmax;
    pOld->acvo.txoplimit  = pNew->acvo_txoplimit;
}

void ConvertERPInfo(tpAniSirGlobal    pMac,
                          tSirMacErpInfo   *pOld,
                          tDot11fIEERPInfo    *pNew)
{
    pOld->nonErpPresent = pNew->non_erp_present;
    pOld->useProtection = pNew->use_prot;
    pOld->barkerPreambleMode = pNew->barker_preamble;
}

void ConvertEDCAParam(tpAniSirGlobal         pMac,
                            tSirMacEdcaParamSetIE *pOld,
                            tDot11fIEEDCAParamSet    *pNew)
{
    pOld->type   = 12;
    pOld->length = 20;

    vos_mem_copy( ( tANI_U8* )&pOld->qosInfo, ( tANI_U8* )&pNew->qos, 1 );

    pOld->acbe.aci.aifsn  = pNew->acbe_aifsn;
    pOld->acbe.aci.acm    = pNew->acbe_acm;
    pOld->acbe.aci.aci    = pNew->acbe_aci;
    pOld->acbe.cw.min     = pNew->acbe_acwmin;
    pOld->acbe.cw.max     = pNew->acbe_acwmax;
    pOld->acbe.txoplimit  = pNew->acbe_txoplimit;

    pOld->acbk.aci.aifsn  = pNew->acbk_aifsn;
    pOld->acbk.aci.acm    = pNew->acbk_acm;
    pOld->acbk.aci.aci    = pNew->acbk_aci;
    pOld->acbk.cw.min     = pNew->acbk_acwmin;
    pOld->acbk.cw.max     = pNew->acbk_acwmax;
    pOld->acbk.txoplimit  = pNew->acbk_txoplimit;

    pOld->acvi.aci.aifsn  = pNew->acvi_aifsn;
    pOld->acvi.aci.acm    = pNew->acvi_acm;
    pOld->acvi.aci.aci    = pNew->acvi_aci;
    pOld->acvi.cw.min     = pNew->acvi_acwmin;
    pOld->acvi.cw.max     = pNew->acvi_acwmax;
    pOld->acvi.txoplimit  = pNew->acvi_txoplimit;

    pOld->acvo.aci.aifsn  = pNew->acvo_aifsn;
    pOld->acvo.aci.acm    = pNew->acvo_acm;
    pOld->acvo.aci.aci    = pNew->acvo_aci;
    pOld->acvo.cw.min     = pNew->acvo_acwmin;
    pOld->acvo.cw.max     = pNew->acvo_acwmax;
    pOld->acvo.txoplimit  = pNew->acvo_txoplimit;

}

void ConvertTSPEC(tpAniSirGlobal  pMac,
                        tSirMacTspecIE *pOld,
                        tDot11fIETSPEC *pNew)
{
    pOld->tsinfo.traffic.trafficType  = (tANI_U16)pNew->traffic_type;
    pOld->tsinfo.traffic.tsid         = (tANI_U16)pNew->tsid;
    pOld->tsinfo.traffic.direction    = (tANI_U16)pNew->direction;
    pOld->tsinfo.traffic.accessPolicy = (tANI_U16)pNew->access_policy;
    pOld->tsinfo.traffic.aggregation  = (tANI_U16)pNew->aggregation;
    pOld->tsinfo.traffic.psb          = (tANI_U16)pNew->psb;
    pOld->tsinfo.traffic.userPrio     = (tANI_U16)pNew->user_priority;
    pOld->tsinfo.traffic.ackPolicy    = (tANI_U16)pNew->tsinfo_ack_pol;

    pOld->tsinfo.schedule.schedule    = (tANI_U8)pNew->schedule;

    pOld->nomMsduSz                   = pNew->size;
    pOld->maxMsduSz                   = pNew->max_msdu_size;
    pOld->minSvcInterval              = pNew->min_service_int;
    pOld->maxSvcInterval              = pNew->max_service_int;
    pOld->inactInterval               = pNew->inactivity_int;
    pOld->suspendInterval             = pNew->suspension_int;
    pOld->svcStartTime                = pNew->service_start_time;
    pOld->minDataRate                 = pNew->min_data_rate;
    pOld->meanDataRate                = pNew->mean_data_rate;
    pOld->peakDataRate                = pNew->peak_data_rate;
    pOld->maxBurstSz                  = pNew->burst_size;
    pOld->delayBound                  = pNew->delay_bound;
    pOld->minPhyRate                  = pNew->min_phy_rate;
    pOld->surplusBw                   = pNew->surplus_bw_allowance;
    pOld->mediumTime                  = pNew->medium_time;
}

tSirRetStatus ConvertTCLAS(tpAniSirGlobal  pMac,
                                 tSirTclasInfo  *pOld,
                                 tDot11fIETCLAS *pNew)
{
    tANI_U32 length = 0;

    if ( DOT11F_FAILED( dot11fGetPackedIETCLAS( pMac, pNew, &length ) ) )
    {
        return eSIR_FAILURE;
    }

    pOld->tclas.type           = DOT11F_EID_TCLAS;
    pOld->tclas.length         = (tANI_U8)length;
    pOld->tclas.userPrio       = pNew->user_priority;
    pOld->tclas.classifierType = pNew->classifier_type;
    pOld->tclas.classifierMask = pNew->classifier_mask;

    switch ( pNew->classifier_type )
    {
    case 0:
        vos_mem_copy( pOld->tclasParams.eth.srcAddr, pNew->info.EthParams.source, 6 );
        vos_mem_copy( pOld->tclasParams.eth.dstAddr, pNew->info.EthParams.dest, 6 );
        pOld->tclasParams.eth.type = pNew->info.EthParams.type;
        break;
    case 1:
        pOld->version = pNew->info.IpParams.version;
        if ( 4 == pNew->info.IpParams.version )
        {
            pOld->tclasParams.ipv4.version = 4;
            vos_mem_copy( pOld->tclasParams.ipv4.srcIpAddr,
                          pNew->info.IpParams.params.IpV4Params.source, 4 );
            vos_mem_copy( pOld->tclasParams.ipv4.dstIpAddr,
                          pNew->info.IpParams.params.IpV4Params.dest, 4 );
            pOld->tclasParams.ipv4.srcPort  = pNew->info.IpParams.params.IpV4Params.src_port;
            pOld->tclasParams.ipv4.dstPort  = pNew->info.IpParams.params.IpV4Params.dest_port;
            pOld->tclasParams.ipv4.dscp     = pNew->info.IpParams.params.IpV4Params.DSCP;
            pOld->tclasParams.ipv4.protocol = pNew->info.IpParams.params.IpV4Params.proto;
            pOld->tclasParams.ipv4.rsvd     = pNew->info.IpParams.params.IpV4Params.reserved;
        }
        else if ( 6 == pNew->info.IpParams.version )
        {
            pOld->tclasParams.ipv6.version = 6;
            vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.srcIpAddr,
                          ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.source, 16 );
            vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.dstIpAddr,
                          ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.dest, 16 );
            pOld->tclasParams.ipv6.srcPort  = pNew->info.IpParams.params.IpV6Params.src_port;
            pOld->tclasParams.ipv6.dstPort  = pNew->info.IpParams.params.IpV6Params.dest_port;
            vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.flowLabel,
                          ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.flow_label, 3 );
        }
        else
        {
            return eSIR_FAILURE;
        }
        break;
    case 2:
        pOld->tclasParams.t8021dq.tag = pNew->info.Params8021dq.tag_type;
        break;
    default:
        return eSIR_FAILURE;
    }

    return eSIR_SUCCESS;
}

void ConvertWMMTSPEC(tpAniSirGlobal     pMac,
                           tSirMacTspecIE    *pOld,
                           tDot11fIEWMMTSPEC *pNew)
{
    pOld->tsinfo.traffic.trafficType  = (tANI_U16)pNew->traffic_type;
    pOld->tsinfo.traffic.tsid         = (tANI_U16)pNew->tsid;
    pOld->tsinfo.traffic.direction    = (tANI_U16)pNew->direction;
    pOld->tsinfo.traffic.accessPolicy = (tANI_U16)pNew->access_policy;
    pOld->tsinfo.traffic.aggregation  = (tANI_U16)pNew->aggregation;
    pOld->tsinfo.traffic.psb          = (tANI_U16)pNew->psb;
    pOld->tsinfo.traffic.userPrio     = (tANI_U16)pNew->user_priority;
    pOld->tsinfo.traffic.ackPolicy    = (tANI_U16)pNew->tsinfo_ack_pol;
    pOld->nomMsduSz                   = (pNew->fixed << 15) | pNew->size;
    pOld->maxMsduSz                   = pNew->max_msdu_size;
    pOld->minSvcInterval              = pNew->min_service_int;
    pOld->maxSvcInterval              = pNew->max_service_int;
    pOld->inactInterval               = pNew->inactivity_int;
    pOld->suspendInterval             = pNew->suspension_int;
    pOld->svcStartTime                = pNew->service_start_time;
    pOld->minDataRate                 = pNew->min_data_rate;
    pOld->meanDataRate                = pNew->mean_data_rate;
    pOld->peakDataRate                = pNew->peak_data_rate;
    pOld->maxBurstSz                  = pNew->burst_size;
    pOld->delayBound                  = pNew->delay_bound;
    pOld->minPhyRate                  = pNew->min_phy_rate;
    pOld->surplusBw                   = pNew->surplus_bw_allowance;
    pOld->mediumTime                  = pNew->medium_time;
}

tSirRetStatus ConvertWMMTCLAS(tpAniSirGlobal    pMac,
                                    tSirTclasInfo     *pOld,
                                    tDot11fIEWMMTCLAS *pNew)
{
    tANI_U32 length = 0;

    if ( DOT11F_FAILED( dot11fGetPackedIEWMMTCLAS( pMac, pNew, &length ) ) )
    {
        return eSIR_FAILURE;
    }

    pOld->tclas.type           = DOT11F_EID_WMMTCLAS;
    pOld->tclas.length         = (tANI_U8)length;
    pOld->tclas.userPrio       = pNew->user_priority;
    pOld->tclas.classifierType = pNew->classifier_type;
    pOld->tclas.classifierMask = pNew->classifier_mask;

    switch ( pNew->classifier_type )
    {
    case 0:
        vos_mem_copy(  pOld->tclasParams.eth.srcAddr, pNew->info.EthParams.source, 6 );
        vos_mem_copy( pOld->tclasParams.eth.dstAddr, pNew->info.EthParams.dest, 6 );
        pOld->tclasParams.eth.type = pNew->info.EthParams.type;
        break;
    case 1:
        pOld->version = pNew->info.IpParams.version;
        if ( 4 == pNew->info.IpParams.version )
        {
            pOld->tclasParams.ipv4.version = 4;
            vos_mem_copy( pOld->tclasParams.ipv4.srcIpAddr,
                          pNew->info.IpParams.params.IpV4Params.source, 4 );
            vos_mem_copy( pOld->tclasParams.ipv4.dstIpAddr,
                          pNew->info.IpParams.params.IpV4Params.dest, 4 );
            pOld->tclasParams.ipv4.srcPort  = pNew->info.IpParams.params.IpV4Params.src_port;
            pOld->tclasParams.ipv4.dstPort  = pNew->info.IpParams.params.IpV4Params.dest_port;
            pOld->tclasParams.ipv4.dscp     = pNew->info.IpParams.params.IpV4Params.DSCP;
            pOld->tclasParams.ipv4.protocol = pNew->info.IpParams.params.IpV4Params.proto;
            pOld->tclasParams.ipv4.rsvd     = pNew->info.IpParams.params.IpV4Params.reserved;
        }
        else if ( 6 == pNew->info.IpParams.version )
        {
            pOld->tclasParams.ipv6.version = 6;
            vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.srcIpAddr,
                          ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.source, 16 );
            vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.dstIpAddr,
                          ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.dest, 16 );
            pOld->tclasParams.ipv6.srcPort  = pNew->info.IpParams.params.IpV6Params.src_port;
            pOld->tclasParams.ipv6.dstPort  = pNew->info.IpParams.params.IpV6Params.dest_port;
            vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.flowLabel,
                          ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.flow_label, 3 );
        }
        else
        {
            return eSIR_FAILURE;
        }
        break;
    case 2:
        pOld->tclasParams.t8021dq.tag = pNew->info.Params8021dq.tag_type;
        break;
    default:
        return eSIR_FAILURE;
    }

    return eSIR_SUCCESS;
}

void ConvertTSDelay(tpAniSirGlobal    pMac,
                          tSirMacTsDelayIE *pOld,
                          tDot11fIETSDelay *pNew)
{
    pOld->type   = DOT11F_EID_TSDELAY;
    pOld->length = 4U;
    pOld->delay  = pNew->delay;
}

void ConvertSchedule(tpAniSirGlobal     pMac,
                           tSirMacScheduleIE *pOld,
                           tDot11fIESchedule *pNew)
{
    pOld->type             = DOT11F_EID_SCHEDULE;
    pOld->length           = DOT11F_IE_SCHEDULE_MIN_LEN;

    pOld->info.aggregation = pNew->aggregation;
    pOld->info.tsid        = pNew->tsid;
    pOld->info.direction   = pNew->direction;

    pOld->svcStartTime     = pNew->service_start_time;
    pOld->svcInterval      = pNew->service_interval;
    pOld->specInterval     = pNew->spec_interval;
}

void ConvertWMMSchedule(tpAniSirGlobal        pMac,
                              tSirMacScheduleIE    *pOld,
                              tDot11fIEWMMSchedule *pNew)
{
    pOld->type             = DOT11F_EID_WMMSCHEDULE;
    pOld->length           = DOT11F_IE_WMMSCHEDULE_MIN_LEN;

    pOld->info.aggregation = pNew->aggregation;
    pOld->info.tsid        = pNew->tsid;
    pOld->info.direction   = pNew->direction;

    pOld->svcStartTime     = pNew->service_start_time;
    pOld->svcInterval      = pNew->service_interval;
    pOld->specInterval     = pNew->spec_interval;
}

/**
    @brief   :    This functions converts the given buffer till given size to Big endian format assuming the 
                     bus is 32 bit. The size should be four byte aligned.
    @param :    ptr to be converted, size
    @return  :    void
*/

void ConverttoBigEndian(void *ptr, tANI_U16    size)
{
    tANI_U8        *temp_ptr;
    tANI_U32    *dest_ptr;

    dest_ptr  = (tANI_U32 *)ptr;
    while(size)
    {
        temp_ptr = (tANI_U8 *) dest_ptr;
        *dest_ptr = (temp_ptr[0] << 24) | (temp_ptr[1] << 16) | (temp_ptr[2] << 8) | temp_ptr[3];
        dest_ptr++;
        size -= 4;
    }
}


void CreateScanDataNullFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr,
                  tANI_U8 pwrMgmt, tSirMacAddr bssid, tSirMacAddr selfMacAddr)
{

    macMgmtHdr->fc.type = SIR_MAC_DATA_FRAME;
    macMgmtHdr->fc.subType = SIR_MAC_DATA_NULL;
    macMgmtHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
    macMgmtHdr->fc.order = 0;
    macMgmtHdr->fc.wep = 0;
    macMgmtHdr->fc.moreData =0;
    macMgmtHdr->fc.powerMgmt = pwrMgmt;
    macMgmtHdr->fc.retry = 0;
    macMgmtHdr->fc.moreFrag = 0;
    macMgmtHdr->fc.fromDS = 0;
    macMgmtHdr->fc.toDS = 0;
    macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff);
    macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8);
    macMgmtHdr->seqControl.fragNum = 0;
    macMgmtHdr->seqControl.seqNumLo = 0;
    macMgmtHdr->seqControl.seqNumHi = 2;
    vos_mem_copy( (void *)&macMgmtHdr->da,
                              (void *)bssid, sizeof(tSirMacAddr));
    vos_mem_copy( (void *)&macMgmtHdr->sa,
                              (void *)selfMacAddr, sizeof(tSirMacAddr));
    vos_mem_copy( (void *)&macMgmtHdr->bssId,
                              (void *)bssid, sizeof(tSirMacAddr));
    
    return;
}


void CreateScanCtsFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tSirMacAddr selfMac)
{
    macMgmtHdr->fc.type = SIR_MAC_CTRL_FRAME;
    macMgmtHdr->fc.subType = SIR_MAC_CTRL_CTS;
    macMgmtHdr->fc.order = 0;
    macMgmtHdr->fc.wep = 0;
    macMgmtHdr->fc.moreData =0;
    macMgmtHdr->fc.powerMgmt = 0;  
    macMgmtHdr->fc.retry = 0;
    macMgmtHdr->fc.moreFrag = 0;
    macMgmtHdr->fc.fromDS = 0;
    macMgmtHdr->fc.toDS = 0;
    macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff);
    macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8);
    vos_mem_copy( (void *)macMgmtHdr->da, (void *)selfMac, sizeof(tSirMacAddr));
            
    return;
}

void ConvertQosMapsetFrame(tpAniSirGlobal pMac, tSirQosMapSet* Qos, tDot11fIEQosMapSet* dot11fIE)
{
    tANI_U8 i,j=0;
    if (dot11fIE->num_dscp_exceptions > 58)
        dot11fIE->num_dscp_exceptions = 58;
    if (dot11fIE->num_dscp_exceptions < 16)
        return;
    Qos->num_dscp_exceptions = (dot11fIE->num_dscp_exceptions - 16)/2;
    for (i=0;i<Qos->num_dscp_exceptions;i++)
    {
        Qos->dscp_exceptions[i][0] = dot11fIE->dscp_exceptions[j];
        j++;
        Qos->dscp_exceptions[i][1] = dot11fIE->dscp_exceptions[j];
        j++;
    }
    for (i=0;i<8;i++)
    {
        Qos->dscp_range[i][0] = dot11fIE->dscp_exceptions[j];
        j++;
        Qos->dscp_range[i][1] = dot11fIE->dscp_exceptions[j];
        j++;
    }
}

/**
    @brief    :    This functions creates a DATA_NULL/CTS2SELF frame in Big endian format 
    @param    :    Global MAC structure, pointer to return the created packet, role which is Station/AP
    @return    :    void
*/

void CreateInitScanRawFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tBssSystemRole role)
{
#if 0
    tpStaStruct pSta = (tpStaStruct) pMac->hal.halMac.staTable;
    
    if (role == eSYSTEM_STA_ROLE)
    {
        macMgmtHdr->fc.type = SIR_MAC_DATA_FRAME;
        macMgmtHdr->fc.subType = SIR_MAC_DATA_NULL;
        macMgmtHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
        macMgmtHdr->fc.order = 0;
        macMgmtHdr->fc.wep = 0;
        macMgmtHdr->fc.moreData =0;
        macMgmtHdr->fc.powerMgmt = 1;  // Needed for station
        macMgmtHdr->fc.retry = 0;
        macMgmtHdr->fc.moreFrag = 0;
        macMgmtHdr->fc.fromDS = 0;
        macMgmtHdr->fc.toDS = 1;
        macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff);
        macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8);
        macMgmtHdr->seqControl.fragNum = 0;
        macMgmtHdr->seqControl.seqNumLo = 0;
        macMgmtHdr->seqControl.seqNumHi = 2;
        vos_mem_copy( (void *)&macMgmtHdr->da, (void *)pSta[0].bssId, 6);
        vos_mem_copy( &macMgmtHdr->sa, pSta[0].staAddr, 6);
        vos_mem_copy( (void *)&macMgmtHdr->bssId, (void *)pSta[0].bssId, 6);
    }
    else if (role == eSYSTEM_AP_ROLE || role == eSYSTEM_STA_IN_IBSS_ROLE)
    {
        macMgmtHdr->fc.type = SIR_MAC_CTRL_FRAME;
        macMgmtHdr->fc.subType = SIR_MAC_CTRL_CTS;
        macMgmtHdr->fc.order = 0;
        macMgmtHdr->fc.wep = 0;
        macMgmtHdr->fc.moreData =0;
        macMgmtHdr->fc.powerMgmt = 0;  // Needed for station
        macMgmtHdr->fc.retry = 0;
        macMgmtHdr->fc.moreFrag = 0;
        macMgmtHdr->fc.fromDS = 0;
        macMgmtHdr->fc.toDS = 0;
        macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff);
        macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8);
        vos_mem_copy( (void *)macMgmtHdr->da, (void *)pSta[0].staAddr, 6);
    }
    return;
#endif
}

/**
    @brief    :    This functions creates a DATA_NULL frame in Big endian format 
    @param    :    Global MAC structure, pointer to return the created packet, role which is Station/AP
    @return    :    void
*/


void CreateFinishScanRawFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tBssSystemRole role)
{
#if 0
    tpStaStruct pSta = (tpStaStruct) pMac->hal.halMac.staTable;

    if (role == eSYSTEM_STA_ROLE)
    {
        macMgmtHdr->fc.type = SIR_MAC_DATA_FRAME;
        macMgmtHdr->fc.subType = SIR_MAC_DATA_NULL;
        macMgmtHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
        macMgmtHdr->fc.order = 0;
        macMgmtHdr->fc.wep = 0;
        macMgmtHdr->fc.moreData =0;
        macMgmtHdr->fc.powerMgmt = 0;     // Needed for station
        macMgmtHdr->fc.retry = 0;
        macMgmtHdr->fc.moreFrag = 0;
        macMgmtHdr->fc.fromDS = 0;
        macMgmtHdr->fc.toDS = 1;
        macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff);
        macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8);
        macMgmtHdr->seqControl.fragNum = 0;
        macMgmtHdr->seqControl.seqNumLo = 0;
        macMgmtHdr->seqControl.seqNumHi = 2;
        vos_mem_copy( (void *)macMgmtHdr->da, (void *)pSta[0].bssId, 6);
        vos_mem_copy( macMgmtHdr->sa, pSta[0].staAddr, 6);
        vos_mem_copy( (void *)macMgmtHdr->bssId, (void *)pSta[0].bssId, 6);

    }
    
    return;
#endif
}


// utilsParser.c ends here.
