/*
 * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
 *
 * 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.
 */

/*
 *
 * This file lim_process_disassoc_frame.cc contains the code
 * for processing Disassocation Frame.
 * Author:        Chandra Modumudi
 * Date:          03/24/02
 * History:-
 * Date           Modified by    Modification Information
 * --------------------------------------------------------------------
 *
 */
#include "cds_api.h"
#include "wni_api.h"
#include "sir_api.h"
#include "ani_global.h"
#include "wni_cfg.h"

#include "utils_api.h"
#include "lim_types.h"
#include "lim_utils.h"
#include "lim_assoc_utils.h"
#include "lim_security_utils.h"
#include "lim_ser_des_utils.h"
#include "lim_send_messages.h"
#include "sch_api.h"

/**
 * lim_process_disassoc_frame
 *
 ***FUNCTION:
 * This function is called by limProcessMessageQueue() upon
 * Disassociation frame reception.
 *
 ***LOGIC:
 *
 ***ASSUMPTIONS:
 * DPH drops packets for STA with 'valid' bit in pStaDs set to '0'.
 *
 ***NOTE:
 *
 * @param  mac - Pointer to Global MAC structure
 * @param  *pRxPacketInfo - A pointer to Rx packet info structure
 * @return None
 */
void
lim_process_disassoc_frame(struct mac_context *mac, uint8_t *pRxPacketInfo,
			   struct pe_session *pe_session)
{
	uint8_t *pBody;
	uint16_t aid, reasonCode;
	tpSirMacMgmtHdr pHdr;
	tpDphHashNode pStaDs;
	uint32_t frame_len;
	int32_t frame_rssi;

	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
	frame_len = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);

	frame_rssi = (int32_t)WMA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo);

	if (lim_is_group_addr(pHdr->sa)) {
		/* Received Disassoc frame from a BC/MC address */
		/* Log error and ignore it */
		pe_err("received Disassoc frame from a BC/MC address");
		return;
	}

	if (lim_is_group_addr(pHdr->da) && !lim_is_addr_bc(pHdr->da)) {
		/* Received Disassoc frame for a MC address */
		/* Log error and ignore it */
		pe_err("received Disassoc frame for a MC address");
		return;
	}
	if (!lim_validate_received_frame_a1_addr(mac,
			pHdr->da, pe_session)) {
		pe_err("rx frame doesn't have valid a1 address, drop it");
		return;
	}

	if (LIM_IS_STA_ROLE(pe_session) &&
		((eLIM_SME_WT_DISASSOC_STATE == pe_session->limSmeState) ||
		(eLIM_SME_WT_DEAUTH_STATE == pe_session->limSmeState))) {
		if (!(mac->lim.disassocMsgCnt & 0xF)) {
			pe_debug("received Disassoc frame in %s"
				"already processing previously received Disassoc frame, dropping this %d",
				 lim_sme_state_str(pe_session->limSmeState),
				 ++mac->lim.disassocMsgCnt);
		} else {
			mac->lim.disassocMsgCnt++;
		}
		return;
	}
#ifdef WLAN_FEATURE_11W
	/* PMF: If this session is a PMF session, then ensure that this frame was protected */
	if (pe_session->limRmfEnabled
	    && (WMA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) &
		DPU_FEEDBACK_UNPROTECTED_ERROR)) {
		pe_err("received an unprotected disassoc from AP");
		/*
		 * When 11w offload is enabled then
		 * firmware should not fwd this frame
		 */
		if (LIM_IS_STA_ROLE(pe_session) &&  mac->pmf_offload) {
			pe_err("11w offload is enable,unprotected disassoc is not expected");
			return;
		}

		/* If the frame received is unprotected, forward it to the supplicant to initiate */
		/* an SA query */
		/* send the unprotected frame indication to SME */
		lim_send_sme_unprotected_mgmt_frame_ind(mac, pHdr->fc.subType,
							(uint8_t *) pHdr,
							(frame_len +
							 sizeof(tSirMacMgmtHdr)),
							pe_session->smeSessionId,
							pe_session);
		return;
	}
#endif

	if (frame_len < 2) {
		pe_err("frame len less than 2");
		return;
	}

	/* Get reasonCode from Disassociation frame body */
	reasonCode = sir_read_u16(pBody);

	pe_debug("Received Disassoc frame for Addr: " MAC_ADDRESS_STR
		 "(mlm state=%s, sme state=%d RSSI=%d),"
		 "with reason code %d [%s] from " MAC_ADDRESS_STR,
		 MAC_ADDR_ARRAY(pHdr->da),
		 lim_mlm_state_str(pe_session->limMlmState),
		 pe_session->limSmeState, frame_rssi, reasonCode,
		 lim_dot11_reason_str(reasonCode), MAC_ADDR_ARRAY(pHdr->sa));
	lim_diag_event_report(mac, WLAN_PE_DIAG_DISASSOC_FRAME_EVENT,
		pe_session, 0, reasonCode);

	if (mac->mlme_cfg->gen.fatal_event_trigger &&
	    (reasonCode != eSIR_MAC_UNSPEC_FAILURE_REASON &&
	    reasonCode != eSIR_MAC_DEAUTH_LEAVING_BSS_REASON &&
	    reasonCode != eSIR_MAC_DISASSOC_LEAVING_BSS_REASON)) {
		cds_flush_logs(WLAN_LOG_TYPE_FATAL,
			       WLAN_LOG_INDICATOR_HOST_DRIVER,
			       WLAN_LOG_REASON_DISCONNECT,
			       false, false);
	}
	/**
	 * Extract 'associated' context for STA, if any.
	 * This is maintained by DPH and created by LIM.
	 */
	pStaDs =
		dph_lookup_hash_entry(mac, pHdr->sa, &aid,
				      &pe_session->dph.dphHashTable);

	if (pStaDs == NULL) {
		/**
		 * Disassociating STA is not associated.
		 * Log error.
		 */
		pe_err("received Disassoc frame from STA that does not have context"
			"reasonCode=%d, addr " MAC_ADDRESS_STR,
			reasonCode, MAC_ADDR_ARRAY(pHdr->sa));
		return;
	}

	if (lim_check_disassoc_deauth_ack_pending(mac, (uint8_t *) pHdr->sa)) {
		pe_err("Ignore the DisAssoc received, while waiting for ack of disassoc/deauth");
		lim_clean_up_disassoc_deauth_req(mac, (uint8_t *) pHdr->sa, 1);
		return;
	}

	if (mac->lim.disassocMsgCnt != 0) {
		mac->lim.disassocMsgCnt = 0;
	}

	/** If we are in the Wait for ReAssoc Rsp state */
	if (lim_is_reassoc_in_progress(mac, pe_session)) {
		/*
		 * For LFR3, the roaming bssid is not known during ROAM_START,
		 * so check if the disassoc is received from current AP when
		 * roaming is being done in the firmware
		 */
		if (pe_session->fw_roaming_started &&
		    IS_CURRENT_BSSID(mac, pHdr->sa, pe_session)) {
			pe_debug("Dropping disassoc frame from connected AP");
			pe_session->recvd_disassoc_while_roaming = true;
			pe_session->deauth_disassoc_rc = reasonCode;
			return;
		}
		/** If we had received the DisAssoc from,
		 *     a. the Current AP during ReAssociate to different AP in same ESS
		 *     b. Unknown AP
		 *   drop/ignore the DisAssoc received
		 */
		if (!IS_REASSOC_BSSID(mac, pHdr->sa, pe_session)) {
			pe_err("Ignore DisAssoc while Processing ReAssoc");
			return;
		}
		/** If the Disassoc is received from the new AP to which we tried to ReAssociate
		 *  Drop ReAssoc and Restore the Previous context( current connected AP).
		 */
		if (!IS_CURRENT_BSSID(mac, pHdr->sa, pe_session)) {
			pe_debug("received Disassoc from the New AP to which ReAssoc is sent");
			lim_restore_pre_reassoc_state(mac,
						      eSIR_SME_REASSOC_REFUSED,
						      reasonCode,
						      pe_session);
			return;
		}
	}

	if (LIM_IS_AP_ROLE(pe_session)) {
		switch (reasonCode) {
		case eSIR_MAC_UNSPEC_FAILURE_REASON:
		case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON:
		case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
		case eSIR_MAC_MIC_FAILURE_REASON:
		case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON:
		case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON:
		case eSIR_MAC_RSN_IE_MISMATCH_REASON:
		case eSIR_MAC_1X_AUTH_FAILURE_REASON:
			/* Valid reasonCode in received Disassociation frame */
			break;

		default:
			/* Invalid reasonCode in received Disassociation frame */
			pe_warn("received Disassoc frame with invalid reasonCode: %d from " MAC_ADDRESS_STR,
				reasonCode, MAC_ADDR_ARRAY(pHdr->sa));
			break;
		}
	} else if (LIM_IS_STA_ROLE(pe_session) &&
		   ((pe_session->limSmeState != eLIM_SME_WT_JOIN_STATE) &&
		   (pe_session->limSmeState != eLIM_SME_WT_AUTH_STATE) &&
		   (pe_session->limSmeState != eLIM_SME_WT_ASSOC_STATE) &&
		   (pe_session->limSmeState != eLIM_SME_WT_REASSOC_STATE))) {
		switch (reasonCode) {
		case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON:
		case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
			/* Valid reasonCode in received Disassociation frame */
			/* as long as we're not about to channel switch */
			if (pe_session->gLimChannelSwitch.state !=
			    eLIM_CHANNEL_SWITCH_IDLE) {
				pe_err("Ignoring disassoc frame due to upcoming channel switch, from "MAC_ADDRESS_STR,
					MAC_ADDR_ARRAY(pHdr->sa));
				return;
			}
			break;

		default:
			break;
		}
	} else {
		/* Received Disassociation frame in either IBSS */
		/* or un-known role. Log and ignore it */
		pe_err("received Disassoc frame with invalid reasonCode: %d in role:"
				"%d in sme state: %d from " MAC_ADDRESS_STR, reasonCode,
			GET_LIM_SYSTEM_ROLE(pe_session), pe_session->limSmeState,
			MAC_ADDR_ARRAY(pHdr->sa));

		return;
	}

	if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
	    (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE) ||
	    pStaDs->sta_deletion_in_progress) {
		/**
		 * Already in the process of deleting context for the peer
		 * and received Disassociation frame. Log and Ignore.
		 */
		pe_debug("Deletion is in progress (%d) for peer:%pM in mlmState %d",
			 pStaDs->sta_deletion_in_progress, pHdr->sa,
			 pStaDs->mlmStaContext.mlmState);
		return;
	}
	pStaDs->sta_deletion_in_progress = true;
	lim_disassoc_tdls_peers(mac, pe_session, pHdr->sa);
	if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) {
		/**
		 * Requesting STA is in some 'transient' state?
		 * Log error.
		 */
		if (pStaDs->mlmStaContext.mlmState ==
		    eLIM_MLM_WT_ASSOC_CNF_STATE)
			pStaDs->mlmStaContext.updateContext = 1;

		pe_err("received Disassoc frame from peer that is in state: %X, addr "MAC_ADDRESS_STR,
			pStaDs->mlmStaContext.mlmState,
			       MAC_ADDR_ARRAY(pHdr->sa));

	} /* if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) */

	lim_perform_disassoc(mac, frame_rssi, reasonCode,
			     pe_session, pHdr->sa);

} /*** end lim_process_disassoc_frame() ***/

#ifdef FEATURE_WLAN_TDLS
void lim_disassoc_tdls_peers(struct mac_context *mac_ctx,
				    struct pe_session *pe_session, tSirMacAddr addr)
{
	tpDphHashNode sta_ds;
	uint16_t aid;

	sta_ds = dph_lookup_hash_entry(mac_ctx, addr, &aid,
				       &pe_session->dph.dphHashTable);
	if (sta_ds == NULL) {
		pe_debug("Hash entry not found");
		return;
	}
	/**
	 *  Delete all the TDLS peers only if Disassoc is received
	 *  from the AP
	 */
	if ((LIM_IS_STA_ROLE(pe_session)) &&
	    ((sta_ds->mlmStaContext.mlmState ==
	      eLIM_MLM_LINK_ESTABLISHED_STATE) ||
	     (sta_ds->mlmStaContext.mlmState ==
	      eLIM_MLM_IDLE_STATE)) &&
	    (IS_CURRENT_BSSID(mac_ctx, addr, pe_session)))
		lim_delete_tdls_peers(mac_ctx, pe_session);
}
#endif

void lim_perform_disassoc(struct mac_context *mac_ctx, int32_t frame_rssi,
			  uint16_t rc, struct pe_session *pe_session, tSirMacAddr addr)
{
	tLimMlmDisassocInd mlmDisassocInd;
	uint16_t aid;
	tpDphHashNode sta_ds;

	sta_ds = dph_lookup_hash_entry(mac_ctx, addr, &aid,
				       &pe_session->dph.dphHashTable);
	if (sta_ds == NULL) {
		pe_debug("Hash entry not found");
		return;
	}
	sta_ds->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC;
	sta_ds->mlmStaContext.disassocReason = (tSirMacReasonCodes) rc;

	/* Issue Disassoc Indication to SME. */
	qdf_mem_copy((uint8_t *) &mlmDisassocInd.peerMacAddr,
			(uint8_t *) sta_ds->staAddr, sizeof(tSirMacAddr));
	mlmDisassocInd.reasonCode =
		(uint8_t) sta_ds->mlmStaContext.disassocReason;
	mlmDisassocInd.disassocTrigger = eLIM_PEER_ENTITY_DISASSOC;

	/* Update PE session Id  */
	mlmDisassocInd.sessionId = pe_session->peSessionId;

	if (lim_is_reassoc_in_progress(mac_ctx, pe_session)) {

		/* If we're in the middle of ReAssoc and received disassoc from
		 * the ReAssoc AP, then notify SME by sending REASSOC_RSP with
		 * failure result code. By design, SME will then issue "Disassoc"
		 * and cleanup will happen at that time.
		 */
		pe_debug("received Disassoc from AP while waiting for Reassoc Rsp");

		if (pe_session->limAssocResponseData) {
			qdf_mem_free(pe_session->limAssocResponseData);
			pe_session->limAssocResponseData = NULL;
		}

		lim_restore_pre_reassoc_state(mac_ctx, eSIR_SME_REASSOC_REFUSED,
				rc, pe_session);
		return;
	}

	lim_update_lost_link_info(mac_ctx, pe_session, frame_rssi);
	lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_IND,
			(uint32_t *) &mlmDisassocInd);

	/* send eWNI_SME_DISASSOC_IND to SME */
	lim_send_sme_disassoc_ind(mac_ctx, sta_ds, pe_session);

	return;
}
