summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVarun Reddy Yeturu <varunreddy.yeturu@codeaurora.org>2016-02-10 14:32:50 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-04-17 18:09:42 -0700
commitdbbb9919e9ae7d1043ef8205b28f55e37a3a7a54 (patch)
tree4af01b46a8a7c01041c895ac39d867badad9b3ea
parent32de0e4137f3c1ab2df4391c19c6dfdba89c0aac (diff)
qcacld-3.0: Isolate the pre-authentication code into a new file
Move all the pre-authentication related code in LIM to a separate file so that it is feature specific and easy to maintain across different projects CRs-Fixed: 978905 Change-Id: I3ca443139b974b25be8121fd6df040d858693708
-rwxr-xr-xKbuild1
-rw-r--r--core/mac/src/pe/lim/lim_ft.c724
-rw-r--r--core/mac/src/pe/lim/lim_ft_preauth.c782
3 files changed, 785 insertions, 722 deletions
diff --git a/Kbuild b/Kbuild
index d4ac68b34633..7b13789bb13e 100755
--- a/Kbuild
+++ b/Kbuild
@@ -403,6 +403,7 @@ MAC_LIM_OBJS := $(MAC_SRC_DIR)/pe/lim/lim_aid_mgmt.o \
$(MAC_SRC_DIR)/pe/lim/lim_assoc_utils.o \
$(MAC_SRC_DIR)/pe/lim/lim_debug.o \
$(MAC_SRC_DIR)/pe/lim/lim_ft.o \
+ $(MAC_SRC_DIR)/pe/lim/lim_ft_preauth.o \
$(MAC_SRC_DIR)/pe/lim/lim_ibss_peer_mgmt.o \
$(MAC_SRC_DIR)/pe/lim/lim_link_monitoring_algo.o \
$(MAC_SRC_DIR)/pe/lim/lim_p2p.o \
diff --git a/core/mac/src/pe/lim/lim_ft.c b/core/mac/src/pe/lim/lim_ft.c
index 82f2498359e4..ad918d237540 100644
--- a/core/mac/src/pe/lim/lim_ft.c
+++ b/core/mac/src/pe/lim/lim_ft.c
@@ -64,75 +64,6 @@ void lim_ft_open(tpAniSirGlobal pMac, tpPESession psessionEntry)
0);
}
-/*--------------------------------------------------------------------------
- Cleanup FT variables.
- ------------------------------------------------------------------------*/
-void lim_ft_cleanup_pre_auth_info(tpAniSirGlobal pMac, tpPESession psessionEntry)
-{
- tpPESession pReAssocSessionEntry = NULL;
- uint8_t sessionId = 0;
-
- if (!psessionEntry) {
- lim_log(pMac, LOGE, FL("psessionEntry is NULL"));
- return;
- }
-
- /* Nothing to be done if the session is not in STA mode */
- if (!LIM_IS_STA_ROLE(psessionEntry)) {
- lim_log(pMac, LOGE, FL("psessionEntry is not in STA mode"));
- return;
- }
-
- if (psessionEntry->ftPEContext.pFTPreAuthReq) {
- pReAssocSessionEntry =
- pe_find_session_by_bssid(pMac,
- psessionEntry->ftPEContext.
- pFTPreAuthReq->preAuthbssId,
- &sessionId);
-
- lim_log(pMac, LOG1, FL("Freeing pFTPreAuthReq= %p"),
- psessionEntry->ftPEContext.pFTPreAuthReq);
- if (psessionEntry->ftPEContext.pFTPreAuthReq->
- pbssDescription) {
- qdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq->
- pbssDescription);
- psessionEntry->ftPEContext.pFTPreAuthReq->
- pbssDescription = NULL;
- }
- qdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq);
- psessionEntry->ftPEContext.pFTPreAuthReq = NULL;
- }
-
- if (psessionEntry->ftPEContext.pAddBssReq) {
- qdf_mem_free(psessionEntry->ftPEContext.pAddBssReq);
- psessionEntry->ftPEContext.pAddBssReq = NULL;
- }
-
- if (psessionEntry->ftPEContext.pAddStaReq) {
- qdf_mem_free(psessionEntry->ftPEContext.pAddStaReq);
- psessionEntry->ftPEContext.pAddStaReq = NULL;
- }
-
- /* The session is being deleted, cleanup the contents */
- qdf_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext), 0);
-
- /* Delete the session created while handling pre-auth response */
- if (pReAssocSessionEntry) {
- /* If we have successful pre-auth response, then we would have
- * created a session on which reassoc request will be sent
- */
- if (pReAssocSessionEntry->valid &&
- pReAssocSessionEntry->limSmeState ==
- eLIM_SME_WT_REASSOC_STATE) {
- QDF_TRACE(QDF_MODULE_ID_PE,
- QDF_TRACE_LEVEL_DEBUG,
- FL("Deleting Preauth session(%d)"),
- pReAssocSessionEntry->peSessionId);
- pe_delete_session(pMac, pReAssocSessionEntry);
- }
- }
-}
-
void lim_ft_cleanup_all_ft_sessions(tpAniSirGlobal pMac)
{
/* Wrapper function to cleanup all FT sessions */
@@ -188,186 +119,6 @@ void lim_ft_cleanup(tpAniSirGlobal pMac, tpPESession psessionEntry)
qdf_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext), 0);
}
-/*
- * lim_process_ft_pre_auth_req() - process ft pre auth req
- *
- * @mac_ctx: global mac ctx
- * @msg: pointer to message
- *
- * In this function, we process the FT Pre Auth Req:
- * We receive Pre-Auth, suspend link, register a call back. In the call back,
- * we will need to accept frames from the new bssid. Send out the auth req to
- * new AP. Start timer and when the timer is done or if we receive the Auth
- * response. We change channel. Resume link
- *
- * Return: value to indicate if buffer was consumed
- */
-int lim_process_ft_pre_auth_req(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
-{
- int buf_consumed = false;
- tpPESession session;
- uint8_t session_id;
- tpSirFTPreAuthReq ft_pre_auth_req = (tSirFTPreAuthReq *) msg->bodyptr;
-
- if (NULL == ft_pre_auth_req) {
- lim_log(mac_ctx, LOGE, FL("tSirFTPreAuthReq is NULL"));
- return buf_consumed;
- }
-
- /* Get the current session entry */
- session = pe_find_session_by_bssid(mac_ctx,
- ft_pre_auth_req->currbssId,
- &session_id);
- if (session == NULL) {
- lim_log(mac_ctx, LOGE,
- FL("Unable to find session for the bssid"
- MAC_ADDRESS_STR),
- MAC_ADDR_ARRAY(ft_pre_auth_req->currbssId));
- /* Post the FT Pre Auth Response to SME */
- lim_post_ft_pre_auth_rsp(mac_ctx, eSIR_FAILURE, NULL, 0,
- session);
- /*
- * return FALSE, since the Pre-Auth Req will be freed in
- * limPostFTPreAuthRsp on failure
- */
- return buf_consumed;
- }
-
- /* Nothing to be done if the session is not in STA mode */
- if (!LIM_IS_STA_ROLE(session)) {
- lim_log(mac_ctx, LOGE, FL("session is not in STA mode"));
- buf_consumed = true;
- return buf_consumed;
- }
-
- /* Can set it only after sending auth */
- session->ftPEContext.ftPreAuthStatus = eSIR_FAILURE;
- session->ftPEContext.ftPreAuthSession = true;
-
- /* Indicate that this is the session on which preauth is being done */
- if (session->ftPEContext.pFTPreAuthReq) {
- if (session->ftPEContext.pFTPreAuthReq->pbssDescription) {
- qdf_mem_free(
- session->ftPEContext.pFTPreAuthReq->pbssDescription);
- session->ftPEContext.pFTPreAuthReq->pbssDescription =
- NULL;
- }
- qdf_mem_free(session->ftPEContext.pFTPreAuthReq);
- session->ftPEContext.pFTPreAuthReq = NULL;
- }
-
- /* We need information from the Pre-Auth Req. Lets save that */
- session->ftPEContext.pFTPreAuthReq = ft_pre_auth_req;
-
- lim_log(mac_ctx, LOG1, FL("PRE Auth ft_ies_length=%02x%02x%02x"),
- session->ftPEContext.pFTPreAuthReq->ft_ies[0],
- session->ftPEContext.pFTPreAuthReq->ft_ies[1],
- session->ftPEContext.pFTPreAuthReq->ft_ies[2]);
-#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
- lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_PRE_AUTH_REQ_EVENT,
- session, 0, 0);
-#endif
-
- /* Dont need to suspend if APs are in same channel */
- if (session->currentOperChannel !=
- session->ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
- /* Need to suspend link only if the channels are different */
- lim_log(mac_ctx, LOG2,
- FL("Performing pre-auth on diff channel(session %p)"),
- session);
- lim_send_preauth_scan_offload(mac_ctx, session->peSessionId,
- session->ftPEContext.pFTPreAuthReq);
- } else {
- lim_log(mac_ctx, LOG2,
- FL("Performing pre-auth on same channel (session %p)"),
- session);
- /* We are in the same channel. Perform pre-auth */
- lim_perform_ft_pre_auth(mac_ctx, QDF_STATUS_SUCCESS, NULL,
- session);
- }
-
- return buf_consumed;
-}
-
-/*------------------------------------------------------------------
- * Send the Auth1
- * Receive back Auth2
- *------------------------------------------------------------------*/
-void lim_perform_ft_pre_auth(tpAniSirGlobal pMac, QDF_STATUS status,
- uint32_t *data, tpPESession psessionEntry)
-{
- tSirMacAuthFrameBody authFrame;
-
- if (NULL == psessionEntry) {
- PELOGE(lim_log(pMac, LOGE, FL("psessionEntry is NULL"));)
- return;
- }
-
- if (psessionEntry->is11Rconnection &&
- psessionEntry->ftPEContext.pFTPreAuthReq) {
- /* Only 11r assoc has FT IEs */
- if (psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies == NULL) {
- lim_log(pMac, LOGE,
- FL("FTIEs for Auth Req Seq 1 is absent"));
- goto preauth_fail;
- }
- }
-
- if (status != QDF_STATUS_SUCCESS) {
- lim_log(pMac, LOGE,
- FL(" Change channel not successful for FT pre-auth"));
- goto preauth_fail;
- }
-
- /* Nothing to be done if the session is not in STA mode */
- if (!LIM_IS_STA_ROLE(psessionEntry)) {
- lim_log(pMac, LOGE, FL("psessionEntry is not in STA mode"));
- return;
- }
- lim_log(pMac, LOG2, "Entered wait auth2 state for FT (old session %p)",
- psessionEntry);
- if (psessionEntry->is11Rconnection) {
- /* Now we are on the right channel and need to send out Auth1 and
- * receive Auth2
- */
- authFrame.authAlgoNumber = eSIR_FT_AUTH;
- } else {
- /* Will need to make isESEconnection a enum may be for further
- * improvements to this to match this algorithm number
- */
- authFrame.authAlgoNumber = eSIR_OPEN_SYSTEM;
- }
- authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
- authFrame.authStatusCode = 0;
-
- /* Start timer here to come back to operating channel */
- pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId =
- psessionEntry->peSessionId;
- if (TX_SUCCESS !=
- tx_timer_activate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer)) {
- lim_log(pMac, LOGE, FL("FT Auth Rsp Timer Start Failed"));
- goto preauth_fail;
- }
- MTRACE(mac_trace(pMac, TRACE_CODE_TIMER_ACTIVATE,
- psessionEntry->peSessionId, eLIM_FT_PREAUTH_RSP_TIMER));
-
- lim_log(pMac, LOG1, FL("FT Auth Rsp Timer Started"));
-#ifdef FEATURE_WLAN_DIAG_SUPPORT
- lim_diag_event_report(pMac, WLAN_PE_DIAG_ROAM_AUTH_START_EVENT,
- pMac->lim.pSessionEntry, eSIR_SUCCESS, eSIR_SUCCESS);
-#endif
-
- lim_send_auth_mgmt_frame(pMac, &authFrame,
- psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId,
- LIM_NO_WEP_IN_FC, psessionEntry, false);
-
- return;
-
-preauth_fail:
- lim_handle_ft_pre_auth_rsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry);
- return;
-}
-
/*------------------------------------------------------------------
*
* Create the new Add Bss Req to the new AP.
@@ -944,272 +695,6 @@ void lim_fill_ft_session(tpAniSirGlobal pMac,
/*------------------------------------------------------------------
*
- * Setup the session and the add bss req for the pre-auth AP.
- *
- *------------------------------------------------------------------*/
-tSirRetStatus lim_ft_setup_auth_session(tpAniSirGlobal pMac,
- tpPESession psessionEntry)
-{
- tpPESession pftSessionEntry = NULL;
- uint8_t sessionId = 0;
-
- pftSessionEntry =
- pe_find_session_by_bssid(pMac, psessionEntry->limReAssocbssId,
- &sessionId);
- if (pftSessionEntry == NULL) {
- PELOGE(lim_log(pMac, LOGE,
- FL
- ("Unable to find session for the following bssid"));
- )
- lim_print_mac_addr(pMac, psessionEntry->limReAssocbssId, LOGE);
- return eSIR_FAILURE;
- }
-
- /* Nothing to be done if the session is not in STA mode */
- if (!LIM_IS_STA_ROLE(psessionEntry)) {
- lim_log(pMac, LOGE, FL("psessionEntry is not in STA mode"));
- return eSIR_FAILURE;
- }
-
- if (psessionEntry->ftPEContext.pFTPreAuthReq &&
- psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) {
- lim_fill_ft_session(pMac,
- psessionEntry->ftPEContext.pFTPreAuthReq->
- pbssDescription, pftSessionEntry,
- psessionEntry);
-
- lim_ft_prepare_add_bss_req(pMac, false, pftSessionEntry,
- psessionEntry->ftPEContext.pFTPreAuthReq->
- pbssDescription);
- }
-
- return eSIR_SUCCESS;
-}
-
-/*------------------------------------------------------------------
- * Resume Link Call Back
- *------------------------------------------------------------------*/
-void lim_ft_process_pre_auth_result(tpAniSirGlobal pMac, QDF_STATUS status,
- tpPESession psessionEntry)
-{
- if (NULL == psessionEntry ||
- NULL == psessionEntry->ftPEContext.pFTPreAuthReq)
- return;
-
- /* Nothing to be done if the session is not in STA mode */
- if (!LIM_IS_STA_ROLE(psessionEntry)) {
- lim_log(pMac, LOGE, FL("psessionEntry is not in STA mode"));
- return;
- }
-
- if (psessionEntry->ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) {
- psessionEntry->ftPEContext.ftPreAuthStatus =
- lim_ft_setup_auth_session(pMac, psessionEntry);
- }
- /* Post the FT Pre Auth Response to SME */
- lim_post_ft_pre_auth_rsp(pMac, psessionEntry->ftPEContext.ftPreAuthStatus,
- psessionEntry->ftPEContext.saved_auth_rsp,
- psessionEntry->ftPEContext.saved_auth_rsp_length,
- psessionEntry);
-}
-
-/*
- * lim_post_ft_pre_auth_rsp() - post ft pre auth response to SME.
- *
- * @mac_ctx: global mac ctx
- * @status: status code to post in auth rsp
- * @auth_rsp: pointer to auth rsp FT ie
- * @auth_rsp_length: len of the IE field
- * @session: pe session
- *
- * post pre auth response to SME.
- *
- * Return: void
- */
-void lim_post_ft_pre_auth_rsp(tpAniSirGlobal mac_ctx,
- tSirRetStatus status,
- uint8_t *auth_rsp,
- uint16_t auth_rsp_length,
- tpPESession session)
-{
- tpSirFTPreAuthRsp ft_pre_auth_rsp;
- tSirMsgQ mmh_msg;
- uint16_t rsp_len = sizeof(tSirFTPreAuthRsp);
-
- ft_pre_auth_rsp = (tpSirFTPreAuthRsp) qdf_mem_malloc(rsp_len);
- if (NULL == ft_pre_auth_rsp) {
- lim_log(mac_ctx, LOGE, "Failed to allocate memory");
- QDF_ASSERT(ft_pre_auth_rsp != NULL);
- return;
- }
- qdf_mem_zero(ft_pre_auth_rsp, rsp_len);
-
- lim_log(mac_ctx, LOG1, FL("Auth Rsp = %p"), ft_pre_auth_rsp);
- if (session) {
- /* Nothing to be done if the session is not in STA mode */
- if (!LIM_IS_STA_ROLE(session)) {
- lim_log(mac_ctx, LOGE,
- FL("session is not in STA mode"));
- qdf_mem_free(ft_pre_auth_rsp);
- return;
- }
- ft_pre_auth_rsp->smeSessionId = session->smeSessionId;
- /* The bssid of the AP we are sending Auth1 to. */
- if (session->ftPEContext.pFTPreAuthReq)
- sir_copy_mac_addr(ft_pre_auth_rsp->preAuthbssId,
- session->ftPEContext.pFTPreAuthReq->preAuthbssId);
- }
-
- ft_pre_auth_rsp->messageType = eWNI_SME_FT_PRE_AUTH_RSP;
- ft_pre_auth_rsp->length = (uint16_t) rsp_len;
- ft_pre_auth_rsp->status = status;
-
- /* Attach the auth response now back to SME */
- ft_pre_auth_rsp->ft_ies_length = 0;
- if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE)) {
- /* Only 11r assoc has FT IEs */
- qdf_mem_copy(ft_pre_auth_rsp->ft_ies,
- auth_rsp, auth_rsp_length);
- ft_pre_auth_rsp->ft_ies_length = auth_rsp_length;
- }
-
- if (status != eSIR_SUCCESS) {
- /*
- * Ensure that on Pre-Auth failure the cached Pre-Auth Req and
- * other allocated memory is freed up before returning.
- */
- lim_log(mac_ctx, LOG1, "Pre-Auth Failed, Cleanup!");
- lim_ft_cleanup(mac_ctx, session);
- }
-
- mmh_msg.type = ft_pre_auth_rsp->messageType;
- mmh_msg.bodyptr = ft_pre_auth_rsp;
- mmh_msg.bodyval = 0;
-
- lim_log(mac_ctx, LOG1, FL("Posted Auth Rsp to SME with status of 0x%x"),
- status);
-#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
- if (status == eSIR_SUCCESS)
- lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_PREAUTH_DONE,
- session, status, 0);
-#endif
- lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg, ePROT);
-}
-
-/*------------------------------------------------------------------
- *
- * Send the FT Pre Auth Response to SME whenever we have a status
- * ready to be sent to SME
- *
- * SME will be the one to send it up to the supplicant to receive
- * FTIEs which will be required for Reassoc Req.
- *
- *------------------------------------------------------------------*/
-void lim_handle_ft_pre_auth_rsp(tpAniSirGlobal pMac, tSirRetStatus status,
- uint8_t *auth_rsp, uint16_t auth_rsp_length,
- tpPESession psessionEntry)
-{
- tpPESession pftSessionEntry = NULL;
- uint8_t sessionId = 0;
- tpSirBssDescription pbssDescription = NULL;
-#ifdef FEATURE_WLAN_DIAG_SUPPORT
- lim_diag_event_report(pMac, WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT,
- psessionEntry, (uint16_t) status, 0);
-#endif
-
- /* Nothing to be done if the session is not in STA mode */
- if (!LIM_IS_STA_ROLE(psessionEntry)) {
- lim_log(pMac, LOGE, FL("psessionEntry is not in STA mode"));
- return;
- }
-
- /* Save the status of pre-auth */
- psessionEntry->ftPEContext.ftPreAuthStatus = status;
-
- /* Save the auth rsp, so we can send it to
- * SME once we resume link
- */
- psessionEntry->ftPEContext.saved_auth_rsp_length = 0;
- if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE)) {
- qdf_mem_copy(psessionEntry->ftPEContext.saved_auth_rsp,
- auth_rsp, auth_rsp_length);
- psessionEntry->ftPEContext.saved_auth_rsp_length =
- auth_rsp_length;
- }
-
- if (!psessionEntry->ftPEContext.pFTPreAuthReq ||
- !psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) {
- lim_log(pMac, LOGE,
- FL("pFTPreAuthReq or pbssDescription is NULL"));
- return;
- }
-
- /* Create FT session for the re-association at this point */
- if (psessionEntry->ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) {
- pbssDescription =
- psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription;
- lim_print_mac_addr(pMac, pbssDescription->bssId, LOG1);
- pftSessionEntry =
- pe_create_session(pMac, pbssDescription->bssId,
- &sessionId, pMac->lim.maxStation,
- psessionEntry->bssType);
- if (pftSessionEntry == NULL) {
- lim_log(pMac, LOGE, FL(
- "Session not created for pre-auth 11R AP"));
- status = eSIR_FAILURE;
- psessionEntry->ftPEContext.ftPreAuthStatus = status;
- goto send_rsp;
- }
- pftSessionEntry->peSessionId = sessionId;
- pftSessionEntry->smeSessionId = psessionEntry->smeSessionId;
- sir_copy_mac_addr(pftSessionEntry->selfMacAddr,
- psessionEntry->selfMacAddr);
- sir_copy_mac_addr(pftSessionEntry->limReAssocbssId,
- pbssDescription->bssId);
- pftSessionEntry->bssType = psessionEntry->bssType;
-
- if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) {
- pftSessionEntry->limSystemRole = eLIM_STA_ROLE;
- } else if (pftSessionEntry->bssType == eSIR_BTAMP_AP_MODE) {
- pftSessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE;
- } else {
- lim_log(pMac, LOGE, FL("Invalid bss type"));
- }
- pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState;
- qdf_mem_copy(&(pftSessionEntry->htConfig),
- &(psessionEntry->htConfig),
- sizeof(psessionEntry->htConfig));
- pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
-
- PELOGE(lim_log
- (pMac, LOG1, "%s:created session (%p) with id = %d",
- __func__, pftSessionEntry,
- pftSessionEntry->peSessionId);
- )
-
- /* Update the ReAssoc BSSID of the current session */
- sir_copy_mac_addr(psessionEntry->limReAssocbssId,
- pbssDescription->bssId);
- lim_print_mac_addr(pMac, psessionEntry->limReAssocbssId, LOG1);
- }
-send_rsp:
- if (psessionEntry->currentOperChannel !=
- psessionEntry->ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
- /* Need to move to the original AP channel */
- lim_process_abort_scan_ind(pMac, psessionEntry->peSessionId,
- psessionEntry->ftPEContext.pFTPreAuthReq->scan_id,
- PREAUTH_REQUESTOR_ID);
- } else {
- lim_log(pMac, LOG1,
- "Pre auth on same channel as connected AP channel %d",
- psessionEntry->ftPEContext.pFTPreAuthReq->
- preAuthchannelNum);
- lim_ft_process_pre_auth_result(pMac, status, psessionEntry);
- }
-}
-
-/*------------------------------------------------------------------
- *
* This function handles the 11R Reassoc Req from SME
*
*------------------------------------------------------------------*/
@@ -1352,81 +837,6 @@ void lim_process_mlm_ft_reassoc_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf,
return;
}
-/*
- * lim_process_ft_preauth_rsp_timeout() - process ft preauth rsp timeout
- *
- * @mac_ctx: global mac ctx
- *
- * This function is called if preauth response is not received from the AP
- * within this timeout while FT in progress
- *
- * Return: void
- */
-void lim_process_ft_preauth_rsp_timeout(tpAniSirGlobal mac_ctx)
-{
- tpPESession session;
-
- /*
- * We have failed pre auth. We need to resume link and get back on
- * home channel
- */
- lim_log(mac_ctx, LOGE, FL("FT Pre-Auth Time Out!!!!"));
- session = pe_find_session_by_session_id(mac_ctx,
- mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer.sessionId);
- if (NULL == session) {
- lim_log(mac_ctx, LOGE,
- FL("Session Does not exist for given sessionID"));
- return;
- }
-
- /* Nothing to be done if the session is not in STA mode */
- if (!LIM_IS_STA_ROLE(session)) {
- lim_log(mac_ctx, LOGE, FL("session is not in STA mode"));
- return;
- }
-
- /* Reset the flag to indicate preauth request session */
- session->ftPEContext.ftPreAuthSession = false;
-
- if (NULL == session->ftPEContext.pFTPreAuthReq) {
- lim_log(mac_ctx, LOGE,
- FL("pFTPreAuthReq is NULL. Auth Rsp might already be posted to SME and ftcleanup done! sessionId:%d"),
- mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer.sessionId);
- return;
- }
-
- /*
- * To handle the race condition where we recieve preauth rsp after
- * timer has expired.
- */
- if (true ==
- session->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) {
- lim_log(mac_ctx, LOGE,
- FL("Auth rsp already posted to SME (session %p)"),
- session);
- return;
- } else {
- /*
- * Here we are sending preauth rsp with failure state
- * and which is forwarded to SME. Now, if we receive an preauth
- * resp from AP with success it would create a FT pesession, but
- * will be dropped in SME leaving behind the pesession. Mark
- * Preauth rsp processed so that any rsp from AP is dropped in
- * lim_process_auth_frame_no_session.
- */
- lim_log(mac_ctx, LOG1,
- FL("Auth rsp not yet posted to SME (session %p)"),
- session);
- session->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed = true;
- }
-
- /*
- * Attempted at Pre-Auth and failed. If we are off channel. We need
- * to get back to home channel
- */
- lim_handle_ft_pre_auth_rsp(mac_ctx, eSIR_FAILURE, NULL, 0, session);
-}
-
/*------------------------------------------------------------------
*
* This function is called to process the update key request from SME
@@ -1599,6 +1009,7 @@ lim_ft_send_aggr_qos_rsp(tpAniSirGlobal pMac, uint8_t rspReqd,
lim_send_sme_aggr_qos_rsp(pMac, rsp, smesessionId);
return;
}
+
void lim_process_ft_aggr_qo_s_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
{
tpAggrAddTsParams pAggrQosRspMsg = NULL;
@@ -1662,6 +1073,7 @@ void lim_process_ft_aggr_qo_s_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
}
return;
}
+
tSirRetStatus lim_process_ft_aggr_qos_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
{
tSirMsgQ msg;
@@ -1843,135 +1255,3 @@ tSirRetStatus lim_process_ft_aggr_qos_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf
return eSIR_SUCCESS;
}
-/**
- * lim_send_preauth_scan_offload() - Send scan command to handle preauth.
- *
- * @mac_ctx: Pointer to Global MAC structure
- * @session_id: pe session id
- * @ft_preauth_req: Preauth request with parameters
- *
- * Builds a single channel scan request and sends it to WMA.
- * Scan dwell time is the time allocated to go to preauth candidate
- * channel for auth frame exchange.
- *
- * Return: Status of sending message to WMA.
- */
-QDF_STATUS lim_send_preauth_scan_offload(tpAniSirGlobal mac_ctx,
- uint8_t session_id,
- tSirFTPreAuthReq *ft_preauth_req)
-{
- tSirScanOffloadReq *scan_offload_req;
- tSirRetStatus rc = eSIR_SUCCESS;
- tSirMsgQ msg;
-
- scan_offload_req = qdf_mem_malloc(sizeof(tSirScanOffloadReq));
- if (NULL == scan_offload_req) {
- lim_log(mac_ctx, LOGE,
- FL("Memory allocation failed for pScanOffloadReq"));
- return QDF_STATUS_E_NOMEM;
- }
-
- qdf_mem_zero(scan_offload_req, sizeof(tSirScanOffloadReq));
-
- msg.type = WMA_START_SCAN_OFFLOAD_REQ;
- msg.bodyptr = scan_offload_req;
- msg.bodyval = 0;
-
- qdf_mem_copy((uint8_t *) &scan_offload_req->selfMacAddr.bytes,
- (uint8_t *) ft_preauth_req->self_mac_addr,
- sizeof(tSirMacAddr));
-
- qdf_mem_copy((uint8_t *) &scan_offload_req->bssId.bytes,
- (uint8_t *) ft_preauth_req->currbssId,
- sizeof(tSirMacAddr));
- scan_offload_req->scanType = eSIR_PASSIVE_SCAN;
- /*
- * P2P_SCAN_TYPE_LISTEN tells firmware to allow mgt frames to/from
- * mac address that is not of connected AP.
- */
- scan_offload_req->p2pScanType = P2P_SCAN_TYPE_LISTEN;
- scan_offload_req->restTime = 0;
- scan_offload_req->minChannelTime = LIM_FT_PREAUTH_SCAN_TIME;
- scan_offload_req->maxChannelTime = LIM_FT_PREAUTH_SCAN_TIME;
- scan_offload_req->sessionId = session_id;
- scan_offload_req->channelList.numChannels = 1;
- scan_offload_req->channelList.channelNumber[0] =
- ft_preauth_req->preAuthchannelNum;
- wma_get_scan_id(&ft_preauth_req->scan_id);
- scan_offload_req->scan_id = ft_preauth_req->scan_id;
- scan_offload_req->scan_requestor_id = PREAUTH_REQUESTOR_ID;
-
- lim_log(mac_ctx, LOG1,
- FL("Scan request: duration %u, session %hu, chan %hu"),
- scan_offload_req->maxChannelTime, session_id,
- ft_preauth_req->preAuthchannelNum);
-
- rc = wma_post_ctrl_msg(mac_ctx, &msg);
- if (rc != eSIR_SUCCESS) {
- lim_log(mac_ctx, LOGE, FL("START_SCAN_OFFLOAD failed %u"), rc);
- qdf_mem_free(scan_offload_req);
- return QDF_STATUS_E_FAILURE;
- }
-
- return QDF_STATUS_SUCCESS;
-}
-
-
-/**
- * lim_preauth_scan_event_handler() - Process firmware preauth scan events
- *
- * @mac_ctx:Pointer to global MAC structure
- * @event: Scan event
- * @session_id: session entry
- * @scan_id: scan id from WMA scan event.
- *
- * If scan event signifies failure or successful completion, operation
- * is complete.
- * If scan event signifies that STA is on foreign channel, send auth frame
- *
- * Return: void
- */
-
-void lim_preauth_scan_event_handler(tpAniSirGlobal mac_ctx,
- enum lim_scan_event_type event,
- uint8_t session_id,
- uint32_t scan_id)
-{
- tpPESession session_entry;
-
- session_entry = pe_find_session_by_session_id(mac_ctx, session_id);
- if (session_entry == NULL) {
- lim_log(mac_ctx, LOGE,
- FL("SessionId:%d Session Does not exist"), session_id);
- return;
- }
-
- switch (event) {
- case LIM_SCAN_EVENT_START_FAILED:
- /* Scan command is rejected by firmware */
- lim_log(mac_ctx, LOGE, FL("Failed to start preauth scan"));
- lim_post_ft_pre_auth_rsp(mac_ctx, eSIR_FAILURE, NULL, 0,
- session_entry);
- return;
-
- case LIM_SCAN_EVENT_COMPLETED:
- /*
- * Scan either completed succesfully or or got terminated
- * after successful auth, or timed out. Either way, STA
- * is back to home channel. Data traffic can continue.
- */
- lim_ft_process_pre_auth_result(mac_ctx, QDF_STATUS_SUCCESS,
- session_entry);
- break;
-
- case LIM_SCAN_EVENT_FOREIGN_CHANNEL:
- /* Sta is on candidate channel. Send auth */
- lim_perform_ft_pre_auth(mac_ctx, QDF_STATUS_SUCCESS, NULL,
- session_entry);
- break;
- default:
- /* Don't print message for scan events that are ignored */
- break;
- }
-}
-
diff --git a/core/mac/src/pe/lim/lim_ft_preauth.c b/core/mac/src/pe/lim/lim_ft_preauth.c
new file mode 100644
index 000000000000..0bc94f9c1fbb
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_ft_preauth.c
@@ -0,0 +1,782 @@
+/*
+ * 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: lim_ft_preauth.c
+ *
+ * Pre-Authentication implementation for host based roaming
+ */
+#include <lim_send_messages.h>
+#include <lim_types.h>
+#include <lim_ft.h>
+#include <lim_ft_defs.h>
+#include <lim_utils.h>
+#include <lim_prop_exts_utils.h>
+#include <lim_assoc_utils.h>
+#include <lim_session.h>
+#include <lim_admit_control.h>
+#include "wma.h"
+
+/**
+ * lim_ft_cleanup_pre_auth_info() - Cleanup preauth related information
+ * @pMac: Global MAC Context
+ * @psessionEntry: PE Session
+ *
+ * This routine is called to free the FT context, session and other
+ * information used during preauth operation.
+ *
+ * Return: None
+ */
+void lim_ft_cleanup_pre_auth_info(tpAniSirGlobal pMac,
+ tpPESession psessionEntry)
+{
+ tpPESession pReAssocSessionEntry = NULL;
+ uint8_t sessionId = 0;
+
+ if (!psessionEntry) {
+ lim_log(pMac, LOGE, FL("psessionEntry is NULL"));
+ return;
+ }
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+ lim_log(pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ return;
+ }
+
+ if (psessionEntry->ftPEContext.pFTPreAuthReq) {
+ pReAssocSessionEntry =
+ pe_find_session_by_bssid(pMac,
+ psessionEntry->ftPEContext.
+ pFTPreAuthReq->preAuthbssId,
+ &sessionId);
+
+ lim_log(pMac, LOG1, FL("Freeing pFTPreAuthReq= %p"),
+ psessionEntry->ftPEContext.pFTPreAuthReq);
+ if (psessionEntry->ftPEContext.pFTPreAuthReq->
+ pbssDescription) {
+ qdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq->
+ pbssDescription);
+ psessionEntry->ftPEContext.pFTPreAuthReq->
+ pbssDescription = NULL;
+ }
+ qdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq);
+ psessionEntry->ftPEContext.pFTPreAuthReq = NULL;
+ }
+
+ if (psessionEntry->ftPEContext.pAddBssReq) {
+ qdf_mem_free(psessionEntry->ftPEContext.pAddBssReq);
+ psessionEntry->ftPEContext.pAddBssReq = NULL;
+ }
+
+ if (psessionEntry->ftPEContext.pAddStaReq) {
+ qdf_mem_free(psessionEntry->ftPEContext.pAddStaReq);
+ psessionEntry->ftPEContext.pAddStaReq = NULL;
+ }
+
+ /* The session is being deleted, cleanup the contents */
+ qdf_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext), 0);
+
+ /* Delete the session created while handling pre-auth response */
+ if (pReAssocSessionEntry) {
+ /* If we have successful pre-auth response, then we would have
+ * created a session on which reassoc request will be sent
+ */
+ if (pReAssocSessionEntry->valid &&
+ pReAssocSessionEntry->limSmeState ==
+ eLIM_SME_WT_REASSOC_STATE) {
+ QDF_TRACE(QDF_MODULE_ID_PE,
+ QDF_TRACE_LEVEL_DEBUG,
+ FL("Deleting Preauth session(%d)"),
+ pReAssocSessionEntry->peSessionId);
+ pe_delete_session(pMac, pReAssocSessionEntry);
+ }
+ }
+}
+
+/*
+ * lim_process_ft_pre_auth_req() - process ft pre auth req
+ *
+ * @mac_ctx: global mac ctx
+ * @msg: pointer to message
+ *
+ * In this function, we process the FT Pre Auth Req:
+ * We receive Pre-Auth, suspend link, register a call back. In the call back,
+ * we will need to accept frames from the new bssid. Send out the auth req to
+ * new AP. Start timer and when the timer is done or if we receive the Auth
+ * response. We change channel. Resume link
+ *
+ * Return: value to indicate if buffer was consumed
+ */
+int lim_process_ft_pre_auth_req(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
+{
+ int buf_consumed = false;
+ tpPESession session;
+ uint8_t session_id;
+ tpSirFTPreAuthReq ft_pre_auth_req = (tSirFTPreAuthReq *) msg->bodyptr;
+
+ if (NULL == ft_pre_auth_req) {
+ lim_log(mac_ctx, LOGE, FL("tSirFTPreAuthReq is NULL"));
+ return buf_consumed;
+ }
+
+ /* Get the current session entry */
+ session = pe_find_session_by_bssid(mac_ctx,
+ ft_pre_auth_req->currbssId,
+ &session_id);
+ if (session == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("Unable to find session for the bssid"
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(ft_pre_auth_req->currbssId));
+ /* Post the FT Pre Auth Response to SME */
+ lim_post_ft_pre_auth_rsp(mac_ctx, eSIR_FAILURE, NULL, 0,
+ session);
+ /*
+ * return FALSE, since the Pre-Auth Req will be freed in
+ * limPostFTPreAuthRsp on failure
+ */
+ return buf_consumed;
+ }
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(session)) {
+ lim_log(mac_ctx, LOGE, FL("session is not in STA mode"));
+ buf_consumed = true;
+ return buf_consumed;
+ }
+
+ /* Can set it only after sending auth */
+ session->ftPEContext.ftPreAuthStatus = eSIR_FAILURE;
+ session->ftPEContext.ftPreAuthSession = true;
+
+ /* Indicate that this is the session on which preauth is being done */
+ if (session->ftPEContext.pFTPreAuthReq) {
+ if (session->ftPEContext.pFTPreAuthReq->pbssDescription) {
+ qdf_mem_free(
+ session->ftPEContext.pFTPreAuthReq->pbssDescription);
+ session->ftPEContext.pFTPreAuthReq->pbssDescription =
+ NULL;
+ }
+ qdf_mem_free(session->ftPEContext.pFTPreAuthReq);
+ session->ftPEContext.pFTPreAuthReq = NULL;
+ }
+
+ /* We need information from the Pre-Auth Req. Lets save that */
+ session->ftPEContext.pFTPreAuthReq = ft_pre_auth_req;
+
+ lim_log(mac_ctx, LOG1, FL("PRE Auth ft_ies_length=%02x%02x%02x"),
+ session->ftPEContext.pFTPreAuthReq->ft_ies[0],
+ session->ftPEContext.pFTPreAuthReq->ft_ies[1],
+ session->ftPEContext.pFTPreAuthReq->ft_ies[2]);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_PRE_AUTH_REQ_EVENT,
+ session, 0, 0);
+#endif
+
+ /* Dont need to suspend if APs are in same channel */
+ if (session->currentOperChannel !=
+ session->ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+ /* Need to suspend link only if the channels are different */
+ lim_log(mac_ctx, LOG2,
+ FL("Performing pre-auth on diff channel(session %p)"),
+ session);
+ lim_send_preauth_scan_offload(mac_ctx, session->peSessionId,
+ session->ftPEContext.pFTPreAuthReq);
+ } else {
+ lim_log(mac_ctx, LOG2,
+ FL("Performing pre-auth on same channel (session %p)"),
+ session);
+ /* We are in the same channel. Perform pre-auth */
+ lim_perform_ft_pre_auth(mac_ctx, QDF_STATUS_SUCCESS, NULL,
+ session);
+ }
+
+ return buf_consumed;
+}
+
+/**
+ * lim_perform_ft_pre_auth() - Perform preauthentication
+ * @pMac: Global MAC Context
+ * @status: Status Code
+ * @data: pre-auth data
+ * @psessionEntry: PE Session
+ *
+ * This routine will trigger the sending of authentication frame
+ * to the peer.
+ *
+ * Return: None
+ */
+void lim_perform_ft_pre_auth(tpAniSirGlobal pMac, QDF_STATUS status,
+ uint32_t *data, tpPESession psessionEntry)
+{
+ tSirMacAuthFrameBody authFrame;
+
+ if (NULL == psessionEntry) {
+ PELOGE(lim_log(pMac, LOGE, FL("psessionEntry is NULL"));)
+ return;
+ }
+
+ if (psessionEntry->is11Rconnection &&
+ psessionEntry->ftPEContext.pFTPreAuthReq) {
+ /* Only 11r assoc has FT IEs */
+ if (psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies == NULL) {
+ lim_log(pMac, LOGE,
+ FL("FTIEs for Auth Req Seq 1 is absent"));
+ goto preauth_fail;
+ }
+ }
+
+ if (status != QDF_STATUS_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL(" Change channel not successful for FT pre-auth"));
+ goto preauth_fail;
+ }
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+ lim_log(pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ return;
+ }
+ lim_log(pMac, LOG2, "Entered wait auth2 state for FT (old session %p)",
+ psessionEntry);
+ if (psessionEntry->is11Rconnection) {
+ /* Now we are on the right channel and need to send out Auth1
+ * and receive Auth2
+ */
+ authFrame.authAlgoNumber = eSIR_FT_AUTH;
+ } else {
+ /* Will need to make isESEconnection a enum may be for further
+ * improvements to this to match this algorithm number
+ */
+ authFrame.authAlgoNumber = eSIR_OPEN_SYSTEM;
+ }
+ authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
+ authFrame.authStatusCode = 0;
+
+ /* Start timer here to come back to operating channel */
+ pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId =
+ psessionEntry->peSessionId;
+ if (TX_SUCCESS !=
+ tx_timer_activate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer)) {
+ lim_log(pMac, LOGE, FL("FT Auth Rsp Timer Start Failed"));
+ goto preauth_fail;
+ }
+ MTRACE(mac_trace(pMac, TRACE_CODE_TIMER_ACTIVATE,
+ psessionEntry->peSessionId, eLIM_FT_PREAUTH_RSP_TIMER));
+
+ lim_log(pMac, LOG1, FL("FT Auth Rsp Timer Started"));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_ROAM_AUTH_START_EVENT,
+ pMac->lim.pSessionEntry, eSIR_SUCCESS, eSIR_SUCCESS);
+#endif
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId,
+ LIM_NO_WEP_IN_FC, psessionEntry, false);
+
+ return;
+
+preauth_fail:
+ lim_handle_ft_pre_auth_rsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry);
+ return;
+}
+
+/**
+ * lim_ft_setup_auth_session() - Fill the FT Session
+ * @pMac: Global MAC Context
+ * @psessionEntry: PE Session
+ *
+ * Setup the session and the add bss req for the pre-auth AP.
+ *
+ * Return: Success or Failure Status
+ */
+tSirRetStatus lim_ft_setup_auth_session(tpAniSirGlobal pMac,
+ tpPESession psessionEntry)
+{
+ tpPESession pftSessionEntry = NULL;
+ uint8_t sessionId = 0;
+
+ pftSessionEntry =
+ pe_find_session_by_bssid(pMac, psessionEntry->limReAssocbssId,
+ &sessionId);
+ if (pftSessionEntry == NULL) {
+ lim_log(pMac, LOGE, FL("No session found for bssid"));
+ lim_print_mac_addr(pMac, psessionEntry->limReAssocbssId, LOGE);
+ return eSIR_FAILURE;
+ }
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+ lim_log(pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ return eSIR_FAILURE;
+ }
+
+ if (psessionEntry->ftPEContext.pFTPreAuthReq &&
+ psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) {
+ lim_fill_ft_session(pMac,
+ psessionEntry->ftPEContext.pFTPreAuthReq->
+ pbssDescription, pftSessionEntry,
+ psessionEntry);
+
+ lim_ft_prepare_add_bss_req(pMac, false, pftSessionEntry,
+ psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription);
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/**
+ * lim_ft_process_pre_auth_result() - Process the Auth frame
+ * @pMac: Global MAC context
+ * @status: Status code
+ * psessionEntry: PE Session
+ *
+ * Return: None
+ */
+void lim_ft_process_pre_auth_result(tpAniSirGlobal pMac, QDF_STATUS status,
+ tpPESession psessionEntry)
+{
+ if (NULL == psessionEntry ||
+ NULL == psessionEntry->ftPEContext.pFTPreAuthReq)
+ return;
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+ lim_log(pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ return;
+ }
+
+ if (psessionEntry->ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) {
+ psessionEntry->ftPEContext.ftPreAuthStatus =
+ lim_ft_setup_auth_session(pMac, psessionEntry);
+ }
+ /* Post the FT Pre Auth Response to SME */
+ lim_post_ft_pre_auth_rsp(pMac,
+ psessionEntry->ftPEContext.ftPreAuthStatus,
+ psessionEntry->ftPEContext.saved_auth_rsp,
+ psessionEntry->ftPEContext.saved_auth_rsp_length,
+ psessionEntry);
+}
+
+/**
+ * lim_handle_ft_pre_auth_rsp() - Handle the Auth response
+ * @pMac: Global MAC Context
+ * @status: Status Code
+ * @auth_rsp: Auth Response
+ * @auth_rsp_length: Auth response length
+ * @psessionEntry: PE Session
+ *
+ * Send the FT Pre Auth Response to SME whenever we have a status
+ * ready to be sent to SME
+ *
+ * SME will be the one to send it up to the supplicant to receive
+ * FTIEs which will be required for Reassoc Req.
+ *
+ * @Return: None
+ */
+void lim_handle_ft_pre_auth_rsp(tpAniSirGlobal pMac, tSirRetStatus status,
+ uint8_t *auth_rsp, uint16_t auth_rsp_length,
+ tpPESession psessionEntry)
+{
+ tpPESession pftSessionEntry = NULL;
+ uint8_t sessionId = 0;
+ tpSirBssDescription pbssDescription = NULL;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT,
+ psessionEntry, (uint16_t) status, 0);
+#endif
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+ lim_log(pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ return;
+ }
+
+ /* Save the status of pre-auth */
+ psessionEntry->ftPEContext.ftPreAuthStatus = status;
+
+ /* Save the auth rsp, so we can send it to
+ * SME once we resume link
+ */
+ psessionEntry->ftPEContext.saved_auth_rsp_length = 0;
+ if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE)) {
+ qdf_mem_copy(psessionEntry->ftPEContext.saved_auth_rsp,
+ auth_rsp, auth_rsp_length);
+ psessionEntry->ftPEContext.saved_auth_rsp_length =
+ auth_rsp_length;
+ }
+
+ if (!psessionEntry->ftPEContext.pFTPreAuthReq ||
+ !psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) {
+ lim_log(pMac, LOGE,
+ FL("pFTPreAuthReq or pbssDescription is NULL"));
+ return;
+ }
+
+ /* Create FT session for the re-association at this point */
+ if (psessionEntry->ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) {
+ pbssDescription =
+ psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription;
+ lim_print_mac_addr(pMac, pbssDescription->bssId, LOG1);
+ pftSessionEntry =
+ pe_create_session(pMac, pbssDescription->bssId,
+ &sessionId, pMac->lim.maxStation,
+ psessionEntry->bssType);
+ if (pftSessionEntry == NULL) {
+ lim_log(pMac, LOGE, FL(
+ "Session not created for pre-auth 11R AP"));
+ status = eSIR_FAILURE;
+ psessionEntry->ftPEContext.ftPreAuthStatus = status;
+ goto send_rsp;
+ }
+ pftSessionEntry->peSessionId = sessionId;
+ pftSessionEntry->smeSessionId = psessionEntry->smeSessionId;
+ sir_copy_mac_addr(pftSessionEntry->selfMacAddr,
+ psessionEntry->selfMacAddr);
+ sir_copy_mac_addr(pftSessionEntry->limReAssocbssId,
+ pbssDescription->bssId);
+ pftSessionEntry->bssType = psessionEntry->bssType;
+
+ if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE)
+ pftSessionEntry->limSystemRole = eLIM_STA_ROLE;
+ else if (pftSessionEntry->bssType == eSIR_BTAMP_AP_MODE)
+ pftSessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE;
+ else
+ lim_log(pMac, LOGE, FL("Invalid bss type"));
+ pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState;
+ qdf_mem_copy(&(pftSessionEntry->htConfig),
+ &(psessionEntry->htConfig),
+ sizeof(psessionEntry->htConfig));
+ pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+
+ lim_log(pMac, LOG1, FL("created session (%p) with id = %d"),
+ pftSessionEntry, pftSessionEntry->peSessionId);
+
+ /* Update the ReAssoc BSSID of the current session */
+ sir_copy_mac_addr(psessionEntry->limReAssocbssId,
+ pbssDescription->bssId);
+ lim_print_mac_addr(pMac, psessionEntry->limReAssocbssId, LOG1);
+ }
+send_rsp:
+ if (psessionEntry->currentOperChannel !=
+ psessionEntry->ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+ /* Need to move to the original AP channel */
+ lim_process_abort_scan_ind(pMac, psessionEntry->peSessionId,
+ psessionEntry->ftPEContext.pFTPreAuthReq->scan_id,
+ PREAUTH_REQUESTOR_ID);
+ } else {
+ lim_log(pMac, LOG1,
+ "Pre auth on same channel as connected AP channel %d",
+ psessionEntry->ftPEContext.pFTPreAuthReq->
+ preAuthchannelNum);
+ lim_ft_process_pre_auth_result(pMac, status, psessionEntry);
+ }
+}
+
+/*
+ * lim_process_ft_preauth_rsp_timeout() - process ft preauth rsp timeout
+ *
+ * @mac_ctx: global mac ctx
+ *
+ * This function is called if preauth response is not received from the AP
+ * within this timeout while FT in progress
+ *
+ * Return: void
+ */
+void lim_process_ft_preauth_rsp_timeout(tpAniSirGlobal mac_ctx)
+{
+ tpPESession session;
+
+ /*
+ * We have failed pre auth. We need to resume link and get back on
+ * home channel
+ */
+ lim_log(mac_ctx, LOGE, FL("FT Pre-Auth Time Out!!!!"));
+ session = pe_find_session_by_session_id(mac_ctx,
+ mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer.sessionId);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGE,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(session)) {
+ lim_log(mac_ctx, LOGE, FL("session is not in STA mode"));
+ return;
+ }
+
+ /* Reset the flag to indicate preauth request session */
+ session->ftPEContext.ftPreAuthSession = false;
+
+ if (NULL == session->ftPEContext.pFTPreAuthReq) {
+ /* Auth Rsp might already be posted to SME and ftcleanup done */
+ lim_log(mac_ctx, LOGE, FL("pFTPreAuthReq is NULL sessionId:%d"),
+ mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer.sessionId);
+ return;
+ }
+
+ /*
+ * To handle the race condition where we recieve preauth rsp after
+ * timer has expired.
+ */
+ if (true ==
+ session->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) {
+ lim_log(mac_ctx, LOGE,
+ FL("Auth rsp already posted to SME (session %p)"),
+ session);
+ return;
+ } else {
+ /*
+ * Here we are sending preauth rsp with failure state
+ * and which is forwarded to SME. Now, if we receive an preauth
+ * resp from AP with success it would create a FT pesession, but
+ * will be dropped in SME leaving behind the pesession. Mark
+ * Preauth rsp processed so that any rsp from AP is dropped in
+ * lim_process_auth_frame_no_session.
+ */
+ lim_log(mac_ctx, LOG1,
+ FL("Auth rsp not yet posted to SME (session %p)"),
+ session);
+ session->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed = true;
+ }
+
+ /*
+ * Attempted at Pre-Auth and failed. If we are off channel. We need
+ * to get back to home channel
+ */
+ lim_handle_ft_pre_auth_rsp(mac_ctx, eSIR_FAILURE, NULL, 0, session);
+}
+
+/*
+ * lim_post_ft_pre_auth_rsp() - post ft pre auth response to SME.
+ *
+ * @mac_ctx: global mac ctx
+ * @status: status code to post in auth rsp
+ * @auth_rsp: pointer to auth rsp FT ie
+ * @auth_rsp_length: len of the IE field
+ * @session: pe session
+ *
+ * post pre auth response to SME.
+ *
+ * Return: void
+ */
+void lim_post_ft_pre_auth_rsp(tpAniSirGlobal mac_ctx,
+ tSirRetStatus status,
+ uint8_t *auth_rsp,
+ uint16_t auth_rsp_length,
+ tpPESession session)
+{
+ tpSirFTPreAuthRsp ft_pre_auth_rsp;
+ tSirMsgQ mmh_msg;
+ uint16_t rsp_len = sizeof(tSirFTPreAuthRsp);
+
+ ft_pre_auth_rsp = (tpSirFTPreAuthRsp) qdf_mem_malloc(rsp_len);
+ if (NULL == ft_pre_auth_rsp) {
+ lim_log(mac_ctx, LOGE, "Failed to allocate memory");
+ QDF_ASSERT(ft_pre_auth_rsp != NULL);
+ return;
+ }
+ qdf_mem_zero(ft_pre_auth_rsp, rsp_len);
+
+ lim_log(mac_ctx, LOG1, FL("Auth Rsp = %p"), ft_pre_auth_rsp);
+ if (session) {
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(session)) {
+ lim_log(mac_ctx, LOGE,
+ FL("session is not in STA mode"));
+ qdf_mem_free(ft_pre_auth_rsp);
+ return;
+ }
+ ft_pre_auth_rsp->smeSessionId = session->smeSessionId;
+ /* The bssid of the AP we are sending Auth1 to. */
+ if (session->ftPEContext.pFTPreAuthReq)
+ sir_copy_mac_addr(ft_pre_auth_rsp->preAuthbssId,
+ session->ftPEContext.pFTPreAuthReq->preAuthbssId);
+ }
+
+ ft_pre_auth_rsp->messageType = eWNI_SME_FT_PRE_AUTH_RSP;
+ ft_pre_auth_rsp->length = (uint16_t) rsp_len;
+ ft_pre_auth_rsp->status = status;
+
+ /* Attach the auth response now back to SME */
+ ft_pre_auth_rsp->ft_ies_length = 0;
+ if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE)) {
+ /* Only 11r assoc has FT IEs */
+ qdf_mem_copy(ft_pre_auth_rsp->ft_ies,
+ auth_rsp, auth_rsp_length);
+ ft_pre_auth_rsp->ft_ies_length = auth_rsp_length;
+ }
+
+ if (status != eSIR_SUCCESS) {
+ /*
+ * Ensure that on Pre-Auth failure the cached Pre-Auth Req and
+ * other allocated memory is freed up before returning.
+ */
+ lim_log(mac_ctx, LOG1, "Pre-Auth Failed, Cleanup!");
+ lim_ft_cleanup(mac_ctx, session);
+ }
+
+ mmh_msg.type = ft_pre_auth_rsp->messageType;
+ mmh_msg.bodyptr = ft_pre_auth_rsp;
+ mmh_msg.bodyval = 0;
+
+ lim_log(mac_ctx, LOG1, FL("Posted Auth Rsp to SME with status of 0x%x"),
+ status);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ if (status == eSIR_SUCCESS)
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_PREAUTH_DONE,
+ session, status, 0);
+#endif
+ lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg, ePROT);
+}
+
+/**
+ * lim_send_preauth_scan_offload() - Send scan command to handle preauth.
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: pe session id
+ * @ft_preauth_req: Preauth request with parameters
+ *
+ * Builds a single channel scan request and sends it to WMA.
+ * Scan dwell time is the time allocated to go to preauth candidate
+ * channel for auth frame exchange.
+ *
+ * Return: Status of sending message to WMA.
+ */
+QDF_STATUS lim_send_preauth_scan_offload(tpAniSirGlobal mac_ctx,
+ uint8_t session_id,
+ tSirFTPreAuthReq *ft_preauth_req)
+{
+ tSirScanOffloadReq *scan_offload_req;
+ tSirRetStatus rc = eSIR_SUCCESS;
+ tSirMsgQ msg;
+
+ scan_offload_req = qdf_mem_malloc(sizeof(tSirScanOffloadReq));
+ if (NULL == scan_offload_req) {
+ lim_log(mac_ctx, LOGE,
+ FL("Memory allocation failed for pScanOffloadReq"));
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ qdf_mem_zero(scan_offload_req, sizeof(tSirScanOffloadReq));
+
+ msg.type = WMA_START_SCAN_OFFLOAD_REQ;
+ msg.bodyptr = scan_offload_req;
+ msg.bodyval = 0;
+
+ qdf_mem_copy((uint8_t *) &scan_offload_req->selfMacAddr.bytes,
+ (uint8_t *) ft_preauth_req->self_mac_addr,
+ sizeof(tSirMacAddr));
+
+ qdf_mem_copy((uint8_t *) &scan_offload_req->bssId.bytes,
+ (uint8_t *) ft_preauth_req->currbssId,
+ sizeof(tSirMacAddr));
+ scan_offload_req->scanType = eSIR_PASSIVE_SCAN;
+ /*
+ * P2P_SCAN_TYPE_LISTEN tells firmware to allow mgt frames to/from
+ * mac address that is not of connected AP.
+ */
+ scan_offload_req->p2pScanType = P2P_SCAN_TYPE_LISTEN;
+ scan_offload_req->restTime = 0;
+ scan_offload_req->minChannelTime = LIM_FT_PREAUTH_SCAN_TIME;
+ scan_offload_req->maxChannelTime = LIM_FT_PREAUTH_SCAN_TIME;
+ scan_offload_req->sessionId = session_id;
+ scan_offload_req->channelList.numChannels = 1;
+ scan_offload_req->channelList.channelNumber[0] =
+ ft_preauth_req->preAuthchannelNum;
+ wma_get_scan_id(&ft_preauth_req->scan_id);
+ scan_offload_req->scan_id = ft_preauth_req->scan_id;
+ scan_offload_req->scan_requestor_id = PREAUTH_REQUESTOR_ID;
+
+ lim_log(mac_ctx, LOG1,
+ FL("Scan request: duration %u, session %hu, chan %hu"),
+ scan_offload_req->maxChannelTime, session_id,
+ ft_preauth_req->preAuthchannelNum);
+
+ rc = wma_post_ctrl_msg(mac_ctx, &msg);
+ if (rc != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE, FL("START_SCAN_OFFLOAD failed %u"), rc);
+ qdf_mem_free(scan_offload_req);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_preauth_scan_event_handler() - Process firmware preauth scan events
+ *
+ * @mac_ctx:Pointer to global MAC structure
+ * @event: Scan event
+ * @session_id: session entry
+ * @scan_id: scan id from WMA scan event.
+ *
+ * If scan event signifies failure or successful completion, operation
+ * is complete.
+ * If scan event signifies that STA is on foreign channel, send auth frame
+ *
+ * Return: void
+ */
+
+void lim_preauth_scan_event_handler(tpAniSirGlobal mac_ctx,
+ enum lim_scan_event_type event,
+ uint8_t session_id,
+ uint32_t scan_id)
+{
+ tpPESession session_entry;
+
+ session_entry = pe_find_session_by_session_id(mac_ctx, session_id);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("SessionId:%d Session Does not exist"), session_id);
+ return;
+ }
+
+ switch (event) {
+ case LIM_SCAN_EVENT_START_FAILED:
+ /* Scan command is rejected by firmware */
+ lim_log(mac_ctx, LOGE, FL("Failed to start preauth scan"));
+ lim_post_ft_pre_auth_rsp(mac_ctx, eSIR_FAILURE, NULL, 0,
+ session_entry);
+ return;
+
+ case LIM_SCAN_EVENT_COMPLETED:
+ /*
+ * Scan either completed succesfully or or got terminated
+ * after successful auth, or timed out. Either way, STA
+ * is back to home channel. Data traffic can continue.
+ */
+ lim_ft_process_pre_auth_result(mac_ctx, QDF_STATUS_SUCCESS,
+ session_entry);
+ break;
+
+ case LIM_SCAN_EVENT_FOREIGN_CHANNEL:
+ /* Sta is on candidate channel. Send auth */
+ lim_perform_ft_pre_auth(mac_ctx, QDF_STATUS_SUCCESS, NULL,
+ session_entry);
+ break;
+ default:
+ /* Don't print message for scan events that are ignored */
+ break;
+ }
+}
+