qcacld-3.0: Fix freeing of SAP PE session lim_send_sme_disassoc_ntf
When a peer connected to a SAP session triggers disconnect,
lim_send_sme_disassoc_ntf is called with the reason
eLIM_PEER_ENTITY_DISASSOC. This leads to the PE sesssion for the SAP
being freed as part of the lim_send_disconnect_done_ind added in the
change Iec0176fecf218e07f31b258c0dc52aefb480defe.
Modify the lim_send_disconnect_done_ind API to just prepare the
disconnect done indication message and the calling function
lim_send_sme_disassoc_ntf would send the notification to SME and
free the PE session only if the current session is a STA.
Change-Id: I377f86f10becd467417d4c6409d167020e26fe87
CRs-Fixed: 2241899
diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
index 0552e78..ebc4d67 100644
--- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -2282,6 +2282,8 @@
tpDphHashNode pStaDs;
tpPESession psessionEntry;
uint8_t sessionId;
+ uint32_t *msg = NULL;
+ QDF_STATUS status;
qdf_mem_copy(&smeDisassocCnf, pMsgBuf,
sizeof(struct sSirSmeDisassocCnf));
@@ -2291,16 +2293,26 @@
&sessionId);
if (psessionEntry == NULL) {
pe_err("session does not exist for given bssId");
- lim_send_disconnect_done_ind(pMac, NULL, CSR_SESSION_ID_INVALID,
- eSIR_SME_INVALID_SESSION, NULL);
+ status = lim_prepare_disconnect_done_ind(pMac, &msg,
+ CSR_SESSION_ID_INVALID,
+ eSIR_SME_INVALID_SESSION,
+ NULL);
+ if (QDF_IS_STATUS_SUCCESS(status))
+ lim_send_sme_disassoc_deauth_ntf(pMac,
+ QDF_STATUS_SUCCESS,
+ (uint32_t *)msg);
return;
}
if (!lim_is_sme_disassoc_cnf_valid(pMac, &smeDisassocCnf, psessionEntry)) {
pe_err("received invalid SME_DISASSOC_CNF message");
- lim_send_disconnect_done_ind(pMac, psessionEntry, sessionId,
- eSIR_SME_INVALID_PARAMETERS,
- smeDisassocCnf.bssid.bytes);
+ status = lim_prepare_disconnect_done_ind(pMac, &msg, sessionId,
+ eSIR_SME_INVALID_PARAMETERS,
+ &smeDisassocCnf.bssid.bytes[0]);
+ if (QDF_IS_STATUS_SUCCESS(status))
+ lim_send_sme_disassoc_deauth_ntf(pMac,
+ QDF_STATUS_SUCCESS,
+ (uint32_t *)msg);
return;
}
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
@@ -2324,11 +2336,15 @@
psessionEntry->limSmeState);
lim_print_sme_state(pMac, LOGE,
psessionEntry->limSmeState);
- lim_send_disconnect_done_ind(pMac, psessionEntry,
- sessionId,
- eSIR_SME_INVALID_STATE,
- smeDisassocCnf.bssid.
- bytes);
+ status = lim_prepare_disconnect_done_ind(pMac, &msg,
+ sessionId,
+ eSIR_SME_INVALID_STATE,
+ &smeDisassocCnf.bssid.
+ bytes[0]);
+ if (QDF_IS_STATUS_SUCCESS(status))
+ lim_send_sme_disassoc_deauth_ntf(pMac,
+ QDF_STATUS_SUCCESS,
+ (uint32_t *)msg);
return;
}
break;
@@ -2341,9 +2357,13 @@
default: /* eLIM_UNKNOWN_ROLE */
pe_err("received unexpected SME_DISASSOC_CNF role %d",
GET_LIM_SYSTEM_ROLE(psessionEntry));
- lim_send_disconnect_done_ind(pMac, psessionEntry, sessionId,
- eSIR_SME_INVALID_STATE,
- smeDisassocCnf.bssid.bytes);
+ status = lim_prepare_disconnect_done_ind(pMac, &msg, sessionId,
+ eSIR_SME_INVALID_STATE,
+ &smeDisassocCnf.bssid.bytes[0]);
+ if (QDF_IS_STATUS_SUCCESS(status))
+ lim_send_sme_disassoc_deauth_ntf(pMac,
+ QDF_STATUS_SUCCESS,
+ (uint32_t *)msg);
return;
}
@@ -2357,10 +2377,14 @@
pe_err("DISASSOC_CNF for a STA with no context, addr= "
MAC_ADDRESS_STR,
MAC_ADDR_ARRAY(smeDisassocCnf.peer_macaddr.bytes));
- lim_send_disconnect_done_ind(pMac, psessionEntry,
+ status = lim_prepare_disconnect_done_ind(pMac, &msg,
sessionId,
eSIR_SME_INVALID_PARAMETERS,
- smeDisassocCnf.bssid.bytes);
+ &smeDisassocCnf.bssid.bytes[0]);
+ if (QDF_IS_STATUS_SUCCESS(status))
+ lim_send_sme_disassoc_deauth_ntf(pMac,
+ QDF_STATUS_SUCCESS,
+ (uint32_t *)msg);
return;
}
@@ -2371,9 +2395,14 @@
pe_err("No need of cleanup for addr:" MAC_ADDRESS_STR "as MLM state is %d",
MAC_ADDR_ARRAY(smeDisassocCnf.peer_macaddr.bytes),
pStaDs->mlmStaContext.mlmState);
- lim_send_disconnect_done_ind(pMac, NULL,
- CSR_SESSION_ID_INVALID,
- eSIR_SME_SUCCESS, NULL);
+ status = lim_prepare_disconnect_done_ind(pMac, &msg,
+ CSR_SESSION_ID_INVALID,
+ eSIR_SME_SUCCESS,
+ NULL);
+ if (QDF_IS_STATUS_SUCCESS(status))
+ lim_send_sme_disassoc_deauth_ntf(pMac,
+ QDF_STATUS_SUCCESS,
+ (uint32_t *)msg);
return;
}
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 900dff8..aa9a7e4 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
@@ -806,6 +806,7 @@
tpPESession session = NULL;
uint16_t i, assoc_id;
tpDphHashNode sta_ds = NULL;
+ QDF_STATUS status;
pe_debug("Disassoc Ntf with trigger : %d reasonCode: %d",
disassocTrigger, reasonCode);
@@ -893,9 +894,14 @@
case eLIM_PEER_ENTITY_DISASSOC:
case eLIM_LINK_MONITORING_DISASSOC:
- lim_send_disconnect_done_ind(pMac, psessionEntry, smesessionId,
- reasonCode, peerMacAddr);
- return;
+ status = lim_prepare_disconnect_done_ind(pMac, &pMsg,
+ smesessionId,
+ reasonCode, &peerMacAddr[0]);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ pe_err("Failed to prepare message");
+ return;
+ }
+ break;
default:
/**
@@ -1162,31 +1168,30 @@
#endif /* FEATURE_WLAN_TDLS */
-void lim_send_disconnect_done_ind(tpAniSirGlobal mac_ctx,
- tpPESession session_entry, uint8_t session_id,
- tSirResultCodes reason_code,
- tSirMacAddr peer_mac_addr)
+QDF_STATUS lim_prepare_disconnect_done_ind(tpAniSirGlobal mac_ctx,
+ uint32_t **msg,
+ uint8_t session_id,
+ tSirResultCodes reason_code,
+ uint8_t *peer_mac_addr)
{
struct sir_sme_discon_done_ind *sir_sme_dis_ind;
- uint32_t *msg;
- sir_sme_dis_ind =
- qdf_mem_malloc(sizeof(*sir_sme_dis_ind));
+ sir_sme_dis_ind = qdf_mem_malloc(sizeof(*sir_sme_dis_ind));
if (!sir_sme_dis_ind) {
- pe_err("call to AllocateMemory failed for disconnect indication");
- return;
+ pe_err("Failed to allocate memory");
+ return QDF_STATUS_E_FAILURE;
}
- pe_debug("send eWNI_SME_DISCONNECT_DONE_IND withretCode: %d",
+ pe_debug("Prepare eWNI_SME_DISCONNECT_DONE_IND withretCode: %d",
reason_code);
- sir_sme_dis_ind->message_type =
- eWNI_SME_DISCONNECT_DONE_IND;
- sir_sme_dis_ind->length =
- sizeof(*sir_sme_dis_ind);
+ sir_sme_dis_ind->message_type = eWNI_SME_DISCONNECT_DONE_IND;
+ sir_sme_dis_ind->length = sizeof(*sir_sme_dis_ind);
sir_sme_dis_ind->session_id = session_id;
- qdf_mem_copy(sir_sme_dis_ind->peer_mac, peer_mac_addr,
- ETH_ALEN);
+ if (peer_mac_addr)
+ qdf_mem_copy(&sir_sme_dis_ind->peer_mac,
+ &peer_mac_addr, ETH_ALEN);
+
/*
* Instead of sending deauth reason code as 505 which is
* internal value(eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE)
@@ -1197,14 +1202,9 @@
else
sir_sme_dis_ind->reason_code = reason_code;
- msg = (uint32_t *)sir_sme_dis_ind;
+ *msg = (uint32_t *)sir_sme_dis_ind;
- /*Delete the PE session created */
- if (session_entry)
- pe_delete_session(mac_ctx, session_entry);
-
- lim_send_sme_disassoc_deauth_ntf(mac_ctx, QDF_STATUS_SUCCESS,
- (uint32_t *)msg);
+ return QDF_STATUS_SUCCESS;
}
/**
@@ -1245,7 +1245,8 @@
tSirSmeDeauthInd *pSirSmeDeauthInd;
tpPESession psessionEntry;
uint8_t sessionId;
- uint32_t *pMsg;
+ uint32_t *pMsg = NULL;
+ QDF_STATUS status;
psessionEntry = pe_find_session_by_bssid(pMac, peerMacAddr, &sessionId);
switch (deauthTrigger) {
@@ -1281,9 +1282,14 @@
case eLIM_PEER_ENTITY_DEAUTH:
case eLIM_LINK_MONITORING_DEAUTH:
- lim_send_disconnect_done_ind(pMac, psessionEntry, smesessionId,
- reasonCode, peerMacAddr);
- return;
+ status = lim_prepare_disconnect_done_ind(pMac, &pMsg,
+ smesessionId, reasonCode,
+ &peerMacAddr[0]);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ pe_err("Failed to prepare message");
+ return;
+ }
+ break;
default:
/**
* Deauthentication indication due to Deauthentication
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h
index a6b9f85..33ec586 100644
--- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h
@@ -44,10 +44,23 @@
tpPESession, uint8_t, uint16_t);
void lim_send_sme_join_reassoc_rsp(tpAniSirGlobal, uint16_t, tSirResultCodes,
uint16_t, tpPESession, uint8_t, uint16_t);
-void lim_send_disconnect_done_ind(tpAniSirGlobal mac_ctx,
- tpPESession session_entry, uint8_t session_id,
- tSirResultCodes reason_code,
- tSirMacAddr peer_mac_addr);
+
+/*
+ * lim_prepare_disconnect_done_ind() - Prepares the disconnect done ind message
+ * @mac_ctx: Global mac_ctx
+ * @session_id: PE session id
+ * @reason_code: Disconnect indication reason code
+ * @peer_mac_addr: MAC address of the peer
+ *
+ * Prepares the disconnect done indication message to be sent to the upper layer
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS lim_prepare_disconnect_done_ind(tpAniSirGlobal mac_ctx,
+ uint32_t **msg,
+ uint8_t session_id,
+ tSirResultCodes reason_code,
+ uint8_t *peer_mac_addr);
void lim_send_sme_disassoc_ntf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes,
uint16_t, uint16_t, uint8_t, uint16_t, tpPESession);
void lim_send_sme_deauth_ntf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes, uint16_t,