/*
 * Copyright (c) 2011-2015 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.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/** ------------------------------------------------------------------------- *
    ------------------------------------------------------------------------- *
    \file csr_cmd_process.c

    Implementation for processing various commands.
   ========================================================================== */

#include "ani_global.h"

#include "csr_inside_api.h"
#include "sme_inside.h"
#include "sms_debug.h"
#include "mac_trace.h"

/**
 * csr_msg_processor() - To process all csr msg
 * @mac_ctx: mac context
 * @msg_buf: message buffer
 *
 * This routine will handle all the message for csr to process
 *
 * Return: CDF_STATUS
 */
CDF_STATUS csr_msg_processor(tpAniSirGlobal mac_ctx, void *msg_buf)
{
	CDF_STATUS status = CDF_STATUS_SUCCESS;
	tSirSmeRsp *sme_rsp = (tSirSmeRsp *) msg_buf;
#ifdef FEATURE_WLAN_SCAN_PNO
	tSirMbMsg *msg = (tSirMbMsg *) msg_buf;
	tCsrRoamSession *session;
#endif
	uint8_t session_id = sme_rsp->sessionId;
	eCsrRoamState cur_state = mac_ctx->roam.curState[session_id];

	sms_log(mac_ctx, LOG2,
		FL("msg %d[0x%04X] recvd in curstate %s & substate %s id(%d)"),
		sme_rsp->messageType, sme_rsp->messageType,
		mac_trace_getcsr_roam_state(cur_state),
		mac_trace_getcsr_roam_sub_state(
			mac_ctx->roam.curSubState[session_id]),
		session_id);

#ifdef FEATURE_WLAN_SCAN_PNO
	/*
	 * PNO scan responses have to be handled irrespective of CSR roam state.
	 * Check if PNO has been started & only then process the PNO scan result
	 * Also note that normal scan isn't allowed when PNO scan is in progress
	 * and so the scan responses reaching here when PNO is started must be
	 * PNO responses. For normal scan, the PNO started flag will be false
	 * and it'll be processed as usual based on the current CSR roam state.
	 */
	session = CSR_GET_SESSION(mac_ctx, session_id);
	if (!session) {
		sms_log(mac_ctx, LOGE, FL("session %d not found, msgType : %d"),
			session_id, msg->type);
		return CDF_STATUS_E_FAILURE;
	}

	if (eWNI_SME_SCAN_RSP == msg->type) {
		status = csr_scanning_state_msg_processor(mac_ctx, msg_buf);
		if (CDF_STATUS_SUCCESS != status)
			sms_log(mac_ctx, LOGE,
				FL("handling PNO scan resp 0x%X CSR state %d"),
				sme_rsp->messageType, cur_state);
		return status;
	}
#endif

	/* Process the message based on the state of the roaming states... */
#if defined(ANI_RTT_DEBUG)
	if (!pAdapter->fRttModeEnabled) {
#endif
		switch (cur_state) {
		case eCSR_ROAMING_STATE_JOINED:
			/* are we in joined state */
			csr_roam_joined_state_msg_processor(mac_ctx, msg_buf);
			break;
		case eCSR_ROAMING_STATE_JOINING:
			/* are we in roaming states */
#if defined(ANI_EMUL_ASSOC)
			emulRoamingStateMsgProcessor(pAdapter, pMBBufHdr);
#endif
			csr_roaming_state_msg_processor(mac_ctx, msg_buf);
			break;

		default:
			/*
			 * For all other messages, we ignore it
			 * To work-around an issue where checking for set/remove
			 * key base on connection state is no longer workable
			 * due to failure or finding the condition meets both
			 * SAP and infra/IBSS requirement.
			 */
			if (eWNI_SME_SETCONTEXT_RSP == sme_rsp->messageType) {
				sms_log(mac_ctx, LOGW,
					FL("handling msg 0x%X CSR state is %d"),
					sme_rsp->messageType, cur_state);
				csr_roam_check_for_link_status_change(mac_ctx,
						sme_rsp);
			} else if (eWNI_SME_GET_RSSI_REQ ==
					sme_rsp->messageType) {
				tAniGetRssiReq *pGetRssiReq =
					(tAniGetRssiReq *) msg_buf;
				if (NULL == pGetRssiReq->rssiCallback) {
					sms_log(mac_ctx, LOGE,
						FL("rssiCallback is NULL"));
					return status;
				}
				sms_log(mac_ctx, LOGW,
						FL("msg eWNI_SME_GET_RSSI_REQ is not handled by CSR in state %d. calling RSSI callback"),
						cur_state);
				((tCsrRssiCallback)(pGetRssiReq->rssiCallback))(
						pGetRssiReq->lastRSSI,
						pGetRssiReq->staId,
						pGetRssiReq->pDevContext);
			} else {
				sms_log(mac_ctx, LOGE,
					FL("Message 0x%04X is not handled by CSR state is %d session Id %d"),
					sme_rsp->messageType, cur_state,
					session_id);

				if (eWNI_SME_FT_PRE_AUTH_RSP ==
						sme_rsp->messageType) {
					sms_log(mac_ctx, LOGE,
						FL("Dequeue eSmeCommandRoam command with reason eCsrPerformPreauth"));
					csr_dequeue_roam_command(mac_ctx,
						eCsrPerformPreauth);
				} else if (eWNI_SME_REASSOC_RSP ==
						sme_rsp->messageType) {
					sms_log(mac_ctx, LOGE,
						FL("Dequeue eSmeCommandRoam command with reason eCsrSmeIssuedFTReassoc"));
					csr_dequeue_roam_command(mac_ctx,
						eCsrSmeIssuedFTReassoc);
				}
			}
			break;
		} /* switch */
#if defined(ANI_RTT_DEBUG)
	}
#endif
	return status;
}

bool csr_check_ps_ready(void *pv)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(pv);

	if (pMac->roam.sPendingCommands < 0) {
		CDF_ASSERT(pMac->roam.sPendingCommands >= 0);
		return 0;
	}
	return pMac->roam.sPendingCommands == 0;
}

bool csr_check_ps_offload_ready(void *pv, uint32_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(pv);

	CDF_ASSERT(pMac->roam.sPendingCommands >= 0);
	return pMac->roam.sPendingCommands == 0;
}

