📄 wlan_ccx.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 + -