blob: 44f600cf62b393ed6b3d70847628c48e607d2e17 [file] [log] [blame]
/*
* 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