From efb20a8901be0932cb5432e7d2f24b55dd5be195 Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Thu, 18 Apr 2019 19:17:23 +0530 Subject: [PATCH] qcacld-3.0: Provide assoc req, rsp IE to kernel in assoc fail case Currently the driver does not sends the assoc req and assoc response frame exchanged with the AP if the connection attempt fails with the peer. The connection failure can be because of n number of reasons, OCE assoc reject be one of them. The supplicant requires these IEs to reject the connection attempt with the AP with which the connect attempt failed for t number of seconds, which is mentioned by the AP. Fix is to send the assoc req, and assoc response IEs to the driver. Change-Id: I9c1f7063105912a8005f9e8399640d028b15eec7 CRs-Fixed: 2445709 --- core/hdd/src/wlan_hdd_assoc.c | 24 +++++- .../src/pe/lim/lim_send_sme_rsp_messages.c | 78 ++++++++++--------- core/sme/inc/csr_internal.h | 1 + core/sme/src/csr/csr_api_roam.c | 45 ++++++++++- 4 files changed, 105 insertions(+), 43 deletions(-) diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 5bfceeeae59d..a367493dba6b 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -3372,7 +3372,21 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, */ if (eCSR_ROAM_ASSOCIATION_FAILURE == roam_status && !hddDisconInProgress) { + u8 *assoc_rsp = NULL; + u8 *assoc_req = NULL; + if (roam_info) { + if (roam_info->pbFrames) { + /* Association Request */ + assoc_req = + (u8 *)(roam_info->pbFrames + + roam_info->nBeaconLength); + /* Association Response */ + assoc_rsp = + (u8 *)(roam_info->pbFrames + + roam_info->nBeaconLength + + roam_info->nAssocReqLength); + } hdd_err("send connect failure to nl80211: for bssid " QDF_MAC_ADDR_STR " result: %d and Status: %d reasoncode: %d", @@ -3397,7 +3411,10 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, if (roam_info) hdd_connect_result(dev, roam_info->bssid.bytes, - roam_info, NULL, 0, NULL, 0, + roam_info, assoc_req, + roam_info->nAssocReqLength, + assoc_rsp, + roam_info->nAssocRspLength, WLAN_STATUS_ASSOC_DENIED_UNSPEC, GFP_KERNEL, connect_timeout, @@ -3414,7 +3431,10 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, if (roam_info) hdd_connect_result(dev, roam_info->bssid.bytes, - roam_info, NULL, 0, NULL, 0, + roam_info, assoc_req, + roam_info->nAssocReqLength, + assoc_rsp, + roam_info->nAssocRspLength, roam_info->reasonCode ? roam_info->reasonCode : WLAN_STATUS_UNSPECIFIED_FAILURE, diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c index 377691017219..ec358b49f44c 100644 --- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c @@ -191,43 +191,47 @@ static void lim_handle_join_rsp_status(struct mac_context *mac_ctx, #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH struct ht_profile *ht_profile; #endif + if (session_entry->beacon) { + sme_join_rsp->beaconLength = session_entry->bcnLen; + qdf_mem_copy(sme_join_rsp->frames, + session_entry->beacon, + sme_join_rsp->beaconLength); + qdf_mem_free(session_entry->beacon); + session_entry->beacon = NULL; + session_entry->bcnLen = 0; + pe_debug("Beacon: %d", + sme_join_rsp->beaconLength); + } + + if (session_entry->assocReq) { + sme_join_rsp->assocReqLength = + session_entry->assocReqLen; + qdf_mem_copy(sme_join_rsp->frames + + sme_join_rsp->beaconLength, + session_entry->assocReq, + sme_join_rsp->assocReqLength); + qdf_mem_free(session_entry->assocReq); + session_entry->assocReq = NULL; + session_entry->assocReqLen = 0; + pe_debug("AssocReq: %d", + sme_join_rsp->assocReqLength); + } + if (session_entry->assocRsp) { + sme_join_rsp->assocRspLength = + session_entry->assocRspLen; + qdf_mem_copy(sme_join_rsp->frames + + sme_join_rsp->beaconLength + + sme_join_rsp->assocReqLength, + session_entry->assocRsp, + sme_join_rsp->assocRspLength); + qdf_mem_free(session_entry->assocRsp); + session_entry->assocRsp = NULL; + session_entry->assocRspLen = 0; + pe_debug("AssocRsp: %d", + sme_join_rsp->assocRspLength); + } + if (result_code == eSIR_SME_SUCCESS) { - if (session_entry->beacon) { - sme_join_rsp->beaconLength = session_entry->bcnLen; - qdf_mem_copy(sme_join_rsp->frames, - session_entry->beacon, - sme_join_rsp->beaconLength); - qdf_mem_free(session_entry->beacon); - session_entry->beacon = NULL; - session_entry->bcnLen = 0; - pe_debug("Beacon: %d", - sme_join_rsp->beaconLength); - } - if (session_entry->assocReq) { - sme_join_rsp->assocReqLength = - session_entry->assocReqLen; - qdf_mem_copy(sme_join_rsp->frames + - sme_join_rsp->beaconLength, - session_entry->assocReq, - sme_join_rsp->assocReqLength); - qdf_mem_free(session_entry->assocReq); - session_entry->assocReq = NULL; - session_entry->assocReqLen = 0; - pe_debug("AssocReq: %d", - sme_join_rsp->assocReqLength); - } - if (session_entry->assocRsp) { - sme_join_rsp->assocRspLength = - session_entry->assocRspLen; - qdf_mem_copy(sme_join_rsp->frames + - sme_join_rsp->beaconLength + - sme_join_rsp->assocReqLength, - session_entry->assocRsp, - sme_join_rsp->assocRspLength); - qdf_mem_free(session_entry->assocRsp); - session_entry->assocRsp = NULL; - session_entry->assocRspLen = 0; - } if (session_entry->ricData) { sme_join_rsp->parsedRicRspLen = session_entry->RICDataLen; @@ -262,8 +266,6 @@ static void lim_handle_join_rsp_status(struct mac_context *mac_ctx, } #endif sme_join_rsp->aid = session_entry->limAID; - pe_debug("AssocRsp: %d", - sme_join_rsp->assocRspLength); sme_join_rsp->vht_channel_width = session_entry->ch_width; #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h index 8ac6c4699622..4be42fb87b88 100644 --- a/core/sme/inc/csr_internal.h +++ b/core/sme/inc/csr_internal.h @@ -583,6 +583,7 @@ struct csr_roam_session { struct rsn_caps rsn_caps; tCsrRoamConnectedProfile connectedProfile; struct csr_roam_connectedinfo connectedInfo; + struct csr_roam_connectedinfo prev_assoc_ap_info; struct csr_roam_profile *pCurRoamProfile; tSirBssDescription *pConnectBssDesc; uint16_t NumPmkidCache; /* valid number of pmkid in the cache*/ diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 2f978154ade7..d5d5722c1a44 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -6299,6 +6299,7 @@ static void csr_roam_process_results_default(struct mac_context *mac_ctx, struct csr_roam_session *session; struct csr_roam_info *roam_info; QDF_STATUS status; + struct csr_roam_connectedinfo *prev_connect_info = NULL; if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { sme_err("Invalid session id %d", session_id); @@ -6309,6 +6310,8 @@ static void csr_roam_process_results_default(struct mac_context *mac_ctx, return; session = CSR_GET_SESSION(mac_ctx, session_id); + prev_connect_info = &session->prev_assoc_ap_info; + sme_debug("receives no association indication; FILS %d", session->is_fils_connection); sme_debug("Assoc ref count: %d", session->bRefAssocStartCnt); @@ -6360,7 +6363,15 @@ static void csr_roam_process_results_default(struct mac_context *mac_ctx, qdf_mem_copy(&roam_info->bssid, &session->joinFailStatusCode.bssId, sizeof(struct qdf_mac_addr)); - + if (prev_connect_info->pbFrames) { + roam_info->nAssocReqLength = + prev_connect_info->nAssocReqLength; + roam_info->nAssocRspLength = + prev_connect_info->nAssocRspLength; + roam_info->nBeaconLength = + prev_connect_info->nBeaconLength; + roam_info->pbFrames = prev_connect_info->pbFrames; + } /* * If Join fails while Handoff is in progress, indicate * disassociated event to supplicant to reconnect @@ -8732,6 +8743,8 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, tListElem *pEntry = NULL; tSmeCmd *pCommand = NULL; struct csr_roam_session *session_ptr; + struct csr_roam_connectedinfo *prev_connect_info; + uint32_t len = 0; if (pSmeJoinRsp) { session_ptr = CSR_GET_SESSION(mac, pSmeJoinRsp->sessionId); @@ -8745,6 +8758,8 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, ("session %d not found"), pSmeJoinRsp->sessionId); return; } + + prev_connect_info = &session_ptr->prev_assoc_ap_info; /* The head of the active list is the request we sent */ pEntry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK); if (pEntry) @@ -8809,6 +8824,25 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, pSmeJoinRsp->sessionId, QDF_STATUS_E_FAILURE); } + + len = pSmeJoinRsp->assocReqLength + + pSmeJoinRsp->assocRspLength + pSmeJoinRsp->beaconLength; + if (prev_connect_info->pbFrames) + csr_roam_free_connected_info(mac, prev_connect_info); + + prev_connect_info->pbFrames = qdf_mem_malloc(len); + if (!prev_connect_info->pbFrames) + sme_err("memory allocation failed for previous assoc profile"); + else { + qdf_mem_copy(prev_connect_info->pbFrames, + pSmeJoinRsp->frames, len); + prev_connect_info->nAssocReqLength = + pSmeJoinRsp->assocReqLength; + prev_connect_info->nAssocRspLength = + pSmeJoinRsp->assocRspLength; + prev_connect_info->nBeaconLength = + pSmeJoinRsp->beaconLength; + } /* * if userspace has issued disconnection, * driver should not continue connecting @@ -8816,9 +8850,9 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, is_dis_pending = is_disconnect_pending(mac, session_ptr->sessionId); if (pCommand && (session_ptr->join_bssid_count < - CSR_MAX_BSSID_COUNT) && !is_dis_pending) + CSR_MAX_BSSID_COUNT) && !is_dis_pending) { csr_roam(mac, pCommand); - else { + } else { /* * When the upper layers issue a connect command, there * is a roam command with reason eCsrHddIssued that @@ -8854,6 +8888,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, csr_roam_complete(mac, eCsrNothingToJoin, NULL, pSmeJoinRsp->sessionId); } + csr_roam_free_connected_info(mac, prev_connect_info); } /*else: ( eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode ) */ } @@ -17183,6 +17218,8 @@ void csr_cleanup_session(struct mac_context *mac, uint32_t sessionId) csr_reset_cfg_privacy(mac); csr_roam_free_connect_profile(&pSession->connectedProfile); csr_roam_free_connected_info(mac, &pSession->connectedInfo); + csr_roam_free_connected_info(mac, + &pSession->prev_assoc_ap_info); qdf_mc_timer_destroy(&pSession->hTimerRoaming); qdf_mc_timer_destroy(&pSession->roaming_offload_timer); csr_purge_vdev_pending_ser_cmd_list(mac, sessionId); @@ -17249,6 +17286,8 @@ static void csr_init_session(struct mac_context *mac, uint32_t sessionId) csr_free_roam_profile(mac, sessionId); csr_roam_free_connect_profile(&pSession->connectedProfile); csr_roam_free_connected_info(mac, &pSession->connectedInfo); + csr_roam_free_connected_info(mac, + &pSession->prev_assoc_ap_info); csr_free_connect_bss_desc(mac, sessionId); qdf_mem_zero(&pSession->selfMacAddr, sizeof(struct qdf_mac_addr)); if (pSession->pWpaRsnReqIE) {