diff options
| author | Kondabattini, Ganesh <ganeshk@codeaurora.org> | 2016-09-13 12:23:47 +0530 |
|---|---|---|
| committer | Nishank Aggarwal <naggar@codeaurora.org> | 2016-09-16 21:06:35 +0530 |
| commit | 3f2d02cd32269e37a02215fa247e3c914bbaa6f3 (patch) | |
| tree | 9f7c75f19ed699d3af2efbb90672129814a8218a | |
| parent | b3bfefd6e10016326dca07e1f38565d28497b400 (diff) | |
qcacld-3.0: Fix to send the deauthentication frame from HDD
qcacld-2.0 to qcacld-3.0 propagation
Currently, On sending disassoc from HDD lim will process
disassoc and clear's session of station and thus leading to
drop deauth in lim since context is already cleared. Hence
deauth frame is not sent from SoftAP although deauth command
is executed on hostapd_cli.
Fix will ensure to send disassoc command through new API
and doesn't clear's session and the same is cleared after
sending deauth.
Change-Id: I912a91f1df4001bb2d4f1f0d6031cc102d1bbd65
CRs-Fixed: 981121
| -rw-r--r-- | core/hdd/src/wlan_hdd_cfg80211.c | 5 | ||||
| -rw-r--r-- | core/mac/inc/sir_api.h | 20 | ||||
| -rw-r--r-- | core/mac/inc/wni_api.h | 1 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_process_message_queue.c | 5 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_process_sme_req_messages.c | 70 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_ser_des_utils.c | 77 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_ser_des_utils.h | 6 | ||||
| -rw-r--r-- | core/sme/inc/sme_api.h | 3 | ||||
| -rw-r--r-- | core/sme/src/common/sme_api.c | 66 |
9 files changed, 248 insertions, 5 deletions
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index e4e93f4b69d7..7b646d43cbd5 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -12608,7 +12608,10 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, goto fn_end; qdf_event_reset(&hapd_state->qdf_event); - hdd_softap_sta_disassoc(pAdapter, pDelStaParams); + sme_send_disassoc_req_frame(WLAN_HDD_GET_HAL_CTX + (pAdapter), pAdapter->sessionId, + (uint8_t *)&pDelStaParams->peerMacAddr, + pDelStaParams->reason_code, 0); qdf_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index de874747c7bd..b20231a000ea 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -6432,4 +6432,24 @@ struct sir_mac_pwr_dbg_cmd { uint32_t args[MAX_POWER_DBG_ARGS_SUPPORTED]; }; +/** + * struct sme_send_disassoc_frm_req - send disassoc request frame + * @msg_type: message type + * @length: length of message + * @session_id: session id + * @trans_id: transaction id + * @peer_mac: peer mac address + * @reason: reason for disassoc + * @wait_for_ack: wait for acknowledgment + **/ + struct sme_send_disassoc_frm_req { + uint16_t msg_type; + uint16_t length; + uint8_t session_id; + uint16_t trans_id; + uint8_t peer_mac[6]; + uint16_t reason; + uint8_t wait_for_ack; + }; + #endif /* __SIR_API_H */ diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index 3703f9380d6c..0798123d3607 100644 --- a/core/mac/inc/wni_api.h +++ b/core/mac/inc/wni_api.h @@ -261,6 +261,7 @@ enum eWniMsgTypes { eWNI_SME_NDP_PEER_DEPARTED_IND, eWNI_SME_NDP_END_IND, eWNI_SME_REGISTER_P2P_ACK_CB, + eWNI_SME_SEND_DISASSOC_FRAME, eWNI_SME_MSG_TYPES_END }; diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index 617426663371..e7820b1d89d3 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -1364,7 +1364,10 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) /* These messages are from HDD. Need to respond to HDD */ lim_process_normal_hdd_msg(mac_ctx, msg, true); break; - + case eWNI_SME_SEND_DISASSOC_FRAME: + /* Need to response to hdd */ + lim_process_normal_hdd_msg(mac_ctx, msg, true); + break; case eWNI_SME_SCAN_ABORT_IND: req_msg = msg->bodyptr; if (req_msg) { 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 a5e8d810631b..cc4e317fa802 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 @@ -90,6 +90,8 @@ static void __lim_process_sme_disassoc_cnf(tpAniSirGlobal, uint32_t *); static void __lim_process_sme_deauth_req(tpAniSirGlobal, uint32_t *); static void __lim_process_sme_set_context_req(tpAniSirGlobal, uint32_t *); static bool __lim_process_sme_stop_bss_req(tpAniSirGlobal, tpSirMsgQ pMsg); +static void __lim_process_send_disassoc_frame(tpAniSirGlobal mac_ctx, + uint32_t *msg_buf); static void lim_process_sme_channel_change_request(tpAniSirGlobal pMac, uint32_t *pMsg); static void lim_process_sme_start_beacon_req(tpAniSirGlobal pMac, uint32_t *pMsg); @@ -120,7 +122,6 @@ extern void pe_register_callbacks_with_wma(tpAniSirGlobal pMac, static void lim_process_ext_change_channel(tpAniSirGlobal mac_ctx, uint32_t *msg); - /** * lim_process_set_hw_mode() - Send set HW mode command to WMA * @mac: Globacl MAC pointer @@ -4763,6 +4764,69 @@ static void lim_register_mgmt_frame_ind_cb(tpAniSirGlobal mac_ctx, } /** + *__lim_process_send_disassoc_frame: function processes disassoc frame + * @mac_ctx: pointer to mac context + * @msg_buf: message buffer + * + * function processes disassoc request received from SME + * + * return: none + */ +static void __lim_process_send_disassoc_frame(tpAniSirGlobal mac_ctx, + uint32_t *msg_buf) +{ + struct sme_send_disassoc_frm_req sme_send_disassoc_frame_req; + tSirRetStatus status; + tpPESession session_entry = NULL; + uint8_t sme_session_id; + uint16_t sme_trans_id; + + if (msg_buf == NULL) { + lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL")); + return; + } + + lim_get_session_info(mac_ctx, (uint8_t *)msg_buf, &sme_session_id, + &sme_trans_id); + + status = lim_send_disassoc_frm_req_ser_des(mac_ctx, + &sme_send_disassoc_frame_req, + (uint8_t *)msg_buf); + + if ((eSIR_FAILURE == status) || + (lim_is_group_addr(sme_send_disassoc_frame_req.peer_mac) && + !lim_is_addr_bc(sme_send_disassoc_frame_req.peer_mac))) { + PELOGE(lim_log(mac_ctx, LOGE, + FL("received invalid SME_DISASSOC_REQ message"));) + return; + } + + session_entry = pe_find_session_by_sme_session_id( + mac_ctx, sme_session_id); + if (session_entry == NULL) { + lim_log(mac_ctx, LOGE, + FL("session does not exist for given bssId "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(sme_send_disassoc_frame_req.peer_mac)); + return; + } + + lim_log(mac_ctx, LOG1, + FL("msg_type->%d len->%d sess_id->%d trans_id->%d mac->"MAC_ADDRESS_STR" reason->%d wait_for_ack->%d"), + sme_send_disassoc_frame_req.msg_type, + sme_send_disassoc_frame_req.length, + sme_send_disassoc_frame_req.session_id, + sme_send_disassoc_frame_req.trans_id, + MAC_ADDR_ARRAY(sme_send_disassoc_frame_req.peer_mac), + sme_send_disassoc_frame_req.reason, + sme_send_disassoc_frame_req.wait_for_ack); + + lim_send_disassoc_mgmt_frame(mac_ctx, + sme_send_disassoc_frame_req.reason, + sme_send_disassoc_frame_req.peer_mac, + session_entry, sme_send_disassoc_frame_req.wait_for_ack); +} + +/** * lim_set_pdev_ht_ie() - sends the set HT IE req to FW * @mac_ctx: Pointer to Global MAC structure * @pdev_id: pdev id to set the IE. @@ -5031,6 +5095,10 @@ bool lim_process_sme_req_messages(tpAniSirGlobal pMac, tpSirMsgQ pMsg) __lim_process_sme_deauth_req(pMac, pMsgBuf); break; + case eWNI_SME_SEND_DISASSOC_FRAME: + __lim_process_send_disassoc_frame(pMac, pMsgBuf); + break; + case eWNI_SME_SETCONTEXT_REQ: __lim_process_sme_set_context_req(pMac, pMsgBuf); break; diff --git a/core/mac/src/pe/lim/lim_ser_des_utils.c b/core/mac/src/pe/lim/lim_ser_des_utils.c index bd778f55cc90..55da544f7a64 100644 --- a/core/mac/src/pe/lim/lim_ser_des_utils.c +++ b/core/mac/src/pe/lim/lim_ser_des_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2015,2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -43,6 +43,7 @@ #include "lim_utils.h" #include "lim_ser_des_utils.h" + /**--------------------------------------------------------------- \fn lim_get_session_info \brief This function returns the sessionId and transactionId @@ -76,3 +77,77 @@ lim_get_session_info(tpAniSirGlobal pMac, uint8_t *pBuf, uint8_t *sessionId, return; } + +/** + * lim_send_disassoc_frm_req_ser_des - called on receiving SME_DISASSOC_REQ + * @mac_ctx: pointer to mac context + * @disassoc_frm_req: pointer to structure sme_send_disassoc_frm_req + * + * function send's disassoc frame request on receiving SME_DISASSOC_REQ + * + * return: eSIR_SUCCESS:Success Error value: Failure + */ +tSirRetStatus lim_send_disassoc_frm_req_ser_des(tpAniSirGlobal mac_ctx, + struct sme_send_disassoc_frm_req *disassoc_frm_req, + uint8_t *buf) +{ + A_INT16 len = 0; + + if (!disassoc_frm_req || !buf) + return eSIR_FAILURE; + + disassoc_frm_req->msg_type = lim_get_u16(buf); + buf += sizeof(A_UINT16); + + len = disassoc_frm_req->length = lim_get_u16(buf); + buf += sizeof(A_UINT16); + + PELOG1(lim_log(mac_ctx, LOG1, + FL("SME_DISASSOC_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(mac_ctx, SIR_LIM_MODULE_ID, LOG1, buf, len);) + + if (len < (A_INT16) sizeof(A_UINT32)) + return eSIR_FAILURE; + + /* skip message header */ + len -= sizeof(A_UINT32); + if (len < 0) + return eSIR_FAILURE; + + /* Extract sessionID */ + disassoc_frm_req->session_id = *buf; + buf += sizeof(A_UINT8); + len -= sizeof(A_UINT8); + if (len < 0) + return eSIR_FAILURE; + + /* Extract transactionid */ + disassoc_frm_req->trans_id = lim_get_u16(buf); + buf += sizeof(A_UINT16); + len -= sizeof(A_UINT16); + + if (len < 0) + return eSIR_FAILURE; + + /* Extract peerMacAddr */ + qdf_mem_copy(disassoc_frm_req->peer_mac, buf, sizeof(tSirMacAddr)); + buf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + + if (len < 0) + return eSIR_FAILURE; + + /* Extract reasonCode */ + disassoc_frm_req->reason = lim_get_u16(buf); + buf += sizeof(A_UINT16); + len -= sizeof(A_UINT16); + + if (len < 0) + return eSIR_FAILURE; + + disassoc_frm_req->wait_for_ack = *buf; + buf += sizeof(A_UINT8); + len -= sizeof(A_UINT8); + + return eSIR_SUCCESS; +} diff --git a/core/mac/src/pe/lim/lim_ser_des_utils.h b/core/mac/src/pe/lim/lim_ser_des_utils.h index f05f4ddd0a9e..82b9c48cf7f5 100644 --- a/core/mac/src/pe/lim/lim_ser_des_utils.h +++ b/core/mac/src/pe/lim/lim_ser_des_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2015,2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -95,4 +95,8 @@ static inline uint32_t lim_get_u32(uint8_t *ptr) #endif } +tSirRetStatus lim_send_disassoc_frm_req_ser_des(tpAniSirGlobal mac_ctx, + struct sme_send_disassoc_frm_req *disassoc_frm_req, + uint8_t *buf); + #endif /* __LIM_SERDES_UTILS_H */ diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 1d98b854018a..b3539fa98e89 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1161,4 +1161,7 @@ QDF_STATUS sme_roam_set_default_key_index(tHalHandle hal, uint8_t session_id, uint8_t default_idx); QDF_STATUS sme_register_p2p_ack_ind_callback(tHalHandle hal, sir_p2p_ack_ind_callback callback); +void sme_send_disassoc_req_frame(tHalHandle hal, uint8_t session_id, uint8_t + *peer_mac, uint16_t reason, uint8_t + wait_for_ack); #endif /* #if !defined( __SME_API_H ) */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 9cc8a1e35327..5175ad1e333b 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -15823,6 +15823,72 @@ QDF_STATUS sme_remove_beacon_filter(tHalHandle hal, uint32_t session_id) } /** + * sme_send_disassoc_req_frame - send disassoc req + * @hal: handler to hal + * @session_id: session id + * @peer_mac: peer mac address + * @reason: reason for disassociation + * wait_for_ack: wait for acknowledgment + * + * function to send disassoc request to lim + * + * return: none + */ +void sme_send_disassoc_req_frame(tHalHandle hal, uint8_t session_id, + uint8_t *peer_mac, uint16_t reason, uint8_t wait_for_ack) +{ + struct sme_send_disassoc_frm_req *msg; + QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; + A_UINT8 *buf; + A_UINT16 tmp; + + msg = qdf_mem_malloc(sizeof(struct sme_send_disassoc_frm_req)); + + if (NULL == msg) + qdf_status = QDF_STATUS_E_FAILURE; + else + qdf_status = QDF_STATUS_SUCCESS; + + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) + return; + + qdf_mem_set(msg, sizeof(struct sme_send_disassoc_frm_req), 0); + msg->msg_type = (uint16_t) eWNI_SME_SEND_DISASSOC_FRAME; + + msg->length = (uint16_t) sizeof(struct sme_send_disassoc_frm_req); + + buf = &msg->session_id; + + /* session id */ + *buf = (A_UINT8) session_id; + buf += sizeof(A_UINT8); + + /* transaction id */ + *buf = 0; + *(buf + 1) = 0; + buf += sizeof(A_UINT16); + + /* Set the peer MAC address before sending the message to LIM */ + qdf_mem_copy(buf, peer_mac, QDF_MAC_ADDR_SIZE); + + buf += QDF_MAC_ADDR_SIZE; + + /* reasoncode */ + tmp = (uint16_t) reason; + qdf_mem_copy(buf, &tmp, sizeof(uint16_t)); + buf += sizeof(uint16_t); + + *buf = wait_for_ack; + buf += sizeof(uint8_t); + + qdf_status = cds_send_mb_message_to_mac(msg); + + if (qdf_status != QDF_STATUS_SUCCESS) + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("cds_send_mb_message Failed")); +} + +/** * sme_get_bpf_offload_capabilities() - Get length for BPF offload * @hal: Global HAL handle * This function constructs the cds message and fill in message type, |
