⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wlan_ccx.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
 /** @file wlan_ccx.c
 *  @brief This file contains data structures and functions
 *  for CCX standard  
 *
 *  Copyright (c) Marvell Semiconductor, Inc. 
 */
/*********************************************************
Change log:
	09/27/05: add comments for Doxygen
*********************************************************/
#ifdef CCX

#include "precomp.h"
#include "wlan_ccx.h"


// For WinCE +++
#define u8 UCHAR
#define s8 char
#define u16 USHORT
#define WLAN_STATUS_SUCCESS			(0)
#define cpu_to_le16(x) x
// For WinCE ---

#pragma pack(1)

// wlan_types.h +++

/**  Local Power Capability */
typedef struct _MrvlIEtypes_PowerCapability_t {
	MrvlIEtypesHeader_t	Header;
	s8 	MinPower;
	s8	MaxPower;
} MrvlIEtypes_PowerCapability_t;
// wlan_types.h ---

/**  OUI Types encoded in the CCX Vendor specific IE. 
 */
typedef enum
{
    CCX_OUI_TYPE_VERSION   = 0x03,
    CCX_OUI_TYPE_QOS_PARAM = 0x04,

} CCX_OUI_Type_t;


/**  CCX IE types that are checked for in BSS descriptions returned in scans.
 */
typedef enum
{
    CCX_IE_VERSION = VENDOR_SPECIFIC_221,
    CCX_IE_CELL_POWER_LIMIT = 0x96,

} CCX_IE_Id_t;



/**  Generic IE Structure containing an OUI and oui type used to encapsulate 
 *    CCX Proprietary elements. 
 */
typedef struct _CCX_IE_OUT_Hdr
{
    u8 elemId;
    u8 len;
    u8 oui[3];
    u8 ouiType;
} CCX_IE_OUI_Hdr_t;
    

/**  CCX Version IE
 *    Received in beacons/probe responses and sent out in (Re)Assocation
 *    requests as a vendor specific 221 element with the OUI set to 0x004096 
 *    and the ouiType set to 0x03.
 *    One octet specifying the major CCX Version supported.
 */    
typedef struct
{
    CCX_IE_OUI_Hdr_t ouiHdr;
    u8 version;

} CCX_IE_Version_t;


/**  CCX Cell Power Limit IE
 *    Received in beacon and probe responses (scans) with a Element ID of 0x96
 *    with the OUI set to 0x004096 and the ouiType set to 0x00.
 *    One octet containing the maximum transmit power for the STA
 */
typedef struct
{
    CCX_IE_OUI_Hdr_t ouiHdr;
    u8 maxPower;
    u8 reserved;

} CCX_IE_Cell_Power_Limit_t;

#pragma pack()

/********************************************************
		Local Variables
********************************************************/

/**
 *  Supported version included in CCX Version IE for (Re)Association requests
 */
static u8 ccx_supported_version = 2U;

/**
 *  Cisco OUI parsed in Vendor Specific IEs 
 */
static u8 cisco_oui[] = { 0x00, 0x40, 0x96 };

/********************************************************
		Global Variables
********************************************************/

/********************************************************
		Local Functions
********************************************************/

/** 
 *  @brief Append a ccx version ie to the buffer and advance
 *  the buffer pointer by the size of the IE appended.
 *  Return the size appended.
 *
 *  @param ppBuffer	pointer to the buffer pointer
 *  @return		number of bytes appended to **ppBuffer	
 */  
static int append_ccx_version_ie( u8** ppBuffer )
{
    CCX_IE_Version_t versionIe;

    /* Null checks */
    if (ppBuffer == 0) return 0;
    if (*ppBuffer == 0) return 0;

    /* Setup OUI Header information */
    versionIe.ouiHdr.elemId = CCX_IE_VERSION;
    versionIe.ouiHdr.len = sizeof(CCX_IE_Version_t) - 2; /* -2 for len + id */
    memcpy(versionIe.ouiHdr.oui, cisco_oui, sizeof(cisco_oui));
    versionIe.ouiHdr.ouiType = CCX_OUI_TYPE_VERSION;

    /* Set version to be internally stored supported version */
    versionIe.version = ccx_supported_version;

    /* Copy the stack versionIe to the returned buffer parameter */
    memcpy(*ppBuffer, (u8*)&versionIe, sizeof(versionIe));
    
    /* Advance the buffer pointer by the size we appended */
    *ppBuffer += sizeof(versionIe);
    
    /* Return appended size */
    return (sizeof(versionIe));
}


/** 
 *  @brief Append a marvell power capability TLV to the buffer.
 *  The minimum power should be set to 0.  The maximum power is
 *  taken from the CCX Cell Power IE received in the scan results
 *  before association.
 *
 *  @param ppBuffer	pointer to the buffer pointer
 *  @param minPower	min power in power capability TLV
 *  @param maxPower	max power in power capability TLV 
 *  @return 	   	number of bytes appended to **ppBuffer 	
 */  
static int append_mrvl_power_capability(u8** ppBuffer,
                                        u8 minPower, u8 maxPower)
{
    MrvlIEtypes_PowerCapability_t powerCapIe;

    /* Null checks */
    if (ppBuffer == 0) return 0;
    if (*ppBuffer == 0) return 0;

    /* Set up marvell Power Capability TLV with passed parameters */
	powerCapIe.Header.Type = cpu_to_le16(TLV_TYPE_POWER_CAPABILITY);
	powerCapIe.Header.Len = cpu_to_le16(sizeof(powerCapIe) 
                                        - sizeof(powerCapIe.Header));
    powerCapIe.MinPower = minPower;
    powerCapIe.MaxPower = maxPower;

    DBGPRINT(DBG_CCX, ("CCX: Power Cap Added: min(%d), max(%d)\n", minPower, maxPower));

    /* Copy the stack powerCapIe to the returned buffer parameter */
    memcpy(*ppBuffer, (u8*)&powerCapIe, sizeof(powerCapIe));

//    HEXDUMP("CCX: PwrCap IE", *ppBuffer, sizeof(powerCapIe));

    /* Advance the buffer pointer by the size we appended */
    *ppBuffer += sizeof(powerCapIe);
    
    /* Return appended size */
    return (sizeof(powerCapIe));
}

/********************************************************
		Global Functions
********************************************************/

/** 
 *  @brief Call back from the main command module to allow CCX proprietary additions
 *  to the association request sent to the firmware.  
 *
 *  @param ppAssocBuf		pointer to the buffer pointer for the assoc req.
 *  @param pCcxBssInfo		CCX information of the specific AP from the scan
 *  @param enableCcxPwrLimit 	boolean CCX transmit power control
 *  @return			number of bytes added to the assoc. request 
 */
				     
int wlan_ccx_process_association_req(u8** ppAssocBuf, 
                                     CCX_BSS_Info_t* pCcxBssInfo,
                                     int enableCcxPwrLimit)
{
    u8* pBufSav;
    u16 passThroughLen = 0;
    MrvlIEtypesHeader_t ieHeader;

    DBGPRINT(DBG_CCX, ("CCX: process assoc req: %d, %d\n", 
            pCcxBssInfo->ccxEnabled, enableCcxPwrLimit));

    /* Null checks */
    if (ppAssocBuf == 0) return 0;
    if (*ppAssocBuf == 0) return 0;
    if (pCcxBssInfo == 0) return 0;

    /*
    **  Return immediately if CCX support isn't required by this specific AP
    **   we are attempting to associate with.  Flag set during scan result 
    **   processing.
    */
    if (pCcxBssInfo->ccxEnabled == FALSE)
    {
        return 0;
    }

    /* Save off the original buffer pointer */
    pBufSav = *ppAssocBuf;

    /* Increment the buffer pointer by the size of the Marvell TLV header.
    **   Skip past the buffer space for the header to append the CCX version
    **   IE.  When we get the size of the version IE, then append the 
    **   marvell TLV header with the appropriate size
    */
    *ppAssocBuf += sizeof(MrvlIEtypesHeader_t);

    /*
    ** Append the version IE to the association buffer.  passThroughLen holds
    **   the amount of data inserted (used for the passthrough TLV header len
    */
    passThroughLen += append_ccx_version_ie(ppAssocBuf);

    /* 
    **  Append the TLV Header to the saved buffer pointer (insert it before
    **    the version IE that was just appended).  Set the TLV ID to the 
    **    PASSTHROUGH type and encode the length as the size of the version IE
    **    previously added.
    */
    ieHeader.Type = TLV_TYPE_PASSTHROUGH;
    ieHeader.Len  = passThroughLen;
    memcpy(pBufSav, &ieHeader, sizeof(ieHeader));

    /*
    **  If a CCX power IE was sensed in the scan response, and CCX Power
    **    limiting is enabled (i.e. no AP 11h support), add a power capability
    **    TLV to the association request setting the max power to the AP
    **    specified maximum
    */
    if (pCcxBssInfo->maxPowerValid && enableCcxPwrLimit)
    {
        append_mrvl_power_capability(ppAssocBuf, 0, pCcxBssInfo->maxPower);
    }

    /* Return the length we've appended to the buffer */
    return (*ppAssocBuf - pBufSav);
}

/** 
 *  @brief This function processes an element in a description
 *
 *  @param pCcxBssInfo	CCX information
 *  @param pBssElem	BSS IE for CCX relevance evaluation
 *  @return 		WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
 */
int wlan_ccx_process_bss_elem(CCX_BSS_Info_t* pCcxBssInfo, u8* pBssElem)
{

    CCX_IE_Version_t*           pVersionIe;
    CCX_IE_Cell_Power_Limit_t*  pCellPowerIe;
    CCX_IE_OUI_Hdr_t*           pOuiHdr = (CCX_IE_OUI_Hdr_t*)pBssElem;

    int enableBssCcxExt = FALSE;
    
    DBGPRINT(DBG_CCX,  ("CCX: process bss element: %d (0x%x)\n", 
            pOuiHdr->elemId, pOuiHdr->elemId));

    /*
    ** Switch statement based on the element ID encoded in the Header
    */
    switch (pOuiHdr->elemId)
    {
    case VENDOR_SPECIFIC_221:
        /*
        ** Vendor Specific Element ID 221 passes information for a variety 
        **   of protocols.  The CCX elements are identified by the Cisco
        **   OUI  (0x004096), check for it and then the OUI Type to correctly
        **   parse a CCX Element
        */
        if (NdisEqualMemory(pOuiHdr->oui, cisco_oui, sizeof(cisco_oui)) == 1)
        {
            /* Flag the presence of CCX elements */
            enableBssCcxExt = TRUE;

            switch (pOuiHdr->ouiType)
            {
            case CCX_OUI_TYPE_VERSION:
                /*
                ** CCX Version IE, just identify it for now.  May need
                **   to customize the CCX behavior in the driver and 
                **   supplicant based on the version of CCX the AP supports
                */
                pVersionIe = (CCX_IE_Version_t*)pOuiHdr;
                DBGPRINT(DBG_CCX,  ("CCX: Version IE found: CCX Version %d\n",
                        pVersionIe->version));
                break;
            case CCX_OUI_TYPE_QOS_PARAM:
                /*
                ** No longer used in CCX V2 specification v2.13 
                */
                DBGPRINT(DBG_CCX,  ("CCX: QOS Param Set IE found: Deprecated\n"));
                break;
            default:
                /*
                **  Aironet/Cisco OUI specified, but unidentified subtype
                */
                DBGPRINT(DBG_CCX,  ("CCX: unhandled oui type: %x (%d)\n",
                        pOuiHdr->ouiType, pOuiHdr->ouiType));
                break;
            }
        }
        break;
        
    case CCX_IE_CELL_POWER_LIMIT:
        if (memcmp(pOuiHdr->oui, cisco_oui, sizeof(cisco_oui)) == 0)
        {
            /* Flag the presence of CCX elements */
            enableBssCcxExt = TRUE;
            
            /*
            ** Set the max power indicated by the Cell Power Limit IE
            **   in the CCX BSS information structure for this AP.
            **   Mark it as valid. Used in association processing.
            */
            pCellPowerIe = (CCX_IE_Cell_Power_Limit_t*)pOuiHdr;
            pCcxBssInfo->maxPowerValid = TRUE;
            pCcxBssInfo->maxPower = pCellPowerIe->maxPower;

            DBGPRINT(DBG_CCX,  ("CCX: Cell Power Limit IE found: Max Power = %d\n",
                    pCellPowerIe->maxPower));
        }
        break;
    default:
        /*
        **  Not a CCX element
        */
        DBGPRINT(DBG_CCX,  ("CCX: Unhandled IE: %d\n", pOuiHdr->elemId));
        break;
    }

    /*
    ** If the parsing routines above find CCX elements, set the enable 
    **   flag in the BSS info structure for this AP.  Triggers CCX support
    **   in association processing.
    */
    pCcxBssInfo->ccxEnabled = enableBssCcxExt;

    /* Succssful return */
    return WLAN_STATUS_SUCCESS;
}


#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -