| /* |
| * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. |
| * |
| * Previously licensed under the ISC license by Qualcomm Atheros, Inc. |
| * |
| * |
| * Permission to use, copy, modify, and/or distribute this software for |
| * any purpose with or without fee is hereby granted, provided that the |
| * above copyright notice and this permission notice appear in all |
| * copies. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| * PERFORMANCE OF THIS SOFTWARE. |
| */ |
| |
| /* |
| * This file was originally distributed by Qualcomm Atheros, Inc. |
| * under proprietary terms before Copyright ownership was assigned |
| * to the Linux Foundation. |
| */ |
| |
| /** ------------------------------------------------------------------------- * |
| ------------------------------------------------------------------------- * |
| |
| |
| \file csrTdlsProcess.c |
| |
| Implementation for the TDLS interface to PE. |
| ========================================================================== */ |
| |
| #ifdef FEATURE_WLAN_TDLS |
| |
| #include "aniGlobal.h" //for tpAniSirGlobal |
| #include "palApi.h" |
| #include "csrInsideApi.h" |
| #include "smeInside.h" |
| #include "smsDebug.h" |
| |
| #include "csrSupport.h" |
| #include "wlan_qct_tl.h" |
| |
| #include "vos_diag_core_log.h" |
| #include "vos_diag_core_event.h" |
| #include "csrInternal.h" |
| |
| |
| |
| |
| /* |
| * common routine to remove TDLS cmd from SME command list.. |
| * commands are removed after getting response from PE. |
| */ |
| eHalStatus csrTdlsRemoveSmeCmd(tpAniSirGlobal pMac, eSmeCommandType cmdType) |
| { |
| eHalStatus status = eHAL_STATUS_FAILURE; |
| tListElem *pEntry; |
| tSmeCmd *pCommand; |
| |
| pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); |
| if( pEntry ) |
| { |
| pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); |
| if( cmdType == pCommand->command ) |
| { |
| if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, |
| pEntry, LL_ACCESS_LOCK ) ) |
| { |
| vos_mem_zero( &pCommand->u.tdlsCmd, sizeof( tTdlsCmd ) ); |
| csrReleaseCommand( pMac, pCommand ); |
| smeProcessPendingQueue( pMac ); |
| status = eHAL_STATUS_SUCCESS ; |
| } |
| } |
| } |
| return status ; |
| } |
| |
| /* |
| * TDLS request API, called from HDD to send a TDLS frame |
| * in SME/CSR and send message to PE to trigger TDLS discovery procedure. |
| */ |
| eHalStatus csrTdlsSendMgmtReq(tHalHandle hHal, tANI_U8 sessionId, tCsrTdlsSendMgmt *tdlsSendMgmt) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| tSmeCmd *tdlsSendMgmtCmd ; |
| eHalStatus status = eHAL_STATUS_FAILURE ; |
| |
| //If connected and in Infra. Only then allow this |
| if( CSR_IS_SESSION_VALID( pMac, sessionId ) && |
| csrIsConnStateConnectedInfra( pMac, sessionId ) && |
| (NULL != tdlsSendMgmt) ) |
| { |
| tdlsSendMgmtCmd = csrGetCommandBuffer(pMac) ; |
| |
| if(tdlsSendMgmtCmd) |
| { |
| tTdlsSendMgmtCmdInfo *tdlsSendMgmtCmdInfo = |
| &tdlsSendMgmtCmd->u.tdlsCmd.u.tdlsSendMgmtCmdInfo ; |
| |
| tdlsSendMgmtCmd->sessionId = sessionId; |
| |
| tdlsSendMgmtCmdInfo->frameType = tdlsSendMgmt->frameType ; |
| tdlsSendMgmtCmdInfo->dialog = tdlsSendMgmt->dialog ; |
| tdlsSendMgmtCmdInfo->statusCode = tdlsSendMgmt->statusCode ; |
| tdlsSendMgmtCmdInfo->responder = tdlsSendMgmt->responder; |
| tdlsSendMgmtCmdInfo->peerCapability = tdlsSendMgmt->peerCapability; |
| vos_mem_copy(tdlsSendMgmtCmdInfo->peerMac, |
| tdlsSendMgmt->peerMac, sizeof(tSirMacAddr)) ; |
| |
| if( (0 != tdlsSendMgmt->len) && (NULL != tdlsSendMgmt->buf) ) |
| { |
| tdlsSendMgmtCmdInfo->buf = vos_mem_malloc(tdlsSendMgmt->len); |
| if ( NULL == tdlsSendMgmtCmdInfo->buf ) |
| status = eHAL_STATUS_FAILURE; |
| else |
| status = eHAL_STATUS_SUCCESS; |
| if(!HAL_STATUS_SUCCESS( status ) ) |
| { |
| smsLog( pMac, LOGE, FL("Alloc Failed") ); |
| VOS_ASSERT(0) ; |
| return status ; |
| } |
| vos_mem_copy(tdlsSendMgmtCmdInfo->buf, |
| tdlsSendMgmt->buf, tdlsSendMgmt->len ); |
| tdlsSendMgmtCmdInfo->len = tdlsSendMgmt->len; |
| } |
| else |
| { |
| tdlsSendMgmtCmdInfo->buf = NULL; |
| tdlsSendMgmtCmdInfo->len = 0; |
| } |
| |
| tdlsSendMgmtCmd->command = eSmeCommandTdlsSendMgmt ; |
| tdlsSendMgmtCmd->u.tdlsCmd.size = sizeof(tTdlsSendMgmtCmdInfo) ; |
| smePushCommand(pMac, tdlsSendMgmtCmd, FALSE) ; |
| status = eHAL_STATUS_SUCCESS ; |
| smsLog( pMac, LOG1, |
| FL("Successfully posted tdlsSendMgmtCmd to SME")); |
| } |
| } |
| |
| return status ; |
| } |
| |
| /* |
| * TDLS request API, called from HDD to modify an existing TDLS peer |
| */ |
| eHalStatus csrTdlsChangePeerSta(tHalHandle hHal, |
| tANI_U8 sessionId, |
| const tSirMacAddr peerMac, |
| tCsrStaParams *pstaParams) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| tSmeCmd *tdlsAddStaCmd ; |
| eHalStatus status = eHAL_STATUS_FAILURE ; |
| |
| if (NULL == pstaParams) |
| return status; |
| //If connected and in Infra. Only then allow this |
| if (CSR_IS_SESSION_VALID( pMac, sessionId ) && |
| csrIsConnStateConnectedInfra( pMac, sessionId ) && |
| (NULL != peerMac) && (NULL != pstaParams)) { |
| |
| tdlsAddStaCmd = csrGetCommandBuffer(pMac) ; |
| |
| if (tdlsAddStaCmd) |
| { |
| tTdlsAddStaCmdInfo *tdlsAddStaCmdInfo = |
| &tdlsAddStaCmd->u.tdlsCmd.u.tdlsAddStaCmdInfo ; |
| |
| tdlsAddStaCmdInfo->tdlsAddOper = TDLS_OPER_UPDATE; |
| |
| tdlsAddStaCmd->sessionId = sessionId; |
| |
| vos_mem_copy(tdlsAddStaCmdInfo->peerMac, |
| peerMac, sizeof(tSirMacAddr)) ; |
| tdlsAddStaCmdInfo->capability = pstaParams->capability; |
| tdlsAddStaCmdInfo->uapsdQueues = pstaParams->uapsd_queues; |
| tdlsAddStaCmdInfo->maxSp = pstaParams->max_sp; |
| vos_mem_copy(tdlsAddStaCmdInfo->extnCapability, |
| pstaParams->extn_capability, |
| sizeof(pstaParams->extn_capability)); |
| |
| tdlsAddStaCmdInfo->htcap_present = pstaParams->htcap_present; |
| if(pstaParams->htcap_present) |
| vos_mem_copy(&tdlsAddStaCmdInfo->HTCap, |
| &pstaParams->HTCap, sizeof(pstaParams->HTCap)); |
| else |
| vos_mem_set(&tdlsAddStaCmdInfo->HTCap, sizeof(pstaParams->HTCap), 0); |
| |
| tdlsAddStaCmdInfo->vhtcap_present = pstaParams->vhtcap_present; |
| if(pstaParams->vhtcap_present) |
| vos_mem_copy(&tdlsAddStaCmdInfo->VHTCap, |
| &pstaParams->VHTCap, sizeof(pstaParams->VHTCap)); |
| else |
| vos_mem_set(&tdlsAddStaCmdInfo->VHTCap, sizeof(pstaParams->VHTCap), 0); |
| |
| tdlsAddStaCmdInfo->supportedRatesLen = pstaParams->supported_rates_len; |
| |
| if (0 != pstaParams->supported_rates_len) |
| vos_mem_copy(&tdlsAddStaCmdInfo->supportedRates, |
| pstaParams->supported_rates, |
| pstaParams->supported_rates_len); |
| |
| tdlsAddStaCmd->command = eSmeCommandTdlsAddPeer; |
| tdlsAddStaCmd->u.tdlsCmd.size = sizeof(tTdlsAddStaCmdInfo) ; |
| smePushCommand(pMac, tdlsAddStaCmd, FALSE) ; |
| smsLog( pMac, LOG1, |
| FL("Successfully posted tdlsAddStaCmd to SME to modify peer ")); |
| status = eHAL_STATUS_SUCCESS ; |
| } |
| } |
| |
| return status ; |
| } |
| /* |
| * TDLS request API, called from HDD to Send Link Establishment Parameters |
| */ |
| VOS_STATUS csrTdlsSendLinkEstablishParams(tHalHandle hHal, |
| tANI_U8 sessionId, |
| const tSirMacAddr peerMac, |
| tCsrTdlsLinkEstablishParams *tdlsLinkEstablishParams) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| tSmeCmd *tdlsLinkEstablishCmd; |
| eHalStatus status = eHAL_STATUS_FAILURE ; |
| //If connected and in Infra. Only then allow this |
| if( CSR_IS_SESSION_VALID( pMac, sessionId ) && |
| csrIsConnStateConnectedInfra( pMac, sessionId ) && |
| (NULL != peerMac) ) |
| { |
| tdlsLinkEstablishCmd = csrGetCommandBuffer(pMac) ; |
| |
| if(tdlsLinkEstablishCmd) |
| { |
| tTdlsLinkEstablishCmdInfo *tdlsLinkEstablishCmdInfo = |
| &tdlsLinkEstablishCmd->u.tdlsCmd.u.tdlsLinkEstablishCmdInfo ; |
| |
| tdlsLinkEstablishCmd->sessionId = sessionId; |
| |
| vos_mem_copy( tdlsLinkEstablishCmdInfo->peerMac, |
| peerMac, sizeof(tSirMacAddr)); |
| tdlsLinkEstablishCmdInfo->isBufSta = tdlsLinkEstablishParams->isBufSta; |
| tdlsLinkEstablishCmdInfo->isResponder= tdlsLinkEstablishParams->isResponder; |
| tdlsLinkEstablishCmdInfo->maxSp= tdlsLinkEstablishParams->maxSp; |
| tdlsLinkEstablishCmdInfo->uapsdQueues= tdlsLinkEstablishParams->uapsdQueues; |
| tdlsLinkEstablishCmdInfo->isOffChannelSupported = |
| tdlsLinkEstablishParams->isOffChannelSupported; |
| vos_mem_copy(tdlsLinkEstablishCmdInfo->supportedChannels, |
| tdlsLinkEstablishParams->supportedChannels, |
| tdlsLinkEstablishParams->supportedChannelsLen); |
| tdlsLinkEstablishCmdInfo->supportedChannelsLen = |
| tdlsLinkEstablishParams->supportedChannelsLen; |
| vos_mem_copy(tdlsLinkEstablishCmdInfo->supportedOperClasses, |
| tdlsLinkEstablishParams->supportedOperClasses, |
| tdlsLinkEstablishParams->supportedOperClassesLen); |
| tdlsLinkEstablishCmdInfo->supportedOperClassesLen = |
| tdlsLinkEstablishParams->supportedOperClassesLen; |
| tdlsLinkEstablishCmdInfo->isResponder= tdlsLinkEstablishParams->isResponder; |
| tdlsLinkEstablishCmdInfo->maxSp= tdlsLinkEstablishParams->maxSp; |
| tdlsLinkEstablishCmdInfo->uapsdQueues= tdlsLinkEstablishParams->uapsdQueues; |
| tdlsLinkEstablishCmd->command = eSmeCommandTdlsLinkEstablish ; |
| tdlsLinkEstablishCmd->u.tdlsCmd.size = sizeof(tTdlsLinkEstablishCmdInfo) ; |
| smePushCommand(pMac, tdlsLinkEstablishCmd, FALSE) ; |
| status = eHAL_STATUS_SUCCESS ; |
| smsLog( pMac, LOG1, |
| FL("Successfully posted tdlsLinkEstablishCmd to SME")); |
| } |
| } |
| |
| return status ; |
| } |
| |
| /* |
| * TDLS request API, called from HDD to add a TDLS peer |
| */ |
| eHalStatus csrTdlsAddPeerSta(tHalHandle hHal, |
| tANI_U8 sessionId, |
| const tSirMacAddr peerMac) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| tSmeCmd *tdlsAddStaCmd ; |
| eHalStatus status = eHAL_STATUS_FAILURE ; |
| |
| //If connected and in Infra. Only then allow this |
| if( CSR_IS_SESSION_VALID( pMac, sessionId ) && |
| csrIsConnStateConnectedInfra( pMac, sessionId ) && |
| (NULL != peerMac) ) |
| { |
| tdlsAddStaCmd = csrGetCommandBuffer(pMac) ; |
| |
| if(tdlsAddStaCmd) |
| { |
| tTdlsAddStaCmdInfo *tdlsAddStaCmdInfo = |
| &tdlsAddStaCmd->u.tdlsCmd.u.tdlsAddStaCmdInfo ; |
| |
| tdlsAddStaCmd->sessionId = sessionId; |
| tdlsAddStaCmdInfo->tdlsAddOper = TDLS_OPER_ADD; |
| |
| vos_mem_copy( tdlsAddStaCmdInfo->peerMac, |
| peerMac, sizeof(tSirMacAddr)) ; |
| |
| tdlsAddStaCmd->command = eSmeCommandTdlsAddPeer ; |
| tdlsAddStaCmd->u.tdlsCmd.size = sizeof(tTdlsAddStaCmdInfo) ; |
| smePushCommand(pMac, tdlsAddStaCmd, FALSE) ; |
| status = eHAL_STATUS_SUCCESS ; |
| smsLog( pMac, LOG1, |
| FL("Successfully posted tdlsAddStaCmd to SME")); |
| } |
| } |
| |
| return status ; |
| } |
| |
| /* |
| * TDLS request API, called from HDD to delete a TDLS peer |
| */ |
| eHalStatus csrTdlsDelPeerSta(tHalHandle hHal, tANI_U8 sessionId, |
| const tSirMacAddr peerMac) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| tSmeCmd *tdlsDelStaCmd ; |
| eHalStatus status = eHAL_STATUS_FAILURE ; |
| |
| //If connected and in Infra. Only then allow this |
| if( CSR_IS_SESSION_VALID( pMac, sessionId ) && |
| csrIsConnStateConnectedInfra( pMac, sessionId ) && |
| (NULL != peerMac) ) |
| { |
| tdlsDelStaCmd = csrGetCommandBuffer(pMac) ; |
| |
| if(tdlsDelStaCmd) |
| { |
| tTdlsDelStaCmdInfo *tdlsDelStaCmdInfo = |
| &tdlsDelStaCmd->u.tdlsCmd.u.tdlsDelStaCmdInfo ; |
| |
| tdlsDelStaCmd->sessionId = sessionId; |
| |
| vos_mem_copy(tdlsDelStaCmdInfo->peerMac, |
| peerMac, sizeof(tSirMacAddr)) ; |
| |
| tdlsDelStaCmd->command = eSmeCommandTdlsDelPeer ; |
| tdlsDelStaCmd->u.tdlsCmd.size = sizeof(tTdlsDelStaCmdInfo) ; |
| smePushCommand(pMac, tdlsDelStaCmd, FALSE) ; |
| status = eHAL_STATUS_SUCCESS ; |
| smsLog( pMac, LOG1, |
| FL("Successfully posted tdlsDelStaCmd to SME")); |
| } |
| } |
| |
| return status ; |
| } |
| |
| /* |
| * TDLS messages sent to PE . |
| */ |
| eHalStatus tdlsSendMessage(tpAniSirGlobal pMac, tANI_U16 msg_type, |
| void *msg_data, tANI_U32 msg_size) |
| { |
| |
| tSirMbMsg *pMsg = (tSirMbMsg *)msg_data ; |
| pMsg->type = msg_type ; |
| pMsg->msgLen = (tANI_U16) (msg_size) ; |
| |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, |
| FL("sending msg = %d"), pMsg->type) ; |
| /* Send message. */ |
| if (palSendMBMessage(pMac->hHdd, pMsg) != eHAL_STATUS_SUCCESS) |
| { |
| smsLog(pMac, LOGE, FL("Cannot send message")); |
| return eHAL_STATUS_FAILURE; |
| } |
| |
| return eHAL_STATUS_SUCCESS; |
| } |
| |
| eHalStatus csrTdlsProcessSendMgmt( tpAniSirGlobal pMac, tSmeCmd *cmd ) |
| { |
| tTdlsSendMgmtCmdInfo *tdlsSendMgmtCmdInfo = &cmd->u.tdlsCmd.u.tdlsSendMgmtCmdInfo ; |
| tSirTdlsSendMgmtReq *tdlsSendMgmtReq = NULL ; |
| tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); |
| eHalStatus status = eHAL_STATUS_FAILURE; |
| |
| if (NULL == pSession) |
| { |
| smsLog( pMac, LOGE, FL("pSession is NULL")); |
| return eHAL_STATUS_FAILURE; |
| } |
| if (NULL == pSession->pConnectBssDesc) |
| { |
| smsLog( pMac, LOGE, FL("BSS Description is not present") ); |
| return eHAL_STATUS_FAILURE; |
| } |
| |
| tdlsSendMgmtReq = vos_mem_malloc( |
| sizeof(tSirTdlsSendMgmtReq) + tdlsSendMgmtCmdInfo->len); |
| if ( NULL == tdlsSendMgmtReq ) |
| status = eHAL_STATUS_FAILURE; |
| else |
| status = eHAL_STATUS_SUCCESS; |
| |
| if (!HAL_STATUS_SUCCESS( status ) ) |
| { |
| smsLog( pMac, LOGE, FL("alloc failed") ); |
| VOS_ASSERT(0) ; |
| return status ; |
| } |
| tdlsSendMgmtReq->sessionId = cmd->sessionId; |
| //Using dialog as transactionId. This can be used to match response with request |
| tdlsSendMgmtReq->transactionId = tdlsSendMgmtCmdInfo->dialog; |
| tdlsSendMgmtReq->reqType = tdlsSendMgmtCmdInfo->frameType ; |
| tdlsSendMgmtReq->dialog = tdlsSendMgmtCmdInfo->dialog ; |
| tdlsSendMgmtReq->statusCode = tdlsSendMgmtCmdInfo->statusCode ; |
| tdlsSendMgmtReq->responder = tdlsSendMgmtCmdInfo->responder; |
| tdlsSendMgmtReq->peerCapability = tdlsSendMgmtCmdInfo->peerCapability; |
| |
| vos_mem_copy(tdlsSendMgmtReq->bssid, |
| pSession->pConnectBssDesc->bssId, sizeof (tSirMacAddr)); |
| |
| vos_mem_copy(tdlsSendMgmtReq->peerMac, |
| tdlsSendMgmtCmdInfo->peerMac, sizeof(tSirMacAddr)) ; |
| |
| if(tdlsSendMgmtCmdInfo->len && tdlsSendMgmtCmdInfo->buf) |
| { |
| vos_mem_copy(tdlsSendMgmtReq->addIe, tdlsSendMgmtCmdInfo->buf, |
| tdlsSendMgmtCmdInfo->len); |
| |
| } |
| // Send the request to PE. |
| smsLog( pMac, LOG1, FL( "sending TDLS Mgmt Frame req to PE ")); |
| status = tdlsSendMessage(pMac, eWNI_SME_TDLS_SEND_MGMT_REQ, |
| (void *)tdlsSendMgmtReq , sizeof(tSirTdlsSendMgmtReq)+tdlsSendMgmtCmdInfo->len) ; |
| if(!HAL_STATUS_SUCCESS( status ) ) |
| { |
| smsLog( pMac, LOGE, FL("Failed to send request to MAC")); |
| } |
| if(tdlsSendMgmtCmdInfo->len && tdlsSendMgmtCmdInfo->buf) |
| { |
| //Done with the buf. Free it. |
| vos_mem_free( tdlsSendMgmtCmdInfo->buf ); |
| tdlsSendMgmtCmdInfo->buf = NULL; |
| tdlsSendMgmtCmdInfo->len = 0; |
| } |
| |
| return status; |
| } |
| |
| eHalStatus csrTdlsProcessAddSta( tpAniSirGlobal pMac, tSmeCmd *cmd ) |
| { |
| tTdlsAddStaCmdInfo *tdlsAddStaCmdInfo = &cmd->u.tdlsCmd.u.tdlsAddStaCmdInfo ; |
| tSirTdlsAddStaReq *tdlsAddStaReq = NULL ; |
| tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); |
| eHalStatus status = eHAL_STATUS_FAILURE; |
| |
| if (NULL == pSession) |
| { |
| smsLog( pMac, LOGE, FL("pSession is NULL")); |
| return eHAL_STATUS_FAILURE; |
| } |
| |
| if (NULL == pSession->pConnectBssDesc) |
| { |
| smsLog( pMac, LOGE, FL("BSS description is not present") ); |
| return eHAL_STATUS_FAILURE; |
| } |
| |
| tdlsAddStaReq = vos_mem_malloc(sizeof(tSirTdlsAddStaReq)); |
| if ( NULL == tdlsAddStaReq ) |
| status = eHAL_STATUS_FAILURE; |
| else |
| status = eHAL_STATUS_SUCCESS; |
| |
| if (!HAL_STATUS_SUCCESS( status ) ) |
| { |
| smsLog( pMac, LOGE, FL("alloc failed") ); |
| VOS_ASSERT(0) ; |
| return status ; |
| } |
| tdlsAddStaReq->sessionId = cmd->sessionId; |
| tdlsAddStaReq->tdlsAddOper = tdlsAddStaCmdInfo->tdlsAddOper; |
| //Using dialog as transactionId. This can be used to match response with request |
| tdlsAddStaReq->transactionId = 0; |
| |
| vos_mem_copy( tdlsAddStaReq->bssid, |
| pSession->pConnectBssDesc->bssId, sizeof (tSirMacAddr)); |
| |
| vos_mem_copy( tdlsAddStaReq->peerMac, |
| tdlsAddStaCmdInfo->peerMac, sizeof(tSirMacAddr)) ; |
| |
| tdlsAddStaReq->capability = tdlsAddStaCmdInfo->capability; |
| tdlsAddStaReq->uapsd_queues = tdlsAddStaCmdInfo->uapsdQueues; |
| tdlsAddStaReq->max_sp = tdlsAddStaCmdInfo->maxSp; |
| |
| vos_mem_copy( tdlsAddStaReq->extn_capability, |
| tdlsAddStaCmdInfo->extnCapability, |
| SIR_MAC_MAX_EXTN_CAP); |
| tdlsAddStaReq->htcap_present = tdlsAddStaCmdInfo->htcap_present; |
| vos_mem_copy( &tdlsAddStaReq->htCap, |
| &tdlsAddStaCmdInfo->HTCap, sizeof(tdlsAddStaCmdInfo->HTCap)); |
| tdlsAddStaReq->vhtcap_present = tdlsAddStaCmdInfo->vhtcap_present; |
| vos_mem_copy( &tdlsAddStaReq->vhtCap, |
| &tdlsAddStaCmdInfo->VHTCap, sizeof(tdlsAddStaCmdInfo->VHTCap)); |
| tdlsAddStaReq->supported_rates_length = tdlsAddStaCmdInfo->supportedRatesLen; |
| vos_mem_copy( &tdlsAddStaReq->supported_rates, |
| tdlsAddStaCmdInfo->supportedRates, tdlsAddStaCmdInfo->supportedRatesLen); |
| |
| // Send the request to PE. |
| smsLog( pMac, LOG1, "sending TDLS Add Sta req to PE " ); |
| status = tdlsSendMessage(pMac, eWNI_SME_TDLS_ADD_STA_REQ, |
| (void *)tdlsAddStaReq , sizeof(tSirTdlsAddStaReq)) ; |
| if(!HAL_STATUS_SUCCESS( status ) ) |
| { |
| smsLog( pMac, LOGE, FL("Failed to send request to MAC")); |
| } |
| return status; |
| } |
| |
| eHalStatus csrTdlsProcessDelSta( tpAniSirGlobal pMac, tSmeCmd *cmd ) |
| { |
| tTdlsDelStaCmdInfo *tdlsDelStaCmdInfo = &cmd->u.tdlsCmd.u.tdlsDelStaCmdInfo ; |
| tSirTdlsDelStaReq *tdlsDelStaReq = NULL ; |
| tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); |
| eHalStatus status = eHAL_STATUS_FAILURE; |
| |
| if (NULL == pSession) |
| { |
| smsLog( pMac, LOGE, FL("pSession is NULL")); |
| return eHAL_STATUS_FAILURE; |
| } |
| |
| if (NULL == pSession->pConnectBssDesc) |
| { |
| smsLog( pMac, LOGE, FL("BSS description is not present") ); |
| return eHAL_STATUS_FAILURE; |
| } |
| |
| tdlsDelStaReq = vos_mem_malloc(sizeof(tSirTdlsDelStaReq)); |
| if ( NULL == tdlsDelStaReq ) |
| status = eHAL_STATUS_FAILURE; |
| else |
| status = eHAL_STATUS_SUCCESS; |
| |
| |
| if (!HAL_STATUS_SUCCESS( status ) ) |
| { |
| smsLog( pMac, LOGE, FL("alloc failed") ); |
| VOS_ASSERT(0) ; |
| return status ; |
| } |
| tdlsDelStaReq->sessionId = cmd->sessionId; |
| //Using dialog as transactionId. This can be used to match response with request |
| tdlsDelStaReq->transactionId = 0; |
| |
| vos_mem_copy( tdlsDelStaReq->bssid, |
| pSession->pConnectBssDesc->bssId, sizeof (tSirMacAddr)); |
| |
| vos_mem_copy( tdlsDelStaReq->peerMac, |
| tdlsDelStaCmdInfo->peerMac, sizeof(tSirMacAddr)) ; |
| |
| // Send the request to PE. |
| smsLog( pMac, LOG1, |
| "sending TDLS Del Sta "MAC_ADDRESS_STR" req to PE", |
| MAC_ADDR_ARRAY(tdlsDelStaCmdInfo->peerMac)); |
| status = tdlsSendMessage(pMac, eWNI_SME_TDLS_DEL_STA_REQ, |
| (void *)tdlsDelStaReq , sizeof(tSirTdlsDelStaReq)) ; |
| if(!HAL_STATUS_SUCCESS( status ) ) |
| { |
| smsLog( pMac, LOGE, FL("Failed to send request to MAC")); |
| } |
| return status; |
| } |
| /* |
| * commands received from CSR |
| */ |
| eHalStatus csrTdlsProcessCmd(tpAniSirGlobal pMac, tSmeCmd *cmd) |
| { |
| eSmeCommandType cmdType = cmd->command ; |
| tANI_BOOLEAN status = eANI_BOOLEAN_TRUE; |
| switch(cmdType) |
| { |
| case eSmeCommandTdlsSendMgmt: |
| { |
| status = csrTdlsProcessSendMgmt( pMac, cmd ); |
| if(HAL_STATUS_SUCCESS( status ) ) |
| { |
| status = eANI_BOOLEAN_FALSE ; |
| } |
| } |
| break ; |
| case eSmeCommandTdlsAddPeer: |
| { |
| status = csrTdlsProcessAddSta( pMac, cmd ); |
| if(HAL_STATUS_SUCCESS( status ) ) |
| { |
| status = eANI_BOOLEAN_FALSE ; |
| } |
| } |
| break; |
| case eSmeCommandTdlsDelPeer: |
| { |
| status = csrTdlsProcessDelSta( pMac, cmd ); |
| if(HAL_STATUS_SUCCESS( status ) ) |
| { |
| status = eANI_BOOLEAN_FALSE ; |
| } |
| } |
| break; |
| case eSmeCommandTdlsLinkEstablish: |
| { |
| status = csrTdlsProcessLinkEstablish( pMac, cmd ); |
| if(HAL_STATUS_SUCCESS( status ) ) |
| { |
| status = eANI_BOOLEAN_FALSE ; |
| } |
| } |
| break; |
| default: |
| { |
| /* TODO: Add default handling */ |
| break ; |
| } |
| |
| } |
| return status ; |
| } |
| |
| eHalStatus csrTdlsProcessLinkEstablish( tpAniSirGlobal pMac, tSmeCmd *cmd ) |
| { |
| tTdlsLinkEstablishCmdInfo *tdlsLinkEstablishCmdInfo = &cmd->u.tdlsCmd.u.tdlsLinkEstablishCmdInfo ; |
| tSirTdlsLinkEstablishReq *tdlsLinkEstablishReq = NULL ; |
| eHalStatus status = eHAL_STATUS_FAILURE; |
| tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); |
| |
| if (NULL == pSession) |
| { |
| smsLog( pMac, LOGE, FL("pSession is NULL")); |
| return eHAL_STATUS_FAILURE; |
| } |
| |
| tdlsLinkEstablishReq = vos_mem_malloc(sizeof(tSirTdlsLinkEstablishReq)); |
| |
| if (tdlsLinkEstablishReq == NULL) |
| { |
| smsLog( pMac, LOGE, FL("alloc failed \n") ); |
| VOS_ASSERT(0) ; |
| return status ; |
| } |
| tdlsLinkEstablishReq->sessionId = cmd->sessionId; |
| //Using dialog as transactionId. This can be used to match response with request |
| tdlsLinkEstablishReq->transactionId = 0; |
| vos_mem_copy(tdlsLinkEstablishReq->peerMac, |
| tdlsLinkEstablishCmdInfo->peerMac, sizeof(tSirMacAddr)); |
| vos_mem_copy(tdlsLinkEstablishReq->bssid, pSession->pConnectBssDesc->bssId, |
| sizeof (tSirMacAddr)); |
| vos_mem_copy(tdlsLinkEstablishReq->supportedChannels, |
| tdlsLinkEstablishCmdInfo->supportedChannels, |
| tdlsLinkEstablishCmdInfo->supportedChannelsLen); |
| tdlsLinkEstablishReq->supportedChannelsLen = |
| tdlsLinkEstablishCmdInfo->supportedChannelsLen; |
| vos_mem_copy(tdlsLinkEstablishReq->supportedOperClasses, |
| tdlsLinkEstablishCmdInfo->supportedOperClasses, |
| tdlsLinkEstablishCmdInfo->supportedOperClassesLen); |
| tdlsLinkEstablishReq->supportedOperClassesLen = |
| tdlsLinkEstablishCmdInfo->supportedOperClassesLen; |
| tdlsLinkEstablishReq->isBufSta = tdlsLinkEstablishCmdInfo->isBufSta; |
| tdlsLinkEstablishReq->isResponder= tdlsLinkEstablishCmdInfo->isResponder; |
| tdlsLinkEstablishReq->uapsdQueues= tdlsLinkEstablishCmdInfo->uapsdQueues; |
| tdlsLinkEstablishReq->maxSp= tdlsLinkEstablishCmdInfo->maxSp; |
| |
| |
| // Send the request to PE. |
| smsLog( pMac, LOGE, "sending TDLS Link Establish Request to PE \n" ); |
| status = tdlsSendMessage(pMac, eWNI_SME_TDLS_LINK_ESTABLISH_REQ, |
| (void *)tdlsLinkEstablishReq, |
| sizeof(tSirTdlsLinkEstablishReq)); |
| if (!HAL_STATUS_SUCCESS( status ) ) |
| { |
| smsLog( pMac, LOGE, FL("Failed to send request to MAC\n")); |
| } |
| return status; |
| } |
| |
| /* |
| * TDLS Message processor, will be called after TDLS message received from |
| * PE |
| */ |
| eHalStatus tdlsMsgProcessor(tpAniSirGlobal pMac, v_U16_t msgType, |
| void *pMsgBuf) |
| { |
| tCsrRoamInfo roamInfo = {0} ; |
| switch(msgType) |
| { |
| case eWNI_SME_TDLS_SEND_MGMT_RSP: |
| { |
| /* remove pending eSmeCommandTdlsDiscovery command */ |
| csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsSendMgmt) ; |
| } |
| break; |
| case eWNI_SME_TDLS_ADD_STA_RSP: |
| { |
| tSirTdlsAddStaRsp *addStaRsp = (tSirTdlsAddStaRsp *) pMsgBuf ; |
| eCsrRoamResult roamResult ; |
| vos_mem_copy( &roamInfo.peerMac, addStaRsp->peerMac, |
| sizeof(tSirMacAddr)) ; |
| roamInfo.staId = addStaRsp->staId ; |
| roamInfo.ucastSig = addStaRsp->ucastSig ; |
| roamInfo.bcastSig = addStaRsp->bcastSig ; |
| roamInfo.statusCode = addStaRsp->statusCode ; |
| /* |
| * register peer with TL, we have to go through HDD as this is |
| * the only way to register any STA with TL. |
| */ |
| if (addStaRsp->tdlsAddOper == TDLS_OPER_ADD) |
| roamResult = eCSR_ROAM_RESULT_ADD_TDLS_PEER; |
| else /* addStaRsp->tdlsAddOper must be TDLS_OPER_UPDATE */ |
| roamResult = eCSR_ROAM_RESULT_UPDATE_TDLS_PEER; |
| csrRoamCallCallback(pMac, addStaRsp->sessionId, &roamInfo, 0, |
| eCSR_ROAM_TDLS_STATUS_UPDATE, |
| roamResult); |
| |
| /* remove pending eSmeCommandTdlsDiscovery command */ |
| csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsAddPeer) ; |
| } |
| break; |
| case eWNI_SME_TDLS_DEL_STA_RSP: |
| { |
| tSirTdlsDelStaRsp *delStaRsp = (tSirTdlsDelStaRsp *) pMsgBuf ; |
| |
| vos_mem_copy( &roamInfo.peerMac, delStaRsp->peerMac, |
| sizeof(tSirMacAddr)) ; |
| roamInfo.staId = delStaRsp->staId ; |
| roamInfo.statusCode = delStaRsp->statusCode ; |
| /* |
| * register peer with TL, we have to go through HDD as this is |
| * the only way to register any STA with TL. |
| */ |
| csrRoamCallCallback(pMac, delStaRsp->sessionId, &roamInfo, 0, |
| eCSR_ROAM_TDLS_STATUS_UPDATE, |
| eCSR_ROAM_RESULT_DELETE_TDLS_PEER); |
| csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsDelPeer); |
| csrRoamCallCallback(pMac, delStaRsp->sessionId, &roamInfo, 0, |
| eCSR_ROAM_TDLS_STATUS_UPDATE, |
| eCSR_ROAM_TDLS_CHECK_BMPS); |
| } |
| break; |
| case eWNI_SME_TDLS_DEL_STA_IND: |
| { |
| tpSirTdlsDelStaInd pSirTdlsDelStaInd = (tpSirTdlsDelStaInd) pMsgBuf ; |
| vos_mem_copy( &roamInfo.peerMac, pSirTdlsDelStaInd->peerMac, |
| sizeof(tSirMacAddr)) ; |
| roamInfo.staId = pSirTdlsDelStaInd->staId ; |
| roamInfo.reasonCode = pSirTdlsDelStaInd->reasonCode ; |
| |
| /* Sending the TEARDOWN indication to HDD. */ |
| csrRoamCallCallback(pMac, pSirTdlsDelStaInd->sessionId, &roamInfo, 0, |
| eCSR_ROAM_TDLS_STATUS_UPDATE, |
| eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND); |
| break ; |
| } |
| case eWNI_SME_TDLS_DEL_ALL_PEER_IND: |
| { |
| tpSirTdlsDelAllPeerInd pSirTdlsDelAllPeerInd = (tpSirTdlsDelAllPeerInd) pMsgBuf ; |
| |
| /* Sending the TEARDOWN indication to HDD. */ |
| csrRoamCallCallback(pMac, pSirTdlsDelAllPeerInd->sessionId, &roamInfo, 0, |
| eCSR_ROAM_TDLS_STATUS_UPDATE, |
| eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND); |
| break ; |
| } |
| case eWNI_SME_MGMT_FRM_TX_COMPLETION_IND: |
| { |
| tpSirMgmtTxCompletionInd pSirTdlsDelAllPeerInd = (tpSirMgmtTxCompletionInd) pMsgBuf ; |
| roamInfo.reasonCode = pSirTdlsDelAllPeerInd->txCompleteStatus; |
| |
| csrRoamCallCallback(pMac, pSirTdlsDelAllPeerInd->sessionId, &roamInfo, |
| 0, eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND, 0); |
| break; |
| } |
| case eWNI_SME_TDLS_LINK_ESTABLISH_RSP: |
| { |
| tSirTdlsLinkEstablishReqRsp *linkEstablishReqRsp = (tSirTdlsLinkEstablishReqRsp *) pMsgBuf ; |
| vos_mem_copy(&roamInfo.peerMac, linkEstablishReqRsp->peerMac, |
| sizeof(tSirMacAddr)); |
| roamInfo.staId = (uint8_t)linkEstablishReqRsp->sta_idx; |
| roamInfo.statusCode = linkEstablishReqRsp->statusCode; |
| csrRoamCallCallback(pMac, linkEstablishReqRsp->sessionId, &roamInfo, 0, |
| eCSR_ROAM_TDLS_STATUS_UPDATE, |
| eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP); |
| /* remove pending eSmeCommandTdlsLinkEstablish command */ |
| csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsLinkEstablish); |
| break; |
| } |
| case eWNI_SME_TDLS_SHOULD_DISCOVER: |
| { |
| tSirTdlsEventNotify *tevent = (tSirTdlsEventNotify *) pMsgBuf; |
| vos_mem_copy(&roamInfo.peerMac, tevent->peerMac, |
| sizeof(tSirMacAddr)); |
| roamInfo.reasonCode = tevent->peer_reason; |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, |
| "%s: eWNI_SME_TDLS_SHOULD_DISCOVER for peer mac: " |
| MAC_ADDRESS_STR " peer_reason: %d", |
| __func__, MAC_ADDR_ARRAY(tevent->peerMac), |
| tevent->peer_reason); |
| csrRoamCallCallback(pMac, tevent->sessionId, &roamInfo, 0, |
| eCSR_ROAM_TDLS_STATUS_UPDATE, |
| eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER); |
| break; |
| } |
| case eWNI_SME_TDLS_SHOULD_TEARDOWN: |
| { |
| tSirTdlsEventNotify *tevent = (tSirTdlsEventNotify *) pMsgBuf; |
| vos_mem_copy(&roamInfo.peerMac, tevent->peerMac, |
| sizeof(tSirMacAddr)); |
| roamInfo.reasonCode = tevent->peer_reason; |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, |
| "%s: eWNI_SME_TDLS_SHOULD_TEARDOWN for peer mac: " |
| MAC_ADDRESS_STR " peer_reason: %d", |
| __func__, MAC_ADDR_ARRAY(tevent->peerMac), |
| tevent->peer_reason); |
| csrRoamCallCallback(pMac, tevent->sessionId, &roamInfo, 0, |
| eCSR_ROAM_TDLS_STATUS_UPDATE, |
| eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN); |
| break; |
| } |
| case eWNI_SME_TDLS_PEER_DISCONNECTED: |
| { |
| tSirTdlsEventNotify *tevent = (tSirTdlsEventNotify *) pMsgBuf; |
| vos_mem_copy(&roamInfo.peerMac, tevent->peerMac, |
| sizeof(tSirMacAddr)); |
| roamInfo.reasonCode = tevent->peer_reason; |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, |
| "%s: eWNI_SME_TDLS_PEER_DISCONNECTED for peer mac: " |
| MAC_ADDRESS_STR " peer_reason: %d", |
| __func__, MAC_ADDR_ARRAY(tevent->peerMac), |
| tevent->peer_reason); |
| csrRoamCallCallback(pMac, tevent->sessionId, &roamInfo, 0, |
| eCSR_ROAM_TDLS_STATUS_UPDATE, |
| eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED); |
| break; |
| } |
| default: |
| { |
| break ; |
| } |
| } |
| |
| return eHAL_STATUS_SUCCESS ; |
| } |
| #endif |