/*
* txCtrlServ.c
*
* Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Texas Instruments nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/****************************************************************************/
/* */
/* MODULE: txCtrlServ.c */
/* */
/* PURPOSE: Tx services module, e.g. send-null packet. */
/* A sub-module of TxCtrl module (uses it's object). */
/* */
/****************************************************************************/
#define __FILE_ID__ FILE_ID_58
#include "paramOut.h"
#include "osApi.h"
#include "TWDriver.h"
#include "report.h"
#include "txCtrl.h"
#include "Ethernet.h"
#include "qosMngr_API.h"
/***********************************************************************
* txCtrlServ_buildNullFrame
***********************************************************************
DESCRIPTION: Build Null frame Function.
The function does the following:
- Builds Null Data Frame, considering current QoS mode.
INPUT: hTxCtrl - Tx Ctrl module handle (the txServ uses the txCtrl object!!).
pFrame - A pointer to a buffer where the frame should be stored
pLength - A pointer to a placeholder for the frame length
************************************************************************/
TI_STATUS txCtrlServ_buildNullFrame(TI_HANDLE hTxCtrl, TI_UINT8* pFrame, TI_UINT32* pLength)
{
txCtrl_t *pTxCtrl = (txCtrl_t *)hTxCtrl;
EHeaderConvertMode qosMode = pTxCtrl->headerConverMode;
dot11_header_t *pHeader; /* Note : there is no body for null frame */
TI_STATUS status;
TI_UINT16 fc;
pHeader = (dot11_header_t*)(pFrame);
if (qosMode == HDR_CONVERT_QOS)
{
*pLength = WLAN_QOS_HDR_LEN;
SET_WLAN_WORD(&pHeader->qosControl, 0); /* We are using user priority 0 (BE) so no need for shift and endianess */
}
else
{
*pLength = WLAN_HDR_LEN;
}
/* Set the Frame Control with Null Data type, QoS or non-QoS */
if (qosMode == HDR_CONVERT_QOS)
fc = DOT11_FC_DATA_NULL_QOS | DOT11_FC_TO_DS;
else
fc = DOT11_FC_DATA_NULL_FUNCTION | DOT11_FC_TO_DS;
COPY_WLAN_WORD(&pHeader->fc, &fc); /* copy with endianess handling. */
/* copy destination mac address */
status = ctrlData_getParamBssid(pTxCtrl->hCtrlData, CTRL_DATA_CURRENT_BSSID_PARAM, pHeader->address3);
if (status != TI_OK)
{
return TI_NOK;
}
/* copy source mac address */
status = ctrlData_getParamBssid(pTxCtrl->hCtrlData, CTRL_DATA_MAC_ADDRESS, pHeader->address2);
if (status != TI_OK)
{
return TI_NOK;
}
/* copy BSSID (destination mac address) */
MAC_COPY (pHeader->address1, pHeader->address3);
return status;
}
/***********************************************************************
* txCtrlServ_buildWlanHeader
***********************************************************************
DESCRIPTION: Build WLAN header from Ethernet header.
INPUT: hTxCtrl - Tx Ctrl module handle (the txServ uses the txCtrl object!!).
pFrame - A pointer to a buffer where the frame should be stored
pLength - A pointer to a placeholder for the frame length
************************************************************************/
TI_STATUS txCtrlServ_buildWlanHeader(TI_HANDLE hTxCtrl, TI_UINT8* pFrame, TI_UINT32* pLength)
{
txCtrl_t *pTxCtrl = (txCtrl_t *)hTxCtrl;
TI_STATUS status;
TMacAddr daBssid;
TMacAddr saBssid;
EQosProtocol qosProt;
ScanBssType_e currBssType;
TMacAddr currBssId;
TI_UINT32 headerLength;
TI_UINT16 headerFlags;
TI_BOOL currentPrivacyInvokedMode;
TI_UINT8 encryptionFieldSize;
TTxCtrlBlk tPktCtrlBlk;
dot11_header_t *pDot11Header = (dot11_header_t*)(tPktCtrlBlk.aPktHdr);
Wlan_LlcHeader_T *pWlanSnapHeader;
/*
* If QoS is used, add two bytes padding before the header for 4-bytes alignment.
* Note that the header length doesn't include it, so the txCtrl detects the pad existence
* by checking if the header-length is a multiple of 4.
*/
qosMngr_getParamsActiveProtocol(pTxCtrl->hQosMngr, &qosProt);
if (qosProt == QOS_WME)
{
headerLength = WLAN_QOS_HDR_LEN;
headerFlags = DOT11_FC_DATA_QOS | DOT11_FC_TO_DS;
pDot11Header->qosControl = 0;
}
else
{
headerLength = WLAN_HDR_LEN;
headerFlags = DOT11_FC_DATA | DOT11_FC_TO_DS;
}
/*
* Handle encryption if needed (decision was done at RSN and is provided by TxCtrl):
* - Set WEP bit in header.
* - Add padding for FW security overhead: 4 bytes for TKIP, 8 for AES.
*/
txCtrlParams_getCurrentEncryptionInfo (hTxCtrl,
¤tPrivacyInvokedMode,
&encryptionFieldSize);
if (currentPrivacyInvokedMode)
{
headerFlags |= DOT11_FC_WEP;
headerLength += encryptionFieldSize;
}
COPY_WLAN_WORD (&pDot11Header->fc, &headerFlags); /* copy with endianess handling. */
/* Get the Destination MAC address */
status = ctrlData_getParamBssid (pTxCtrl->hCtrlData, CTRL_DATA_CURRENT_BSSID_PARAM, daBssid);
if (status != TI_OK)
{
return TI_NOK;
}
/* Get the Source MAC address */
status = ctrlData_getParamBssid (pTxCtrl->hCtrlData, CTRL_DATA_MAC_ADDRESS, saBssid);
if (status != TI_OK)
{
return TI_NOK;
}
/* receive BssId and Bss Type from control module */
ctrlData_getCurrBssTypeAndCurrBssId (pTxCtrl->hCtrlData, &currBssId, &currBssType);
if (currBssType != BSS_INFRASTRUCTURE)
{
return TI_NOK;
}
/* copy BSSID */
MAC_COPY (pDot11Header->address1, currBssId);
/* copy source mac address */
MAC_COPY (pDot11Header->address2, saBssid);
/* copy destination mac address*/
MAC_COPY (pDot11Header->address3, daBssid);
/* Set the SNAP header pointer right after the other header parts handled above. */
pWlanSnapHeader = (Wlan_LlcHeader_T *)&(tPktCtrlBlk.aPktHdr[headerLength]);
pWlanSnapHeader->DSAP = SNAP_CHANNEL_ID;
pWlanSnapHeader->SSAP = SNAP_CHANNEL_ID;
pWlanSnapHeader->Control = LLC_CONTROL_UNNUMBERED_INFORMATION;
/* add RFC1042. */
pWlanSnapHeader->OUI[0] = SNAP_OUI_RFC1042_BYTE0;
pWlanSnapHeader->OUI[1] = SNAP_OUI_RFC1042_BYTE1;
pWlanSnapHeader->OUI[2] = SNAP_OUI_RFC1042_BYTE2;
/* set ETH type to IP */
pWlanSnapHeader->Type = HTOWLANS(ETHERTYPE_IP);
/* Add the SNAP length to the total header length. */
headerLength += sizeof(Wlan_LlcHeader_T);
/* copy WLAN header */
os_memoryCopy (pTxCtrl->hOs, pFrame, tPktCtrlBlk.aPktHdr, headerLength);
*pLength = headerLength;
return TI_OK;
}