diff options
| author | Varun Reddy Yeturu <varunreddy.yeturu@codeaurora.org> | 2016-02-19 11:32:52 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-04-17 18:10:20 -0700 |
| commit | 883c4f20f9f3073e49d1a68c1b4d2e91c55d3d3c (patch) | |
| tree | 4eeddaf85aa467b18a6941a8c36d90f25a50156b | |
| parent | d318632e760dfe349ed164af85c04e70a8934ec3 (diff) | |
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
| -rwxr-xr-x | Kbuild | 1 | ||||
| -rw-r--r-- | core/sme/inc/csr_neighbor_roam.h | 22 | ||||
| -rw-r--r-- | core/sme/src/csr/csr_api_roam.c | 258 | ||||
| -rw-r--r-- | core/sme/src/csr/csr_inside_api.h | 1 | ||||
| -rw-r--r-- | core/sme/src/csr/csr_neighbor_roam.c | 501 | ||||
| -rw-r--r-- | core/sme/src/csr/csr_roam_preauth.c | 754 |
6 files changed, 779 insertions, 758 deletions
@@ -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 \ diff --git a/core/sme/inc/csr_neighbor_roam.h b/core/sme/inc/csr_neighbor_roam.h index 22872036e9cb..00fc97725f9a 100644 --- a/core/sme/inc/csr_neighbor_roam.h +++ b/core/sme/inc/csr_neighbor_roam.h @@ -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 */ diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 81ea9fadad07..800a28d71f84 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -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, diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index 37b7c05a696a..1e7ae4cdbc99 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -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); diff --git a/core/sme/src/csr/csr_neighbor_roam.c b/core/sme/src/csr/csr_neighbor_roam.c index 92424ea10838..76781a8bb692 100644 --- a/core/sme/src/csr/csr_neighbor_roam.c +++ b/core/sme/src/csr/csr_neighbor_roam.c @@ -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() @@ -2589,36 +2172,6 @@ QDF_STATUS csr_neighbor_roam_indicate_connect( /* --------------------------------------------------------------------------- - \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 \brief This function initializes 11r related neighbor roam data structures @@ -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 diff --git a/core/sme/src/csr/csr_roam_preauth.c b/core/sme/src/csr/csr_roam_preauth.c new file mode 100644 index 000000000000..3a5bc43628d3 --- /dev/null +++ b/core/sme/src/csr/csr_roam_preauth.c @@ -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; +} + |
