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