qcacld-3.0: Move CSR preauth related code to a separate file

Move the preauthentication related code in the CSR module
into a separate file so that it is easy to maintain
across different projects

CRs-Fixed: 978905
Change-Id: I56e8441f08dec180f080c305ba5c6541302f107c
This commit is contained in:
Varun Reddy Yeturu
2016-02-19 11:32:52 -08:00
committed by Gerrit - the friendly Code Review server
父節點 d318632e76
當前提交 883c4f20f9
共有 6 個文件被更改,包括 779 次插入758 次删除

1
Kbuild
查看文件

@@ -500,6 +500,7 @@ SME_INC := -I$(WLAN_ROOT)/$(SME_INC_DIR) \
-I$(WLAN_ROOT)/$(SME_SRC_DIR)/csr
SME_CSR_OBJS := $(SME_SRC_DIR)/csr/csr_api_roam.o \
$(SME_SRC_DIR)/csr/csr_roam_preauth.o \
$(SME_SRC_DIR)/csr/csr_api_scan.o \
$(SME_SRC_DIR)/csr/csr_cmd_process.o \
$(SME_SRC_DIR)/csr/csr_link_list.o \

查看文件

@@ -298,5 +298,27 @@ void csr_roam_synch_callback(tpAniSirGlobal mac,
void csr_neighbor_roam_state_transition(tpAniSirGlobal mac_ctx,
uint8_t newstate, uint8_t session);
uint8_t *csr_neighbor_roam_state_to_string(uint8_t state);
tpCsrNeighborRoamBSSInfo csr_neighbor_roam_next_roamable_ap(
tpAniSirGlobal mac_ctx, tDblLinkList *llist,
tpCsrNeighborRoamBSSInfo neighbor_entry);
bool csr_neighbor_roam_remove_roamable_ap_list_entry(tpAniSirGlobal pMac,
tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry);
void csr_neighbor_roam_free_neighbor_roam_bss_node(tpAniSirGlobal pMac,
tpCsrNeighborRoamBSSInfo neighborRoamBSSNode);
QDF_STATUS csr_neighbor_roam_issue_preauth_req(tpAniSirGlobal pMac,
uint8_t sessionId);
void csr_neighbor_roam_reset_preauth_control_info(
tpAniSirGlobal mac_ctx, uint8_t session_id);
bool csr_neighbor_roam_is_preauth_candidate(tpAniSirGlobal pMac,
uint8_t sessionId, tSirMacAddr bssId);
#ifdef FEATURE_WLAN_LFR_METRICS
void csr_neighbor_roam_send_lfr_metric_event(tpAniSirGlobal mac_ctx,
uint8_t session_id, tSirMacAddr bssid, eRoamCmdStatus status);
#else
static inline void csr_neighbor_roam_send_lfr_metric_event(
tpAniSirGlobal mac_ctx, uint8_t session_id,
tSirMacAddr bssid, eRoamCmdStatus status)
{}
#endif
#endif /* CSR_NEIGHBOR_ROAM_H */

查看文件

@@ -280,7 +280,6 @@ static QDF_STATUS csr_roam_get_qos_info_from_bss(tpAniSirGlobal pMac,
void csr_roam_reissue_roam_command(tpAniSirGlobal pMac);
static void csr_ser_des_unpack_diassoc_rsp(uint8_t *pBuf,
tSirSmeDisassocRsp *pRsp);
void csr_reinit_preauth_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand);
void csr_init_operating_classes(tHalHandle hHal);
/* Initialize global variables */
@@ -1089,12 +1088,6 @@ static QDF_STATUS csr_roam_free_connected_info(tpAniSirGlobal pMac,
return status;
}
void csr_release_command_preauth(tpAniSirGlobal pMac, tSmeCmd *pCommand)
{
csr_reinit_preauth_cmd(pMac, pCommand);
csr_release_command(pMac, pCommand);
}
void csr_release_command_roam(tpAniSirGlobal pMac, tSmeCmd *pCommand)
{
csr_reinit_roam_cmd(pMac, pCommand);
@@ -5508,14 +5501,6 @@ QDF_STATUS csr_roam_process_command(tpAniSirGlobal pMac, tSmeCmd *pCommand)
return status;
}
void csr_reinit_preauth_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
{
pCommand->u.roamCmd.pLastRoamBss = NULL;
pCommand->u.roamCmd.pRoamBssEntry = NULL;
/* Because u.roamCmd is union and share with scanCmd and StatusChange */
qdf_mem_set(&pCommand->u.roamCmd, sizeof(tRoamCmd), 0);
}
void csr_reinit_roam_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
{
if (pCommand->u.roamCmd.fReleaseBssList) {
@@ -7323,42 +7308,6 @@ QDF_STATUS csr_roam_issue_reassoc(tpAniSirGlobal pMac, uint32_t sessionId,
return status;
}
QDF_STATUS csr_roam_enqueue_preauth(tpAniSirGlobal pMac, uint32_t sessionId,
tpSirBssDescription pBssDescription,
eCsrRoamReason reason, bool fImmediate)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
tSmeCmd *pCommand;
pCommand = csr_get_command_buffer(pMac);
if (NULL == pCommand) {
sms_log(pMac, LOGE, FL(" fail to get command buffer"));
status = QDF_STATUS_E_RESOURCES;
} else {
if (pBssDescription) {
/* copy over the parameters we need later */
pCommand->command = eSmeCommandRoam;
pCommand->sessionId = (uint8_t) sessionId;
pCommand->u.roamCmd.roamReason = reason;
/* this is the important parameter */
/* in this case we are using this field for the "next" BSS */
pCommand->u.roamCmd.pLastRoamBss = pBssDescription;
status = csr_queue_sme_command(pMac, pCommand, fImmediate);
if (!QDF_IS_STATUS_SUCCESS(status)) {
sms_log(pMac, LOGE,
FL
(" fail to enqueue preauth command, status = %d"),
status);
csr_release_command_preauth(pMac, pCommand);
}
} else {
/* Return failure */
status = QDF_STATUS_E_RESOURCES;
}
}
return status;
}
QDF_STATUS csr_dequeue_roam_command(tpAniSirGlobal pMac, eCsrRoamReason reason)
{
tListElem *pEntry;
@@ -17743,213 +17692,6 @@ QDF_STATUS csr_roam_update_wparsni_es(tpAniSirGlobal pMac, uint32_t sessionId,
return status;
}
QDF_STATUS
csr_roam_issue_ft_preauth_req(tHalHandle hHal, uint32_t sessionId,
tpSirBssDescription pBssDescription)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
tpSirFTPreAuthReq pftPreAuthReq;
uint16_t auth_req_len = 0;
tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
if (NULL == pSession) {
sms_log(pMac, LOGE,
FL("Session does not exist for session id(%d)"),
sessionId);
return QDF_STATUS_E_FAILURE;
}
auth_req_len = sizeof(tSirFTPreAuthReq);
pftPreAuthReq = (tpSirFTPreAuthReq) qdf_mem_malloc(auth_req_len);
if (NULL == pftPreAuthReq) {
sms_log(pMac, LOGE,
FL("Memory allocation for FT Preauth request failed"));
return QDF_STATUS_E_NOMEM;
}
/* Save the SME Session ID here. We need it while processing the preauth response */
pSession->ftSmeContext.smeSessionId = sessionId;
qdf_mem_zero(pftPreAuthReq, auth_req_len);
pftPreAuthReq->pbssDescription =
(tpSirBssDescription) qdf_mem_malloc(sizeof(pBssDescription->length)
+ pBssDescription->length);
if (NULL == pftPreAuthReq->pbssDescription) {
sms_log(pMac, LOGE,
FL("Memory allocation for FT Preauth request failed"));
return QDF_STATUS_E_NOMEM;
}
pftPreAuthReq->messageType = eWNI_SME_FT_PRE_AUTH_REQ;
pftPreAuthReq->preAuthchannelNum = pBssDescription->channelId;
qdf_mem_copy((void *)&pftPreAuthReq->currbssId,
(void *)pSession->connectedProfile.bssid.bytes,
sizeof(tSirMacAddr));
qdf_mem_copy((void *)&pftPreAuthReq->preAuthbssId,
(void *)pBssDescription->bssId, sizeof(tSirMacAddr));
qdf_mem_copy((void *)&pftPreAuthReq->self_mac_addr,
(void *)&pSession->selfMacAddr.bytes, sizeof(tSirMacAddr));
if (csr_roam_is11r_assoc(pMac, sessionId) &&
(pMac->roam.roamSession[sessionId].connectedProfile.AuthType !=
eCSR_AUTH_TYPE_OPEN_SYSTEM)) {
pftPreAuthReq->ft_ies_length =
(uint16_t) pSession->ftSmeContext.auth_ft_ies_length;
qdf_mem_copy(pftPreAuthReq->ft_ies,
pSession->ftSmeContext.auth_ft_ies,
pSession->ftSmeContext.auth_ft_ies_length);
} else {
pftPreAuthReq->ft_ies_length = 0;
}
qdf_mem_copy(pftPreAuthReq->pbssDescription, pBssDescription,
sizeof(pBssDescription->length) + pBssDescription->length);
pftPreAuthReq->length = auth_req_len;
return cds_send_mb_message_to_mac(pftPreAuthReq);
}
/*--------------------------------------------------------------------------
* This will receive and process the FT Pre Auth Rsp from the current
* associated ap.
*
* This will invoke the hdd call back. This is so that hdd can now
* send the FTIEs from the Auth Rsp (Auth Seq 2) to the supplicant.
------------------------------------------------------------------------*/
void csr_roam_ft_pre_auth_rsp_processor(tHalHandle hHal,
tpSirFTPreAuthRsp pFTPreAuthRsp)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
QDF_STATUS status = QDF_STATUS_SUCCESS;
tCsrRoamInfo roamInfo;
eCsrAuthType conn_Auth_type;
uint32_t sessionId = pFTPreAuthRsp->smeSessionId;
tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
if (NULL == pSession) {
sms_log(pMac, LOGE, FL("pSession is NULL"));
return;
}
status = csr_neighbor_roam_preauth_rsp_handler(pMac,
pFTPreAuthRsp->smeSessionId,
pFTPreAuthRsp->status);
if (status != QDF_STATUS_SUCCESS) {
/*
* Bail out if pre-auth was not even processed.
*/
sms_log(pMac, LOGE,
FL("Preauth was not processed: %d SessionID: %d"),
status, sessionId);
return;
}
/* The below function calls/timers should be invoked only if the pre-auth is successful */
if (QDF_STATUS_SUCCESS != (QDF_STATUS) pFTPreAuthRsp->status)
return;
/* Implies a success */
pSession->ftSmeContext.FTState = eFT_AUTH_COMPLETE;
/* Indicate SME QoS module the completion of Preauth success. This will trigger the creation of RIC IEs */
pSession->ftSmeContext.psavedFTPreAuthRsp = pFTPreAuthRsp;
/* No need to notify qos module if this is a non 11r & ESE roam */
if (csr_roam_is11r_assoc(pMac, pFTPreAuthRsp->smeSessionId)
#ifdef FEATURE_WLAN_ESE
|| csr_roam_is_ese_assoc(pMac, pFTPreAuthRsp->smeSessionId)
#endif
) {
sme_qos_csr_event_ind(pMac,
pSession->ftSmeContext.smeSessionId,
SME_QOS_CSR_PREAUTH_SUCCESS_IND, NULL);
}
/* Start the pre-auth reassoc interval timer with a period of 400ms. When this expires,
* actual transition from the current to handoff AP is triggered */
status =
qdf_mc_timer_start(&pSession->ftSmeContext.preAuthReassocIntvlTimer,
60);
if (QDF_STATUS_SUCCESS != status) {
sms_log(pMac, LOGE,
FL
("Preauth reassoc interval timer start failed to start with status %d"),
status);
return;
}
/* Save the received response */
qdf_mem_copy((void *)&pSession->ftSmeContext.preAuthbssId,
(void *)pFTPreAuthRsp->preAuthbssId, sizeof(struct qdf_mac_addr));
if (csr_roam_is11r_assoc(pMac, pFTPreAuthRsp->smeSessionId))
csr_roam_call_callback(pMac, pFTPreAuthRsp->smeSessionId, NULL, 0,
eCSR_ROAM_FT_RESPONSE,
eCSR_ROAM_RESULT_NONE);
#ifdef FEATURE_WLAN_ESE
if (csr_roam_is_ese_assoc(pMac, pFTPreAuthRsp->smeSessionId)) {
/* read TSF */
csr_roam_read_tsf(pMac, (uint8_t *) roamInfo.timestamp,
pFTPreAuthRsp->smeSessionId);
/* Save the bssid from the received response */
qdf_mem_copy((void *)&roamInfo.bssid,
(void *)pFTPreAuthRsp->preAuthbssId,
sizeof(struct qdf_mac_addr));
csr_roam_call_callback(pMac, pFTPreAuthRsp->smeSessionId,
&roamInfo, 0, eCSR_ROAM_CCKM_PREAUTH_NOTIFY,
0);
}
#endif /* FEATURE_WLAN_ESE */
/* If Legacy Fast Roaming is enabled, signal the supplicant */
/* So he can send us a PMK-ID for this candidate AP. */
if (csr_roam_is_fast_roam_enabled(pMac, pFTPreAuthRsp->smeSessionId)) {
/* Save the bssid from the received response */
qdf_mem_copy((void *)&roamInfo.bssid,
(void *)pFTPreAuthRsp->preAuthbssId,
sizeof(struct qdf_mac_addr));
csr_roam_call_callback(pMac, pFTPreAuthRsp->smeSessionId,
&roamInfo, 0, eCSR_ROAM_PMK_NOTIFY, 0);
}
/* If its an Open Auth, FT IEs are not provided by supplicant */
/* Hence populate them here */
conn_Auth_type =
pMac->roam.roamSession[sessionId].connectedProfile.AuthType;
pSession->ftSmeContext.addMDIE = false;
/* Done with it, init it. */
pSession->ftSmeContext.psavedFTPreAuthRsp = NULL;
if (csr_roam_is11r_assoc(pMac, pFTPreAuthRsp->smeSessionId) &&
(conn_Auth_type == eCSR_AUTH_TYPE_OPEN_SYSTEM)) {
uint16_t ft_ies_length;
ft_ies_length = pFTPreAuthRsp->ric_ies_length;
if ((pSession->ftSmeContext.reassoc_ft_ies) &&
(pSession->ftSmeContext.reassoc_ft_ies_length)) {
qdf_mem_free(pSession->ftSmeContext.reassoc_ft_ies);
pSession->ftSmeContext.reassoc_ft_ies_length = 0;
pSession->ftSmeContext.reassoc_ft_ies = NULL;
}
if (!ft_ies_length)
return;
pSession->ftSmeContext.reassoc_ft_ies =
qdf_mem_malloc(ft_ies_length);
if (NULL == pSession->ftSmeContext.reassoc_ft_ies) {
sms_log(pMac, LOGE,
FL("Memory allocation failed for ft_ies"));
return;
} else {
/* Copy the RIC IEs to reassoc IEs */
qdf_mem_copy(((uint8_t *) pSession->ftSmeContext.
reassoc_ft_ies),
(uint8_t *) pFTPreAuthRsp->ric_ies,
pFTPreAuthRsp->ric_ies_length);
pSession->ftSmeContext.reassoc_ft_ies_length =
ft_ies_length;
pSession->ftSmeContext.addMDIE = true;
}
}
}
/*
pBuf points to the beginning of the message
LIM packs disassoc rsp as below,

查看文件

@@ -1058,3 +1058,4 @@ bool is_disconnect_pending(tpAniSirGlobal mac_ctx,
void csr_scan_active_list_timeout_handle(void *userData);
QDF_STATUS csr_prepare_disconnect_command(tpAniSirGlobal mac,
uint32_t session_id, tSmeCmd **sme_cmd);
void csr_release_command_preauth(tpAniSirGlobal mac_ctx, tSmeCmd *command);

查看文件

@@ -52,15 +52,10 @@
static void csr_neighbor_roam_reset_channel_info(tpCsrNeighborRoamChannelInfo
rChInfo);
static void csr_neighbor_roam_reset_preauth_control_info(tpAniSirGlobal pMac,
uint8_t sessionId);
QDF_STATUS csr_roam_copy_connected_profile(tpAniSirGlobal pMac, uint32_t sessionId,
tCsrRoamProfile *pDstProfile);
static QDF_STATUS csr_neighbor_roam_issue_preauth_req(tpAniSirGlobal pMac,
uint8_t sessionId);
void csr_neighbor_roam_state_transition(tpAniSirGlobal mac_ctx,
uint8_t newstate, uint8_t session)
{
@@ -103,7 +98,7 @@ uint8_t *csr_neighbor_roam_state_to_string(uint8_t state)
* Return: void
*/
static void csr_neighbor_roam_send_lfr_metric_event(
void csr_neighbor_roam_send_lfr_metric_event(
tpAniSirGlobal mac_ctx,
uint8_t session_id,
tSirMacAddr bssid,
@@ -122,16 +117,6 @@ static void csr_neighbor_roam_send_lfr_metric_event(
qdf_mem_free(roam_info);
}
}
#else
/* Empty inline function will be a no-op */
static inline void csr_neighbor_roam_send_lfr_metric_event(
tpAniSirGlobal mac_ctx,
uint8_t session_id,
tSirMacAddr bssid,
eRoamCmdStatus status)
{
;
}
#endif
/**
@@ -633,30 +618,6 @@ static void csr_neighbor_roam_reset_channel_info(tpCsrNeighborRoamChannelInfo
}
}
static void csr_neighbor_roam_reset_preauth_control_info(tpAniSirGlobal pMac,
uint8_t sessionId)
{
tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
&pMac->roam.neighborRoamInfo[sessionId];
pNeighborRoamInfo->is11rAssoc = false;
/* Purge pre-auth fail list */
csr_neighbor_roam_purge_preauth_failed_list(pMac);
pNeighborRoamInfo->FTRoamInfo.preauthRspPending = false;
pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
/* Do not free up the preauth done list here */
pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
pNeighborRoamInfo->FTRoamInfo.neighborRptPending = false;
pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
qdf_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo,
sizeof(tCsrNeighborReportBssInfo) *
MAX_BSS_IN_NEIGHBOR_RPT);
pNeighborRoamInfo->uOsRequestedHandoff = 0;
qdf_mem_zero(&pNeighborRoamInfo->handoffReqInfo,
sizeof(tCsrHandoffRequest));
}
/**
* csr_neighbor_roam_reset_connected_state_control_info()
*
@@ -734,384 +695,6 @@ void csr_neighbor_roam_reset_init_state_control_info(tpAniSirGlobal pMac,
csr_neighbor_roam_reset_report_scan_state_control_info(pMac, sessionId);
}
/* ---------------------------------------------------------------------------
\fn csr_neighbor_roam_purge_preauth_fail_list
\brief This function empties the preauth fail list
\param pMac - The handle returned by mac_open.
\return VOID
---------------------------------------------------------------------------*/
void csr_neighbor_roam_purge_preauth_fail_list(tpAniSirGlobal pMac)
{
uint8_t i;
tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Purging the preauth fail list"));
for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[i];
while (pNeighborRoamInfo->FTRoamInfo.preAuthFailList.
numMACAddress) {
qdf_mem_zero(pNeighborRoamInfo->FTRoamInfo.
preAuthFailList.
macAddress[pNeighborRoamInfo->FTRoamInfo.
preAuthFailList.numMACAddress -
1], sizeof(tSirMacAddr));
pNeighborRoamInfo->FTRoamInfo.preAuthFailList.
numMACAddress--;
}
}
return;
}
/**
* csr_neighbor_roam_add_preauth_fail() - add bssid to preauth failed list
* @mac_ctx: The handle returned by mac_open.
* @bssid: BSSID to be added to the preauth fail list
*
* This function adds the given BSSID to the Preauth fail list
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
*/
QDF_STATUS csr_neighbor_roam_add_preauth_fail(tpAniSirGlobal mac_ctx,
uint8_t session_id,
tSirMacAddr bssid)
{
uint8_t i = 0;
tpCsrNeighborRoamControlInfo neighbor_roam_info =
&mac_ctx->roam.neighborRoamInfo[session_id];
uint8_t num_mac_addr = neighbor_roam_info->FTRoamInfo.preAuthFailList.
numMACAddress;
NEIGHBOR_ROAM_DEBUG(mac_ctx, LOGE,
FL(" Added BSSID " MAC_ADDRESS_STR " to Preauth failed list"),
MAC_ADDR_ARRAY(bssid));
for (i = 0;
i < neighbor_roam_info->FTRoamInfo.preAuthFailList.numMACAddress;
i++) {
if (true != qdf_mem_cmp(
neighbor_roam_info->FTRoamInfo.preAuthFailList.macAddress[i],
bssid, sizeof(tSirMacAddr))) {
sms_log(mac_ctx, LOGW, FL("BSSID "MAC_ADDRESS_STR" already present in preauth fail list"),
MAC_ADDR_ARRAY(bssid));
return QDF_STATUS_SUCCESS;
}
}
if ((num_mac_addr + 1) > MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS) {
sms_log(mac_ctx, LOGE,
FL("Cannot add, preauth fail list is full."));
return QDF_STATUS_E_FAILURE;
}
qdf_mem_copy(neighbor_roam_info->FTRoamInfo.preAuthFailList.
macAddress[num_mac_addr], bssid, sizeof(tSirMacAddr));
neighbor_roam_info->FTRoamInfo.preAuthFailList.numMACAddress++;
return QDF_STATUS_SUCCESS;
}
/**
* csr_neighbor_roam_is_preauth_candidate()
*
* @mac_ctx: Pointer to Global MAC structure
* @bssId : BSSID of the candidate
*
* This function checks whether the given MAC address is already present
* in the preauth fail list and returns true/false accordingly
*
* Return: true if preauth candidate, false otherwise
*/
bool csr_neighbor_roam_is_preauth_candidate(tpAniSirGlobal pMac,
uint8_t sessionId, tSirMacAddr bssId)
{
uint8_t i = 0;
tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
&pMac->roam.neighborRoamInfo[sessionId];
if (csr_roam_is_roam_offload_scan_enabled(pMac)) {
return true;
}
if (0 == pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
return true;
for (i = 0;
i < pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress;
i++) {
if (true !=
qdf_mem_cmp(pNeighborRoamInfo->FTRoamInfo.
preAuthFailList.macAddress[i], bssId,
sizeof(tSirMacAddr))) {
NEIGHBOR_ROAM_DEBUG(pMac, LOGE,
FL("BSSID " MAC_ADDRESS_STR
" already present in preauth fail list"),
MAC_ADDR_ARRAY(bssId));
return false;
}
}
return true;
}
/**
* csr_neighbor_roam_issue_preauth_req() - Send preauth request to first AP
* @mac_ctx: The handle returned by mac_open.
* @session_id: Session information
*
* This function issues preauth request to PE with the 1st AP entry in the
* roamable AP list
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
*/
static QDF_STATUS csr_neighbor_roam_issue_preauth_req(tpAniSirGlobal mac_ctx,
uint8_t session_id)
{
tpCsrNeighborRoamControlInfo neighbor_roam_info =
&mac_ctx->roam.neighborRoamInfo[session_id];
QDF_STATUS status = QDF_STATUS_SUCCESS;
tpCsrNeighborRoamBSSInfo neighbor_bss_node;
if (false != neighbor_roam_info->FTRoamInfo.preauthRspPending) {
/* This must not be true here */
QDF_ASSERT(neighbor_roam_info->FTRoamInfo.preauthRspPending ==
false);
return QDF_STATUS_E_FAILURE;
}
/*
* Issue Preauth request to PE here.
* Need to issue the preauth request with the BSSID that is in the
* head of the roamable AP list. Parameters that should be passed are
* BSSID, Channel number and the neighborScanPeriod(probably). If
* roamableAPList gets empty, should transition to REPORT_SCAN state
*/
neighbor_bss_node = csr_neighbor_roam_next_roamable_ap(mac_ctx,
&neighbor_roam_info->roamableAPList, NULL);
if (NULL == neighbor_bss_node) {
sms_log(mac_ctx, LOGW, FL("Roamable AP list is empty.. "));
return QDF_STATUS_E_FAILURE;
} else {
csr_neighbor_roam_send_lfr_metric_event(mac_ctx, session_id,
neighbor_bss_node->pBssDescription->bssId,
eCSR_ROAM_PREAUTH_INIT_NOTIFY);
status = csr_roam_enqueue_preauth(mac_ctx, session_id,
neighbor_bss_node->pBssDescription,
eCsrPerformPreauth, true);
sms_log(mac_ctx, LOG1,
FL("Before Pre-Auth: BSSID " MAC_ADDRESS_STR ", Ch:%d"),
MAC_ADDR_ARRAY(
neighbor_bss_node->pBssDescription->bssId),
(int)neighbor_bss_node->pBssDescription->channelId);
if (QDF_STATUS_SUCCESS != status) {
sms_log(mac_ctx, LOGE,
FL("Return failed preauth request status %d"),
status);
return status;
}
}
neighbor_roam_info->FTRoamInfo.preauthRspPending = true;
/* Increment the preauth retry count */
neighbor_roam_info->FTRoamInfo.numPreAuthRetries++;
/* Transition the state to preauthenticating */
csr_neighbor_roam_state_transition(mac_ctx,
eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING, session_id);
return status;
}
/**
* csr_neighbor_roam_preauth_rsp_handler() - handle preauth response
* @mac_ctx: The handle returned by mac_open.
* @session_id: SME session
* @lim_status: eSIR_SUCCESS/eSIR_FAILURE/eSIR_LIM_MAX_STA_REACHED_ERROR/
* eSIT_LIM_AUTH_RSP_TIMEOUT status from PE
*
* This function handle the Preauth response from PE
* Every preauth is allowed max 3 tries if it fails. If a bssid failed
* for more than MAX_TRIES, we will remove it from the list and try
* with the next node in the roamable AP list and add the BSSID to
* pre-auth failed list. If no more entries present in roamable AP list,
* transition to REPORT_SCAN state.
*
* Return: QDF_STATUS_SUCCESS on success (i.e. pre-auth processed),
* QDF_STATUS_E_FAILURE otherwise
*/
QDF_STATUS csr_neighbor_roam_preauth_rsp_handler(tpAniSirGlobal mac_ctx,
uint8_t session_id,
tSirRetStatus lim_status)
{
tpCsrNeighborRoamControlInfo neighbor_roam_info =
&mac_ctx->roam.neighborRoamInfo[session_id];
QDF_STATUS status = QDF_STATUS_SUCCESS;
QDF_STATUS preauth_processed = QDF_STATUS_SUCCESS;
tpCsrNeighborRoamBSSInfo preauth_rsp_node = NULL;
if (false == neighbor_roam_info->FTRoamInfo.preauthRspPending) {
/*
* This can happen when we disconnect immediately
* after sending a pre-auth request. During processing
* of the disconnect command, we would have reset
* preauthRspPending and transitioned to INIT state.
*/
NEIGHBOR_ROAM_DEBUG(mac_ctx, LOGW,
FL("Unexpected pre-auth response in state %d"),
neighbor_roam_info->neighborRoamState);
preauth_processed = QDF_STATUS_E_FAILURE;
goto DEQ_PREAUTH;
}
/* We can receive it in these 2 states. */
if ((neighbor_roam_info->neighborRoamState !=
eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING)) {
NEIGHBOR_ROAM_DEBUG(mac_ctx, LOGW,
FL("Preauth response received in state %s"),
mac_trace_get_neighbour_roam_state
(neighbor_roam_info->neighborRoamState));
preauth_processed = QDF_STATUS_E_FAILURE;
goto DEQ_PREAUTH;
}
neighbor_roam_info->FTRoamInfo.preauthRspPending = false;
if (eSIR_SUCCESS == lim_status)
preauth_rsp_node =
csr_neighbor_roam_next_roamable_ap(
mac_ctx,
&neighbor_roam_info->roamableAPList,
NULL);
if ((eSIR_SUCCESS == lim_status) && (NULL != preauth_rsp_node)) {
NEIGHBOR_ROAM_DEBUG(mac_ctx, LOG1,
FL("Preauth completed successfully after %d tries"),
neighbor_roam_info->FTRoamInfo.numPreAuthRetries);
sms_log(mac_ctx, LOG1,
FL("After Pre-Auth: BSSID " MAC_ADDRESS_STR ", Ch:%d"),
MAC_ADDR_ARRAY(
preauth_rsp_node->pBssDescription->bssId),
(int)preauth_rsp_node->pBssDescription->channelId);
csr_neighbor_roam_send_lfr_metric_event(mac_ctx, session_id,
preauth_rsp_node->pBssDescription->bssId,
eCSR_ROAM_PREAUTH_STATUS_SUCCESS);
/*
* Preauth completed successfully. Insert the preauthenticated
* node to tail of preAuthDoneList.
*/
csr_neighbor_roam_remove_roamable_ap_list_entry(mac_ctx,
&neighbor_roam_info->roamableAPList,
preauth_rsp_node);
csr_ll_insert_tail(
&neighbor_roam_info->FTRoamInfo.preAuthDoneList,
&preauth_rsp_node->List, LL_ACCESS_LOCK);
/* Pre-auth successful. Transition to PREAUTH Done state */
csr_neighbor_roam_state_transition(mac_ctx,
eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE, session_id);
neighbor_roam_info->FTRoamInfo.numPreAuthRetries = 0;
/*
* The caller of this function would start a timer and by
* the time it expires, supplicant should have provided
* the updated FTIEs to SME. So, when it expires, handoff
* will be triggered then.
*/
} else {
tpCsrNeighborRoamBSSInfo neighbor_bss_node = NULL;
tListElem *entry;
bool is_dis_pending = false;
sms_log(mac_ctx, LOGE,
FL("Preauth failed retry number %d, status = 0x%x"),
neighbor_roam_info->FTRoamInfo.numPreAuthRetries,
lim_status);
/*
* Preauth failed. Add the bssId to the preAuth failed list
* of MAC Address. Also remove the AP from roamable AP list.
*/
if ((neighbor_roam_info->FTRoamInfo.numPreAuthRetries >=
CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES) ||
(eSIR_LIM_MAX_STA_REACHED_ERROR == lim_status)) {
/*
* We are going to remove the node as it fails for
* more than MAX tries. Reset this count to 0
*/
neighbor_roam_info->FTRoamInfo.numPreAuthRetries = 0;
/*
* The one in the head of the list should be one with
* which we issued pre-auth and failed
*/
entry = csr_ll_remove_head(
&neighbor_roam_info->roamableAPList,
LL_ACCESS_LOCK);
if (!entry) {
sms_log(mac_ctx, LOGE,
FL("Preauth list is empty"));
goto NEXT_PREAUTH;
}
neighbor_bss_node = GET_BASE_ADDR(entry,
tCsrNeighborRoamBSSInfo,
List);
/*
* Add the BSSID to pre-auth fail list if
* it is not requested by HDD
*/
if (!neighbor_roam_info->uOsRequestedHandoff)
status =
csr_neighbor_roam_add_preauth_fail(
mac_ctx, session_id,
neighbor_bss_node->
pBssDescription->bssId);
csr_neighbor_roam_send_lfr_metric_event(mac_ctx,
session_id,
neighbor_bss_node->pBssDescription->bssId,
eCSR_ROAM_PREAUTH_STATUS_FAILURE);
/* Now we can free this node */
csr_neighbor_roam_free_neighbor_roam_bss_node(
mac_ctx, neighbor_bss_node);
}
NEXT_PREAUTH:
is_dis_pending = is_disconnect_pending(mac_ctx, session_id);
if (is_dis_pending) {
sms_log(mac_ctx, LOGE,
FL("Disconnect in progress, Abort preauth"));
goto ABORT_PREAUTH;
}
/* Issue preauth request for the same/next entry */
if (QDF_STATUS_SUCCESS == csr_neighbor_roam_issue_preauth_req(
mac_ctx, session_id))
goto DEQ_PREAUTH;
ABORT_PREAUTH:
if (csr_roam_is_roam_offload_scan_enabled(mac_ctx)) {
if (neighbor_roam_info->uOsRequestedHandoff) {
neighbor_roam_info->uOsRequestedHandoff = 0;
csr_roam_offload_scan(mac_ctx, 0,
ROAM_SCAN_OFFLOAD_START,
REASON_PREAUTH_FAILED_FOR_ALL);
} else {
csr_roam_offload_scan(mac_ctx, 0,
ROAM_SCAN_OFFLOAD_RESTART,
REASON_PREAUTH_FAILED_FOR_ALL);
}
csr_neighbor_roam_state_transition(mac_ctx,
eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, session_id);
}
}
DEQ_PREAUTH:
csr_dequeue_roam_command(mac_ctx, eCsrPerformPreauth);
return preauth_processed;
}
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
/**
* csr_neighbor_roam_offload_update_preauth_list()
@@ -2587,36 +2170,6 @@ QDF_STATUS csr_neighbor_roam_indicate_connect(
return status;
}
/* ---------------------------------------------------------------------------
\fn csr_neighbor_roam_purge_preauth_failed_list
\brief This function purges all the MAC addresses in the pre-auth fail list
\param pMac - The handle returned by mac_open.
\return VOID
---------------------------------------------------------------------------*/
void csr_neighbor_roam_purge_preauth_failed_list(tpAniSirGlobal pMac)
{
uint8_t i, j;
tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
for (j = 0; j < CSR_ROAM_SESSION_MAX; j++) {
pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[j];
for (i = 0;
i <
pNeighborRoamInfo->FTRoamInfo.preAuthFailList.
numMACAddress; i++) {
qdf_mem_zero(pNeighborRoamInfo->FTRoamInfo.
preAuthFailList.macAddress[i],
sizeof(tSirMacAddr));
}
pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress = 0;
}
}
/* ---------------------------------------------------------------------------
\fn csr_neighbor_roam_init11r_assoc_info
@@ -3081,58 +2634,6 @@ bool csr_neighbor_roam_get_handoff_ap_info(tpAniSirGlobal pMac,
return true;
}
/* ---------------------------------------------------------------------------
\brief This function returns true if preauth is completed
\param pMac - The handle returned by mac_open.
\return bool
---------------------------------------------------------------------------*/
bool csr_neighbor_roam_state_preauth_done(tpAniSirGlobal pMac, uint8_t sessionId)
{
return pMac->roam.neighborRoamInfo[sessionId].neighborRoamState ==
eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE;
}
/* ---------------------------------------------------------------------------
\brief In the event that we are associated with AP1 and we have
completed pre auth with AP2. Then we receive a deauth/disassoc from
AP1.
At this point neighbor roam is in pre auth done state, pre auth timer
is running. We now handle this case by stopping timer and clearing
the pre-auth state. We basically clear up and just go to disconnected
state.
\param pMac - The handle returned by mac_open.
\return bool
---------------------------------------------------------------------------*/
void csr_neighbor_roam_tranistion_preauth_done_to_disconnected(tpAniSirGlobal pMac,
uint8_t sessionId)
{
tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
&pMac->roam.neighborRoamInfo[sessionId];
tCsrRoamSession *session = CSR_GET_SESSION(pMac, sessionId);
if (!session) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
FL("session is NULL"));
return;
}
if (pNeighborRoamInfo->neighborRoamState !=
eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
return;
/* Stop timer */
qdf_mc_timer_stop(&session->ftSmeContext.preAuthReassocIntvlTimer);
/* Transition to init state */
csr_neighbor_roam_state_transition(pMac,
eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId);
pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = false;
}
/* ---------------------------------------------------------------------------
\brief This function returns true if STA is in the middle of roaming states

查看文件

@@ -0,0 +1,754 @@
/*
* Copyright (c) 2016 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.
*/
/**
* DOC: csr_roam_preauth.c
*
* Host based roaming preauthentication implementation
*/
#include "wma_types.h"
#include "cds_mq.h"
#include "csr_inside_api.h"
#include "sms_debug.h"
#include "sme_qos_internal.h"
#include "sme_inside.h"
#include "host_diag_core_event.h"
#include "host_diag_core_log.h"
#include "csr_api.h"
#include "sme_api.h"
#include "csr_neighbor_roam.h"
#include "mac_trace.h"
#include "cds_concurrency.h"
static void csr_reinit_preauth_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand);
static QDF_STATUS csr_neighbor_roam_add_preauth_fail(tpAniSirGlobal mac_ctx,
uint8_t session_id, tSirMacAddr bssid);
/**
* csr_neighbor_roam_state_preauth_done() - Check if state is preauth done
* @mac_ctx: Global MAC context
* @session_id: SME session ID
*
* Return: True if the state id preauth done, false otherwise
*/
bool csr_neighbor_roam_state_preauth_done(tpAniSirGlobal mac_ctx,
uint8_t session_id)
{
return mac_ctx->roam.neighborRoamInfo[session_id].neighborRoamState ==
eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE;
}
/**
* csr_neighbor_roam_tranistion_preauth_done_to_disconnected() - Transition
* the state from preauth done to disconnected
* @mac_ctx: Global MAC Context
* @session_id: SME Session ID
*
* In the event that we are associated with AP1 and we have
* completed pre auth with AP2. Then we receive a deauth/disassoc from AP1.
* At this point neighbor roam is in pre auth done state, pre auth timer
* is running. We now handle this case by stopping timer and clearing
* the pre-auth state. We basically clear up and just go to disconnected
* state
*
* Return: None
*/
void csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
tpAniSirGlobal mac_ctx, uint8_t session_id)
{
tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
&mac_ctx->roam.neighborRoamInfo[session_id];
tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
if (!session) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
FL("session is NULL"));
return;
}
if (pNeighborRoamInfo->neighborRoamState !=
eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
return;
qdf_mc_timer_stop(&session->ftSmeContext.preAuthReassocIntvlTimer);
csr_neighbor_middle_of_roaming(mac_ctx, session_id);
pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = false;
}
/**
* csr_reinit_preauth_cmd() - Cleanup the preauth command
* @mac_ctx: Global MAC context
* @command: Command to be cleaned up
*
* Return: None
*/
static void csr_reinit_preauth_cmd(tpAniSirGlobal mac_ctx, tSmeCmd *command)
{
command->u.roamCmd.pLastRoamBss = NULL;
command->u.roamCmd.pRoamBssEntry = NULL;
qdf_mem_set(&command->u.roamCmd, sizeof(tRoamCmd), 0);
}
/**
* csr_release_command_preauth() - Release the preauth command
* @mac_ctx: Global MAC context
* @command: Command to be released
*
* Return: None
*/
void csr_release_command_preauth(tpAniSirGlobal mac_ctx, tSmeCmd *command)
{
csr_reinit_preauth_cmd(mac_ctx, command);
csr_release_command(mac_ctx, command);
}
/**
* csr_roam_enqueue_preauth() - Put the preauth command in the queue
* @mac_ctx: Global MAC Context
* @session_id: SME Session ID
* @bss_desc: BSS descriptor
* @reason: roaming reason
* @immediate: High priority in the queue or not
*
* Return: Success if queued properly, false otherwise.
*/
QDF_STATUS csr_roam_enqueue_preauth(tpAniSirGlobal mac_ctx,
uint32_t session_id, tpSirBssDescription bss_desc,
eCsrRoamReason reason, bool immediate)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
tSmeCmd *command;
command = csr_get_command_buffer(mac_ctx);
if (NULL == command) {
sms_log(mac_ctx, LOGE, FL(" fail to get command buffer"));
status = QDF_STATUS_E_RESOURCES;
} else {
if (bss_desc) {
command->command = eSmeCommandRoam;
command->sessionId = (uint8_t) session_id;
command->u.roamCmd.roamReason = reason;
command->u.roamCmd.pLastRoamBss = bss_desc;
status = csr_queue_sme_command(mac_ctx, command,
immediate);
if (!QDF_IS_STATUS_SUCCESS(status)) {
sms_log(mac_ctx, LOGE,
FL("fail to queue preauth,status=%d"),
status);
csr_release_command_preauth(mac_ctx, command);
}
} else {
status = QDF_STATUS_E_RESOURCES;
}
}
return status;
}
/**
* csr_neighbor_roam_purge_preauth_failed_list() - Purge the preauth fail list
* @mac_ctx: Global MAC Context
*
* Return: None
*/
void csr_neighbor_roam_purge_preauth_failed_list(tpAniSirGlobal mac_ctx)
{
uint8_t i;
uint8_t j;
uint8_t num_mac_addr;
tpCsrNeighborRoamControlInfo neigh_roam_info = NULL;
tpCsrPreauthFailListInfo fail_list;
for (j = 0; j < CSR_ROAM_SESSION_MAX; j++) {
neigh_roam_info = &mac_ctx->roam.neighborRoamInfo[j];
fail_list = &neigh_roam_info->FTRoamInfo.preAuthFailList;
num_mac_addr = fail_list->numMACAddress;
for (i = 0; i < num_mac_addr; i++)
qdf_mem_zero(fail_list->macAddress[i],
sizeof(tSirMacAddr));
fail_list->numMACAddress = 0;
}
}
/**
* @csr_neighbor_roam_reset_preauth_control_info - Reset preauth info
* @mac_ctx: Global MAC Context
* @session_id: SME Session ID
*
* Return: None
*/
void csr_neighbor_roam_reset_preauth_control_info(tpAniSirGlobal mac_ctx,
uint8_t session_id)
{
tpCsrNeighborRoamControlInfo neigh_roam_info =
&mac_ctx->roam.neighborRoamInfo[session_id];
neigh_roam_info->is11rAssoc = false;
csr_neighbor_roam_purge_preauth_failed_list(mac_ctx);
neigh_roam_info->FTRoamInfo.preauthRspPending = false;
neigh_roam_info->FTRoamInfo.numPreAuthRetries = 0;
neigh_roam_info->FTRoamInfo.currentNeighborRptRetryNum = 0;
neigh_roam_info->FTRoamInfo.neighborRptPending = false;
neigh_roam_info->FTRoamInfo.numBssFromNeighborReport = 0;
qdf_mem_zero(neigh_roam_info->FTRoamInfo.neighboReportBssInfo,
sizeof(tCsrNeighborReportBssInfo) *
MAX_BSS_IN_NEIGHBOR_RPT);
neigh_roam_info->uOsRequestedHandoff = 0;
qdf_mem_zero(&neigh_roam_info->handoffReqInfo,
sizeof(tCsrHandoffRequest));
}
/**
* csr_neighbor_roam_preauth_rsp_handler() - handle preauth response
* @mac_ctx: The handle returned by mac_open.
* @session_id: SME session
* @lim_status: eSIR_SUCCESS/eSIR_FAILURE/eSIR_LIM_MAX_STA_REACHED_ERROR/
* eSIT_LIM_AUTH_RSP_TIMEOUT status from PE
*
* This function handle the Preauth response from PE
* Every preauth is allowed max 3 tries if it fails. If a bssid failed
* for more than MAX_TRIES, we will remove it from the list and try
* with the next node in the roamable AP list and add the BSSID to
* pre-auth failed list. If no more entries present in roamable AP list,
* transition to REPORT_SCAN state.
*
* Return: QDF_STATUS_SUCCESS on success (i.e. pre-auth processed),
* QDF_STATUS_E_FAILURE otherwise
*/
QDF_STATUS csr_neighbor_roam_preauth_rsp_handler(tpAniSirGlobal mac_ctx,
uint8_t session_id,
tSirRetStatus lim_status)
{
tpCsrNeighborRoamControlInfo neighbor_roam_info =
&mac_ctx->roam.neighborRoamInfo[session_id];
QDF_STATUS status = QDF_STATUS_SUCCESS;
QDF_STATUS preauth_processed = QDF_STATUS_SUCCESS;
tpCsrNeighborRoamBSSInfo preauth_rsp_node = NULL;
if (false == neighbor_roam_info->FTRoamInfo.preauthRspPending) {
/*
* This can happen when we disconnect immediately
* after sending a pre-auth request. During processing
* of the disconnect command, we would have reset
* preauthRspPending and transitioned to INIT state.
*/
sms_log(mac_ctx, LOGW,
FL("Unexpected pre-auth response in state %d"),
neighbor_roam_info->neighborRoamState);
preauth_processed = QDF_STATUS_E_FAILURE;
goto DEQ_PREAUTH;
}
/* We can receive it in these 2 states. */
if ((neighbor_roam_info->neighborRoamState !=
eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING)) {
sms_log(mac_ctx, LOGW,
FL("Preauth response received in state %s"),
mac_trace_get_neighbour_roam_state
(neighbor_roam_info->neighborRoamState));
preauth_processed = QDF_STATUS_E_FAILURE;
goto DEQ_PREAUTH;
}
neighbor_roam_info->FTRoamInfo.preauthRspPending = false;
if (eSIR_SUCCESS == lim_status)
preauth_rsp_node =
csr_neighbor_roam_next_roamable_ap(
mac_ctx, &neighbor_roam_info->roamableAPList,
NULL);
if ((eSIR_SUCCESS == lim_status) && (NULL != preauth_rsp_node)) {
sms_log(mac_ctx, LOG1,
FL("Preauth completed successfully after %d tries"),
neighbor_roam_info->FTRoamInfo.numPreAuthRetries);
sms_log(mac_ctx, LOG1,
FL("After Pre-Auth: BSSID " MAC_ADDRESS_STR ", Ch:%d"),
MAC_ADDR_ARRAY(
preauth_rsp_node->pBssDescription->bssId),
(int)preauth_rsp_node->pBssDescription->channelId);
csr_neighbor_roam_send_lfr_metric_event(mac_ctx, session_id,
preauth_rsp_node->pBssDescription->bssId,
eCSR_ROAM_PREAUTH_STATUS_SUCCESS);
/*
* Preauth completed successfully. Insert the preauthenticated
* node to tail of preAuthDoneList.
*/
csr_neighbor_roam_remove_roamable_ap_list_entry(mac_ctx,
&neighbor_roam_info->roamableAPList,
preauth_rsp_node);
csr_ll_insert_tail(
&neighbor_roam_info->FTRoamInfo.preAuthDoneList,
&preauth_rsp_node->List, LL_ACCESS_LOCK);
/* Pre-auth successful. Transition to PREAUTH Done state */
csr_neighbor_middle_of_roaming(mac_ctx, session_id);
neighbor_roam_info->FTRoamInfo.numPreAuthRetries = 0;
/*
* The caller of this function would start a timer and by
* the time it expires, supplicant should have provided
* the updated FTIEs to SME. So, when it expires, handoff
* will be triggered then.
*/
} else {
tpCsrNeighborRoamBSSInfo neighbor_bss_node = NULL;
tListElem *entry;
bool is_dis_pending = false;
sms_log(mac_ctx, LOGE,
FL("Preauth failed retry number %d, status = 0x%x"),
neighbor_roam_info->FTRoamInfo.numPreAuthRetries,
lim_status);
/*
* Preauth failed. Add the bssId to the preAuth failed list
* of MAC Address. Also remove the AP from roamable AP list.
*/
if ((neighbor_roam_info->FTRoamInfo.numPreAuthRetries >=
CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES) ||
(eSIR_LIM_MAX_STA_REACHED_ERROR == lim_status)) {
/*
* We are going to remove the node as it fails for
* more than MAX tries. Reset this count to 0
*/
neighbor_roam_info->FTRoamInfo.numPreAuthRetries = 0;
/*
* The one in the head of the list should be one with
* which we issued pre-auth and failed
*/
entry = csr_ll_remove_head(
&neighbor_roam_info->roamableAPList,
LL_ACCESS_LOCK);
if (!entry) {
sms_log(mac_ctx, LOGE,
FL("Preauth list is empty"));
goto NEXT_PREAUTH;
}
neighbor_bss_node = GET_BASE_ADDR(entry,
tCsrNeighborRoamBSSInfo,
List);
/*
* Add the BSSID to pre-auth fail list if
* it is not requested by HDD
*/
if (!neighbor_roam_info->uOsRequestedHandoff)
status =
csr_neighbor_roam_add_preauth_fail(
mac_ctx, session_id,
neighbor_bss_node->
pBssDescription->bssId);
csr_neighbor_roam_send_lfr_metric_event(mac_ctx,
session_id,
neighbor_bss_node->pBssDescription->bssId,
eCSR_ROAM_PREAUTH_STATUS_FAILURE);
/* Now we can free this node */
csr_neighbor_roam_free_neighbor_roam_bss_node(
mac_ctx, neighbor_bss_node);
}
NEXT_PREAUTH:
is_dis_pending = is_disconnect_pending(mac_ctx, session_id);
if (is_dis_pending) {
sms_log(mac_ctx, LOGE,
FL("Disconnect in progress, Abort preauth"));
goto ABORT_PREAUTH;
}
/* Issue preauth request for the same/next entry */
if (QDF_STATUS_SUCCESS == csr_neighbor_roam_issue_preauth_req(
mac_ctx, session_id))
goto DEQ_PREAUTH;
ABORT_PREAUTH:
if (csr_roam_is_roam_offload_scan_enabled(mac_ctx)) {
if (neighbor_roam_info->uOsRequestedHandoff) {
neighbor_roam_info->uOsRequestedHandoff = 0;
csr_roam_offload_scan(mac_ctx, 0,
ROAM_SCAN_OFFLOAD_START,
REASON_PREAUTH_FAILED_FOR_ALL);
} else {
csr_roam_offload_scan(mac_ctx, 0,
ROAM_SCAN_OFFLOAD_RESTART,
REASON_PREAUTH_FAILED_FOR_ALL);
}
csr_neighbor_middle_of_roaming(mac_ctx, session_id);
}
}
DEQ_PREAUTH:
csr_dequeue_roam_command(mac_ctx, eCsrPerformPreauth);
return preauth_processed;
}
/**
* csr_neighbor_roam_add_preauth_fail() - add bssid to preauth failed list
* @mac_ctx: The handle returned by mac_open.
* @bssid: BSSID to be added to the preauth fail list
*
* This function adds the given BSSID to the Preauth fail list
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
*/
static QDF_STATUS csr_neighbor_roam_add_preauth_fail(tpAniSirGlobal mac_ctx,
uint8_t session_id, tSirMacAddr bssid)
{
uint8_t i = 0;
tpCsrNeighborRoamControlInfo neighbor_roam_info =
&mac_ctx->roam.neighborRoamInfo[session_id];
uint8_t num_mac_addr = neighbor_roam_info->FTRoamInfo.preAuthFailList.
numMACAddress;
sms_log(mac_ctx, LOGE,
FL(" Added BSSID " MAC_ADDRESS_STR " to Preauth failed list"),
MAC_ADDR_ARRAY(bssid));
for (i = 0;
i < neighbor_roam_info->FTRoamInfo.preAuthFailList.numMACAddress;
i++) {
if (!qdf_mem_cmp(
neighbor_roam_info->FTRoamInfo.preAuthFailList.macAddress[i],
bssid, sizeof(tSirMacAddr))) {
sms_log(mac_ctx, LOGW,
FL("BSSID "MAC_ADDRESS_STR" already fail list"),
MAC_ADDR_ARRAY(bssid));
return QDF_STATUS_SUCCESS;
}
}
if ((num_mac_addr + 1) > MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS) {
sms_log(mac_ctx, LOGE,
FL("Cannot add, preauth fail list is full."));
return QDF_STATUS_E_FAILURE;
}
qdf_mem_copy(neighbor_roam_info->FTRoamInfo.preAuthFailList.
macAddress[num_mac_addr], bssid, sizeof(tSirMacAddr));
neighbor_roam_info->FTRoamInfo.preAuthFailList.numMACAddress++;
return QDF_STATUS_SUCCESS;
}
/**
* csr_neighbor_roam_is_preauth_candidate()
*
* @mac_ctx: Pointer to Global MAC structure
* @bssId : BSSID of the candidate
*
* This function checks whether the given MAC address is already present
* in the preauth fail list and returns true/false accordingly
*
* Return: true if preauth candidate, false otherwise
*/
bool csr_neighbor_roam_is_preauth_candidate(tpAniSirGlobal pMac,
uint8_t sessionId, tSirMacAddr bssId)
{
uint8_t i = 0;
tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
&pMac->roam.neighborRoamInfo[sessionId];
if (csr_roam_is_roam_offload_scan_enabled(pMac))
return true;
if (0 == pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
return true;
for (i = 0;
i < pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress;
i++) {
if (!qdf_mem_cmp(pNeighborRoamInfo->FTRoamInfo.
preAuthFailList.macAddress[i], bssId,
sizeof(tSirMacAddr))) {
sms_log(pMac, LOGE,
FL("BSSID exists in fail list" MAC_ADDRESS_STR),
MAC_ADDR_ARRAY(bssId));
return false;
}
}
return true;
}
/**
* csr_roam_issue_ft_preauth_req() - Initiate Preauthentication request
* @hal: Global Handle
* @session_id: SME Session ID
* @bss_desc: BSS descriptor
*
* Return: Success or Failure
*/
QDF_STATUS csr_roam_issue_ft_preauth_req(tHalHandle hal, uint32_t session_id,
tpSirBssDescription bss_desc)
{
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
tpSirFTPreAuthReq preauth_req;
uint16_t auth_req_len = 0;
tCsrRoamSession *csr_session = CSR_GET_SESSION(mac_ctx, session_id);
if (NULL == csr_session) {
sms_log(mac_ctx, LOGE,
FL("Session does not exist for session id(%d)"),
session_id);
return QDF_STATUS_E_FAILURE;
}
auth_req_len = sizeof(tSirFTPreAuthReq);
preauth_req = (tpSirFTPreAuthReq) qdf_mem_malloc(auth_req_len);
if (NULL == preauth_req) {
sms_log(mac_ctx, LOGE,
FL("Memory allocation for FT Preauth request failed"));
return QDF_STATUS_E_NOMEM;
}
/* Save the SME Session ID. We need it while processing preauth resp */
csr_session->ftSmeContext.smeSessionId = session_id;
qdf_mem_zero(preauth_req, auth_req_len);
preauth_req->pbssDescription =
(tpSirBssDescription) qdf_mem_malloc(sizeof(bss_desc->length)
+ bss_desc->length);
if (NULL == preauth_req->pbssDescription) {
sms_log(mac_ctx, LOGE,
FL("Memory allocation for FT Preauth request failed"));
return QDF_STATUS_E_NOMEM;
}
preauth_req->messageType = eWNI_SME_FT_PRE_AUTH_REQ;
preauth_req->preAuthchannelNum = bss_desc->channelId;
qdf_mem_copy((void *)&preauth_req->currbssId,
(void *)csr_session->connectedProfile.bssid.bytes,
sizeof(tSirMacAddr));
qdf_mem_copy((void *)&preauth_req->preAuthbssId,
(void *)bss_desc->bssId, sizeof(tSirMacAddr));
qdf_mem_copy((void *)&preauth_req->self_mac_addr,
(void *)&csr_session->selfMacAddr.bytes, sizeof(tSirMacAddr));
if (csr_roam_is11r_assoc(mac_ctx, session_id) &&
(mac_ctx->roam.roamSession[session_id].connectedProfile.AuthType !=
eCSR_AUTH_TYPE_OPEN_SYSTEM)) {
preauth_req->ft_ies_length =
(uint16_t) csr_session->ftSmeContext.auth_ft_ies_length;
qdf_mem_copy(preauth_req->ft_ies,
csr_session->ftSmeContext.auth_ft_ies,
csr_session->ftSmeContext.auth_ft_ies_length);
} else {
preauth_req->ft_ies_length = 0;
}
qdf_mem_copy(preauth_req->pbssDescription, bss_desc,
sizeof(bss_desc->length) + bss_desc->length);
preauth_req->length = auth_req_len;
return cds_send_mb_message_to_mac(preauth_req);
}
/**
* csr_roam_ft_pre_auth_rsp_processor() - Handle the preauth response
* @hal: Global Handle
* preauth_rsp: Received preauthentication response
*
* Return: None
*/
void csr_roam_ft_pre_auth_rsp_processor(tHalHandle hal,
tpSirFTPreAuthRsp preauth_rsp)
{
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
QDF_STATUS status = QDF_STATUS_SUCCESS;
tCsrRoamInfo roam_info;
eCsrAuthType conn_Auth_type;
uint32_t session_id = preauth_rsp->smeSessionId;
tCsrRoamSession *csr_session = CSR_GET_SESSION(mac_ctx, session_id);
if (NULL == csr_session) {
sms_log(mac_ctx, LOGE, FL("CSR session is NULL"));
return;
}
status = csr_neighbor_roam_preauth_rsp_handler(mac_ctx,
preauth_rsp->smeSessionId, preauth_rsp->status);
if (status != QDF_STATUS_SUCCESS) {
sms_log(mac_ctx, LOGE,
FL("Preauth was not processed: %d SessionID: %d"),
status, session_id);
return;
}
if (QDF_STATUS_SUCCESS != (QDF_STATUS) preauth_rsp->status)
return;
csr_session->ftSmeContext.FTState = eFT_AUTH_COMPLETE;
csr_session->ftSmeContext.psavedFTPreAuthRsp = preauth_rsp;
/* No need to notify qos module if this is a non 11r & ESE roam */
if (csr_roam_is11r_assoc(mac_ctx, preauth_rsp->smeSessionId)
#ifdef FEATURE_WLAN_ESE
|| csr_roam_is_ese_assoc(mac_ctx, preauth_rsp->smeSessionId)
#endif
) {
sme_qos_csr_event_ind(mac_ctx,
csr_session->ftSmeContext.smeSessionId,
SME_QOS_CSR_PREAUTH_SUCCESS_IND, NULL);
}
status =
qdf_mc_timer_start(
&csr_session->ftSmeContext.preAuthReassocIntvlTimer,
60);
if (QDF_STATUS_SUCCESS != status) {
sms_log(mac_ctx, LOGE,
FL("PreauthReassocInterval timer failed status %d"),
status);
return;
}
qdf_mem_copy((void *)&csr_session->ftSmeContext.preAuthbssId,
(void *)preauth_rsp->preAuthbssId,
sizeof(struct qdf_mac_addr));
if (csr_roam_is11r_assoc(mac_ctx, preauth_rsp->smeSessionId))
csr_roam_call_callback(mac_ctx, preauth_rsp->smeSessionId,
NULL, 0, eCSR_ROAM_FT_RESPONSE, eCSR_ROAM_RESULT_NONE);
#ifdef FEATURE_WLAN_ESE
if (csr_roam_is_ese_assoc(mac_ctx, preauth_rsp->smeSessionId)) {
csr_roam_read_tsf(mac_ctx, (uint8_t *) roam_info.timestamp,
preauth_rsp->smeSessionId);
qdf_mem_copy((void *)&roam_info.bssid,
(void *)preauth_rsp->preAuthbssId,
sizeof(struct qdf_mac_addr));
csr_roam_call_callback(mac_ctx, preauth_rsp->smeSessionId,
&roam_info, 0, eCSR_ROAM_CCKM_PREAUTH_NOTIFY,
0);
}
#endif
if (csr_roam_is_fast_roam_enabled(mac_ctx, preauth_rsp->smeSessionId)) {
/* Save the bssid from the received response */
qdf_mem_copy((void *)&roam_info.bssid,
(void *)preauth_rsp->preAuthbssId,
sizeof(struct qdf_mac_addr));
csr_roam_call_callback(mac_ctx, preauth_rsp->smeSessionId,
&roam_info, 0, eCSR_ROAM_PMK_NOTIFY, 0);
}
/* If its an Open Auth, FT IEs are not provided by supplicant */
/* Hence populate them here */
conn_Auth_type =
mac_ctx->roam.roamSession[session_id].connectedProfile.AuthType;
csr_session->ftSmeContext.addMDIE = false;
/* Done with it, init it. */
csr_session->ftSmeContext.psavedFTPreAuthRsp = NULL;
if (csr_roam_is11r_assoc(mac_ctx, preauth_rsp->smeSessionId) &&
(conn_Auth_type == eCSR_AUTH_TYPE_OPEN_SYSTEM)) {
uint16_t ft_ies_length;
ft_ies_length = preauth_rsp->ric_ies_length;
if ((csr_session->ftSmeContext.reassoc_ft_ies) &&
(csr_session->ftSmeContext.reassoc_ft_ies_length)) {
qdf_mem_free(csr_session->ftSmeContext.reassoc_ft_ies);
csr_session->ftSmeContext.reassoc_ft_ies_length = 0;
csr_session->ftSmeContext.reassoc_ft_ies = NULL;
}
if (!ft_ies_length)
return;
csr_session->ftSmeContext.reassoc_ft_ies =
qdf_mem_malloc(ft_ies_length);
if (NULL == csr_session->ftSmeContext.reassoc_ft_ies) {
sms_log(mac_ctx, LOGE,
FL("Memory allocation failed for ft_ies"));
return;
} else {
/* Copy the RIC IEs to reassoc IEs */
qdf_mem_copy(((uint8_t *) csr_session->ftSmeContext.
reassoc_ft_ies),
(uint8_t *) preauth_rsp->ric_ies,
preauth_rsp->ric_ies_length);
csr_session->ftSmeContext.reassoc_ft_ies_length =
ft_ies_length;
csr_session->ftSmeContext.addMDIE = true;
}
}
}
/**
* csr_neighbor_roam_issue_preauth_req() - Send preauth request to first AP
* @mac_ctx: The handle returned by mac_open.
* @session_id: Session information
*
* This function issues preauth request to PE with the 1st AP entry in the
* roamable AP list
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
*/
QDF_STATUS csr_neighbor_roam_issue_preauth_req(tpAniSirGlobal mac_ctx,
uint8_t session_id)
{
tpCsrNeighborRoamControlInfo neighbor_roam_info =
&mac_ctx->roam.neighborRoamInfo[session_id];
QDF_STATUS status = QDF_STATUS_SUCCESS;
tpCsrNeighborRoamBSSInfo neighbor_bss_node;
if (false != neighbor_roam_info->FTRoamInfo.preauthRspPending) {
/* This must not be true here */
QDF_ASSERT(neighbor_roam_info->FTRoamInfo.preauthRspPending ==
false);
return QDF_STATUS_E_FAILURE;
}
/*
* Issue Preauth request to PE here.
* Need to issue the preauth request with the BSSID that is in the
* head of the roamable AP list. Parameters that should be passed are
* BSSID, Channel number and the neighborScanPeriod(probably). If
* roamableAPList gets empty, should transition to REPORT_SCAN state
*/
neighbor_bss_node = csr_neighbor_roam_next_roamable_ap(mac_ctx,
&neighbor_roam_info->roamableAPList, NULL);
if (NULL == neighbor_bss_node) {
sms_log(mac_ctx, LOGW, FL("Roamable AP list is empty.. "));
return QDF_STATUS_E_FAILURE;
} else {
csr_neighbor_roam_send_lfr_metric_event(mac_ctx, session_id,
neighbor_bss_node->pBssDescription->bssId,
eCSR_ROAM_PREAUTH_INIT_NOTIFY);
status = csr_roam_enqueue_preauth(mac_ctx, session_id,
neighbor_bss_node->pBssDescription,
eCsrPerformPreauth, true);
sms_log(mac_ctx, LOG1,
FL("Before Pre-Auth: BSSID " MAC_ADDRESS_STR ", Ch:%d"),
MAC_ADDR_ARRAY(
neighbor_bss_node->pBssDescription->bssId),
(int)neighbor_bss_node->pBssDescription->channelId);
if (QDF_STATUS_SUCCESS != status) {
sms_log(mac_ctx, LOGE,
FL("Return failed preauth request status %d"),
status);
return status;
}
}
neighbor_roam_info->FTRoamInfo.preauthRspPending = true;
/* Increment the preauth retry count */
neighbor_roam_info->FTRoamInfo.numPreAuthRetries++;
/* Transition the state to preauthenticating */
csr_neighbor_middle_of_roaming(mac_ctx, session_id);
return status;
}