/*********************************************************************** * 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_getParamMacAddr(pTxCtrl->hCtrlData, pHeader->address2); if (status != TI_OK) { return TI_NOK; } /* copy BSSID (destination mac address) */ MAC_COPY (pHeader->address1, pHeader->address3); return status; }
TI_STATUS mlmeBuilder_sendFrame(TI_HANDLE hMlme, dot11MgmtSubType_e type, TI_UINT8 *pDataBuff, TI_UINT32 dataLen, TI_UINT8 setWepOpt) { mlme_t *pHandle = (mlme_t*)hMlme; TI_STATUS status; TTxCtrlBlk *pPktCtrlBlk; TI_UINT8 *pPktBuffer; TMacAddr daBssid, saBssid; dot11_mgmtHeader_t *pDot11Header; /* Allocate a TxCtrlBlk and data buffer (large enough for the max management packet) */ pPktCtrlBlk = TWD_txCtrlBlk_Alloc (pHandle->hTWD); if (pPktCtrlBlk == NULL) return TI_NOK; pPktBuffer = txCtrl_AllocPacketBuffer (pHandle->hTxCtrl, pPktCtrlBlk, MAX_MANAGEMENT_FRAME_BODY_LEN + WLAN_HDR_LEN); if (pPktBuffer == NULL) { TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR , ": No memory\n"); TWD_txCtrlBlk_Free (pHandle->hTWD, pPktCtrlBlk); return TI_NOK; } pDot11Header = (dot11_mgmtHeader_t *)(pPktCtrlBlk->aPktHdr); status = mlmeBuilder_buildFrameCtrl (pHandle, type, (TI_UINT16 *)&pDot11Header->fc, setWepOpt); if (status != TI_OK) { txCtrl_FreePacket (pHandle->hTxCtrl, pPktCtrlBlk, TI_NOK); return TI_NOK; } status = ctrlData_getParamBssid(pHandle->hCtrlData, CTRL_DATA_CURRENT_BSSID_PARAM, daBssid); if (status != TI_OK) { txCtrl_FreePacket (pHandle->hTxCtrl, pPktCtrlBlk, TI_NOK); return TI_NOK; } /* copy destination mac address */ MAC_COPY (pDot11Header->DA, daBssid); status = ctrlData_getParamMacAddr(pHandle->hCtrlData, saBssid); if (status != TI_OK) { txCtrl_FreePacket (pHandle->hTxCtrl, pPktCtrlBlk, TI_NOK); return TI_NOK; } /* copy source mac address */ MAC_COPY (pDot11Header->SA, saBssid); /* copy BSSID (destination mac address) */ MAC_COPY (pDot11Header->BSSID, daBssid); if (pDataBuff != NULL) { os_memoryCopy (pHandle->hOs, pPktBuffer, pDataBuff, dataLen); } /* Update packet parameters (start-time, length, pkt-type) */ pPktCtrlBlk->tTxDescriptor.startTime = os_timeStampMs (pHandle->hOs); pPktCtrlBlk->tTxPktParams.uPktType = TX_PKT_TYPE_MGMT; BUILD_TX_TWO_BUF_PKT_BDL (pPktCtrlBlk, (TI_UINT8 *)pDot11Header, WLAN_HDR_LEN, pPktBuffer, dataLen) /* Enqueue packet in the mgmt-queues and run the scheduler. */ status = txMgmtQ_Xmit (pHandle->hTxMgmtQ, pPktCtrlBlk, TI_FALSE); 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_getParamMacAddr (pTxCtrl->hCtrlData, 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; }