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

/**
 * DOC: Implement parsing logic for action_oui strings, extract
 * extensions and store them using linked list. Functions defined in
 * this file can be accessed internally in action_oui component only.
 */

#include "wlan_action_oui_main.h"
#include "wlan_action_oui_public_struct.h"
#include "wlan_action_oui_tgt_api.h"
#include "target_if_action_oui.h"
#include <qdf_str.h>
#include <wlan_utility.h>

/**
 * action_oui_string_to_hex() - convert string to uint8_t hex array
 * @token - string to be converted
 * @hex - output string to hold converted string
 * @no_of_lengths - count of possible lengths for input string
 * @possible_lengths - array holding possible lengths
 *
 * This function converts the continuous input string of even length and
 * containing hexa decimal characters into hexa decimal array of uint8_t type.
 * Input string needs to be NULL terminated and the length should match with
 * one of entries in @possible_lengths
 *
 * Return: If conversion is successful return true else false
 */
static bool action_oui_string_to_hex(uint8_t *token, uint8_t *hex,
			      uint32_t no_of_lengths,
			      uint32_t *possible_lengths)
{
	uint32_t token_len = qdf_str_len(token);
	uint32_t hex_str_len;
	uint32_t i;
	int ret;

	if (!token_len || (token_len & 0x01)) {
		action_oui_err("Token len is not multiple of 2");
		return false;
	}

	for (i = 0; i < no_of_lengths; i++)
		if (token_len == possible_lengths[i])
			break;

	if (i == no_of_lengths) {
		action_oui_err("Token len doesn't match with expected len");
		return false;
	}

	hex_str_len = token_len / 2;

	ret = qdf_hex_str_to_binary(hex, token, hex_str_len);
	if (ret) {
		action_oui_err("Token doesn't contain hex digits");
		return false;
	}

	return true;
}

/**
 * action_oui_token_string() - converts enum value to string
 * token_id: enum value to be converted to string
 *
 * This function converts the enum value of type action_oui_token_type
 * to string
 *
 * Return: converted string
 */
static
uint8_t *action_oui_token_string(enum action_oui_token_type token_id)
{
	switch (token_id) {
		CASE_RETURN_STRING(ACTION_OUI_TOKEN);
		CASE_RETURN_STRING(ACTION_OUI_DATA_LENGTH_TOKEN);
		CASE_RETURN_STRING(ACTION_OUI_DATA_TOKEN);
		CASE_RETURN_STRING(ACTION_OUI_DATA_MASK_TOKEN);
		CASE_RETURN_STRING(ACTION_OUI_INFO_MASK_TOKEN);
		CASE_RETURN_STRING(ACTION_OUI_MAC_ADDR_TOKEN);
		CASE_RETURN_STRING(ACTION_OUI_MAC_MASK_TOKEN);
		CASE_RETURN_STRING(ACTION_OUI_CAPABILITY_TOKEN);
		CASE_RETURN_STRING(ACTION_OUI_END_TOKEN);
	}

	return (uint8_t *) "UNKNOWN";
}

/**
 * validate_and_convert_oui() - validate and convert OUI str to hex array
 * @token: OUI string
 * @ext: pointer to container which holds converted hex array
 * @action_token: next action to be parsed
 *
 * This is an internal function invoked from action_oui_parse to validate
 * the OUI string for action OUI inis, convert them to hex array and store it
 * in action_oui extension. After successful parsing update the
 * @action_token to hold the next expected string.
 *
 * Return: If conversion is successful return true else false
 */
static
bool validate_and_convert_oui(uint8_t *token,
			struct action_oui_extension *ext,
			enum action_oui_token_type *action_token)
{
	bool valid;
	uint32_t expected_token_len[2] = {6, 10};

	valid = action_oui_string_to_hex(token, ext->oui, 2,
					 expected_token_len);
	if (!valid)
		return false;

	ext->oui_length = qdf_str_len(token) / 2;

	*action_token = ACTION_OUI_DATA_LENGTH_TOKEN;

	return valid;
}

/**
 * validate_and_convert_data_length() - validate data len str
 * @token: data length string
 * @ext: pointer to container which holds hex value formed from input str
 * @action_token: next action to be parsed
 *
 * This is an internal function invoked from action_oui_parse to validate
 * the data length string for action OUI inis, convert it to hex value and
 * store it in action_oui extension. After successful parsing update the
 * @action_token to hold the next expected string.
 *
 * Return: If conversion is successful return true else false
 */
static bool
validate_and_convert_data_length(uint8_t *token,
				struct action_oui_extension *ext,
				enum action_oui_token_type *action_token)
{
	uint32_t token_len = qdf_str_len(token);
	int ret;
	uint8_t len = 0;

	if (token_len != 1 && token_len != 2) {
		action_oui_err("Invalid str token len for action OUI data len");
		return false;
	}

	ret = kstrtou8(token, 16, &len);
	if (ret) {
		action_oui_err("Invalid char in action OUI data len str token");
		return false;
	}

	if ((uint32_t)len > ACTION_OUI_MAX_DATA_LENGTH) {
		action_oui_err("action OUI data len is more than %u",
			ACTION_OUI_MAX_DATA_LENGTH);
		return false;
	}

	ext->data_length = len;

	if (!ext->data_length)
		*action_token = ACTION_OUI_INFO_MASK_TOKEN;
	else
		*action_token = ACTION_OUI_DATA_TOKEN;

	return true;
}

/**
 * validate_and_convert_data() - validate and convert data str to hex array
 * @token: data string
 * @ext: pointer to container which holds converted hex array
 * @action_token: next action to be parsed
 *
 * This is an internal function invoked from action_oui_parse to validate
 * the data string for action OUI inis, convert it to hex array and store in
 * action_oui extension. After successful parsing update the @action_token
 * to hold the next expected string.
 *
 * Return: If conversion is successful return true else false
 */
static bool
validate_and_convert_data(uint8_t *token,
			      struct action_oui_extension *ext,
			      enum action_oui_token_type *action_token)
{
	bool valid;
	uint32_t expected_token_len[1] = {2 * ext->data_length};

	valid = action_oui_string_to_hex(token, ext->data, 1,
					 expected_token_len);
	if (!valid)
		return false;

	*action_token = ACTION_OUI_DATA_MASK_TOKEN;

	return true;
}

/**
 * validate_and_convert_data_mask() - validate and convert data mask str
 * @token: data mask string
 * @ext: pointer to container which holds converted hex array
 * @action_token: next action to be parsed
 *
 * This is an internal function invoked from action_oui_parse to validate
 * the data mask string for action OUI inis, convert it to hex array and store
 * in action_oui extension. After successful parsing update the
 * @action_token to hold the next expected string.
 *
 * Return: If conversion is successful return true else false
 */
static bool
validate_and_convert_data_mask(uint8_t *token,
				   struct action_oui_extension *ext,
				   enum action_oui_token_type *action_token)
{
	bool valid;
	uint32_t expected_token_len[1];
	uint32_t data_mask_length;
	uint32_t data_length = ext->data_length;

	if (data_length % 8 == 0)
		data_mask_length = data_length / 8;
	else
		data_mask_length = ((data_length / 8) + 1);

	if (data_mask_length > ACTION_OUI_MAX_DATA_MASK_LENGTH)
		return false;

	expected_token_len[0] = 2 * data_mask_length;

	valid = action_oui_string_to_hex(token, ext->data_mask, 1,
				  expected_token_len);
	if (!valid)
		return false;

	ext->data_mask_length = data_mask_length;

	*action_token = ACTION_OUI_INFO_MASK_TOKEN;

	return valid;
}

/**
 * validate_and_convert_info_mask() - validate and convert info mask str
 * @token: info mask string
 * @ext: pointer to container which holds converted hex array
 * @action_token: next action to be parsed
 *
 * This is an internal function invoked from action_oui_parse to validate
 * the info mask string for action OUI inis, convert it to hex array and store
 * in action_oui extension. After successful parsing update the
 * @action_token to hold the next expected string.
 *
 * Return: If conversion is successful return true else false
 */
static bool
validate_and_convert_info_mask(uint8_t *token,
				   struct action_oui_extension *ext,
				   enum action_oui_token_type *action_token)
{
	uint32_t token_len = qdf_str_len(token);
	uint8_t hex_value = 0;
	uint32_t info_mask;
	int ret;

	if (token_len != 2) {
		action_oui_err("action OUI info mask str token len is not of 2 chars");
		return false;
	}

	ret = kstrtou8(token, 16, &hex_value);
	if (ret) {
		action_oui_err("Invalid char in action OUI info mask str token");
		return false;
	}

	info_mask = hex_value;

	info_mask |= ACTION_OUI_INFO_OUI;
	ext->info_mask = info_mask;

	if (!info_mask || !(info_mask & ~ACTION_OUI_INFO_OUI)) {
		*action_token = ACTION_OUI_END_TOKEN;
		return true;
	}

	if (info_mask & ~ACTION_OUI_INFO_MASK) {
		action_oui_err("Invalid bits are set in action OUI info mask");
		return false;
	}

	if (info_mask & ACTION_OUI_INFO_MAC_ADDRESS) {
		*action_token = ACTION_OUI_MAC_ADDR_TOKEN;
		return true;
	}

	*action_token = ACTION_OUI_CAPABILITY_TOKEN;
	return true;
}

/**
 * validate_and_convert_mac_addr() - validate and convert mac addr str
 * @token: mac address string
 * @ext: pointer to container which holds converted hex array
 * @action_token: next action to be parsed
 *
 * This is an internal function invoked from action_oui_parse to validate
 * the mac address string for action OUI inis, convert it to hex array and store
 * in action_oui extension. After successful parsing update the
 * @action_token to hold the next expected string.
 *
 * Return: If conversion is successful return true else false
 */
static bool
validate_and_convert_mac_addr(uint8_t *token,
				  struct action_oui_extension *ext,
				  enum action_oui_token_type *action_token)
{
	uint32_t expected_token_len[1] = {2 * QDF_MAC_ADDR_SIZE};
	bool valid;

	valid = action_oui_string_to_hex(token, ext->mac_addr, 1,
				  expected_token_len);
	if (!valid)
		return false;

	ext->mac_addr_length = QDF_MAC_ADDR_SIZE;

	*action_token = ACTION_OUI_MAC_MASK_TOKEN;

	return true;
}

/**
 * validate_and_convert_mac_mask() - validate and convert mac mask
 * @token: mac mask string
 * @ext: pointer to container which holds converted hex value
 * @action_token: next action to be parsed
 *
 * This is an internal function invoked from action_oui_parse to validate
 * the mac mask string for action OUI inis, convert it to hex value and store
 * in action_oui extension. After successful parsing update the
 * @action_token to hold the next expected string.
 *
 * Return: If conversion is successful return true else false
 */
static bool
validate_and_convert_mac_mask(uint8_t *token,
				  struct action_oui_extension *ext,
				  enum action_oui_token_type *action_token)
{
	uint32_t expected_token_len[1] = {2};
	uint32_t info_mask = ext->info_mask;
	bool valid;
	uint32_t mac_mask_length;

	valid = action_oui_string_to_hex(token, ext->mac_mask, 1,
				  expected_token_len);
	if (!valid)
		return false;

	mac_mask_length = qdf_str_len(token) / 2;
	if (mac_mask_length > ACTION_OUI_MAC_MASK_LENGTH) {
		action_oui_err("action OUI mac mask str token len is more than %u chars",
			expected_token_len[0]);
		return false;
	}

	ext->mac_mask_length = mac_mask_length;

	if ((info_mask & ACTION_OUI_INFO_AP_CAPABILITY_NSS) ||
	    (info_mask & ACTION_OUI_INFO_AP_CAPABILITY_HT) ||
	    (info_mask & ACTION_OUI_INFO_AP_CAPABILITY_VHT) ||
	    (info_mask & ACTION_OUI_INFO_AP_CAPABILITY_BAND)) {
		*action_token = ACTION_OUI_CAPABILITY_TOKEN;
		return true;
	}

	*action_token = ACTION_OUI_END_TOKEN;
	return true;
}

/**
 * validate_and_convert_capability() - validate and convert capability str
 * @token: capability string
 * @ext: pointer to container which holds converted hex value
 * @action_token: next action to be parsed
 *
 * This is an internal function invoked from action_oui_parse to validate
 * the capability string for action OUI inis, convert it to hex value and store
 * in action_oui extension. After successful parsing update the
 * @action_token to hold the next expected string.
 *
 * Return: If conversion is successful return true else false
 */
static bool
validate_and_convert_capability(uint8_t *token,
				struct action_oui_extension *ext,
				enum action_oui_token_type *action_token)
{
	uint32_t expected_token_len[1] = {2};
	uint32_t info_mask = ext->info_mask;
	uint32_t capability_length;
	uint8_t caps_0;
	bool valid;

	valid = action_oui_string_to_hex(token, ext->capability, 1,
				  expected_token_len);
	if (!valid)
		return false;

	capability_length = qdf_str_len(token) / 2;
	if (capability_length > ACTION_OUI_MAX_CAPABILITY_LENGTH) {
		action_oui_err("action OUI capability str token len is more than %u chars",
			expected_token_len[0]);
		return false;
	}

	caps_0 = ext->capability[0];

	if ((info_mask & ACTION_OUI_INFO_AP_CAPABILITY_NSS) &&
	    (!(caps_0 & ACTION_OUI_CAPABILITY_NSS_MASK))) {
		action_oui_err("Info presence for NSS is set but respective bits in capability are not set");
		return false;
	}

	if ((info_mask & ACTION_OUI_INFO_AP_CAPABILITY_BAND) &&
	    (!(caps_0 & ACTION_OUI_CAPABILITY_BAND_MASK))) {
		action_oui_err("Info presence for BAND is set but respective bits in capability are not set");
		return false;
	}

	ext->capability_length = capability_length;

	*action_token = ACTION_OUI_END_TOKEN;

	return true;
}

/**
 * action_oui_extension_store() - store action oui extension
 * @priv_obj: pointer to action_oui priv obj
 * @oui_priv: type of the action
 * @ext: oui extension to store in sme
 *
 * This function stores the parsed oui extension
 *
 * Return: QDF_STATUS
 *
 */
static QDF_STATUS
action_oui_extension_store(struct action_oui_psoc_priv *psoc_priv,
			   struct action_oui_priv *oui_priv,
			   struct action_oui_extension ext)
{
	struct action_oui_extension_priv *ext_priv;

	qdf_mutex_acquire(&oui_priv->extension_lock);
	if (qdf_list_size(&oui_priv->extension_list) ==
			  ACTION_OUI_MAX_EXTENSIONS) {
		qdf_mutex_release(&oui_priv->extension_lock);
		action_oui_err("Reached maximum OUI extensions");
		return QDF_STATUS_E_FAILURE;
	}

	ext_priv = qdf_mem_malloc(sizeof(*ext_priv));
	if (!ext_priv) {
		qdf_mutex_release(&oui_priv->extension_lock);
		action_oui_err("Failed to allocate memory for action oui extension priv");
		return QDF_STATUS_E_NOMEM;
	}

	ext_priv->extension = ext;
	qdf_list_insert_back(&oui_priv->extension_list, &ext_priv->item);
	psoc_priv->total_extensions++;
	qdf_mutex_release(&oui_priv->extension_lock);

	return QDF_STATUS_SUCCESS;
}

QDF_STATUS
action_oui_parse(struct action_oui_psoc_priv *psoc_priv,
		 uint8_t *oui_string, enum action_oui_id action_id)
{
	struct action_oui_extension ext = {0};
	enum action_oui_token_type action_token = ACTION_OUI_TOKEN;
	char *str1;
	char *str2;
	char *token;
	bool valid = true;
	bool oui_count_exceed = false;
	uint32_t oui_index = 0;
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	struct action_oui_priv *oui_priv;

	if (!oui_string) {
		action_oui_err("Invalid string for action oui: %u", action_id);
		return QDF_STATUS_E_INVAL;
	}

	oui_priv = psoc_priv->oui_priv[action_id];
	if (!oui_priv) {
		action_oui_err("action oui priv not allocated");
		return QDF_STATUS_E_INVAL;
	}

	str1 = qdf_str_trim((char *)oui_string);

	while (str1) {
		str2 = skip_spaces(str1);
		if (str2[0] == '\0') {
			action_oui_err("Invalid spaces in action oui: %u at extension: %u for token: %s",
				action_id,
				oui_index + 1,
				action_oui_token_string(action_token));
			valid = false;
			break;
		}

		token = strsep(&str2, " ");
		if (!token) {
			action_oui_err("Invalid string for token: %s at extension: %u in action oui: %u",
				action_oui_token_string(action_token),
				oui_index + 1, action_id);
			valid = false;
			break;
		}

		str1 = str2;

		switch (action_token) {

		case ACTION_OUI_TOKEN:
			valid = validate_and_convert_oui(token, &ext,
							 &action_token);
			break;

		case ACTION_OUI_DATA_LENGTH_TOKEN:
			valid = validate_and_convert_data_length(token, &ext,
								&action_token);
			break;

		case ACTION_OUI_DATA_TOKEN:
			valid = validate_and_convert_data(token, &ext,
							&action_token);
			break;

		case ACTION_OUI_DATA_MASK_TOKEN:
			valid = validate_and_convert_data_mask(token, &ext,
							&action_token);
			break;

		case ACTION_OUI_INFO_MASK_TOKEN:
			valid = validate_and_convert_info_mask(token, &ext,
							&action_token);
			break;

		case ACTION_OUI_MAC_ADDR_TOKEN:
			valid = validate_and_convert_mac_addr(token, &ext,
							&action_token);
			break;

		case ACTION_OUI_MAC_MASK_TOKEN:
			valid = validate_and_convert_mac_mask(token, &ext,
							&action_token);
			break;

		case ACTION_OUI_CAPABILITY_TOKEN:
			valid = validate_and_convert_capability(token, &ext,
							&action_token);
			break;

		default:
			valid = false;
			break;
		}

		if (!valid) {
			action_oui_err("Invalid string for token: %s at extension: %u in action oui: %u",
				action_oui_token_string(action_token),
				oui_index + 1,
				action_id);
			break;
		}

		if (action_token != ACTION_OUI_END_TOKEN)
			continue;

		status = action_oui_extension_store(psoc_priv, oui_priv, ext);
		if (!QDF_IS_STATUS_SUCCESS(status)) {
			valid = false;
			action_oui_err("sme set of extension: %u for action oui: %u failed",
				oui_index + 1, action_id);
			break;
		}

		oui_index++;
		if (oui_index == ACTION_OUI_MAX_EXTENSIONS) {
			if (str1)
				oui_count_exceed = true;
			break;
		}

		/* reset the params for next action OUI parse */
		action_token = ACTION_OUI_TOKEN;
		qdf_mem_zero(&ext, sizeof(ext));
	}

	if (oui_count_exceed) {
		action_oui_err("Reached Maximum extensions: %u in action_oui: %u, ignoring the rest",
			ACTION_OUI_MAX_EXTENSIONS, action_id);
		return QDF_STATUS_SUCCESS;
	}

	if (action_token != ACTION_OUI_TOKEN &&
	    action_token != ACTION_OUI_END_TOKEN &&
	    valid && !str1) {
		action_oui_err("No string for token: %s at extension: %u in action oui: %u",
			action_oui_token_string(action_token),
			oui_index + 1,
			action_id);
		valid = false;
	}

	if (!oui_index) {
		action_oui_err("Not able to parse any extension in action oui: %u",
			action_id);
		return QDF_STATUS_E_INVAL;
	}

	if (valid)
		action_oui_debug("All extensions: %u parsed successfully in action oui: %u",
			  oui_index, action_id);
	else
		action_oui_err("First %u extensions parsed successfully in action oui: %u",
			oui_index, action_id);

	return QDF_STATUS_SUCCESS;
}

QDF_STATUS action_oui_send(struct action_oui_psoc_priv *psoc_priv,
			enum action_oui_id action_id)
{
	QDF_STATUS status;
	struct action_oui_request *req;
	struct action_oui_priv *oui_priv;
	struct action_oui_extension *extension;
	struct action_oui_extension_priv *ext_priv;
	qdf_list_node_t *node = NULL;
	qdf_list_node_t *next_node = NULL;
	qdf_list_t *extension_list;
	uint32_t len;
	uint32_t no_oui_extensions;

	oui_priv = psoc_priv->oui_priv[action_id];
	if (!oui_priv)
		return QDF_STATUS_SUCCESS;

	extension_list = &oui_priv->extension_list;
	qdf_mutex_acquire(&oui_priv->extension_lock);
	if (qdf_list_empty(extension_list)) {
		qdf_mutex_release(&oui_priv->extension_lock);
		return QDF_STATUS_SUCCESS;
	}

	no_oui_extensions = qdf_list_size(extension_list);
	len = sizeof(*req) + no_oui_extensions * sizeof(*extension);
	req = qdf_mem_malloc(len);
	if (!req) {
		action_oui_err("Failed to allocate memory for action_oui");
		qdf_mutex_release(&oui_priv->extension_lock);
		return QDF_STATUS_E_NOMEM;
	}

	req->action_id = oui_priv->id;
	req->no_oui_extensions = no_oui_extensions;
	req->total_no_oui_extensions = psoc_priv->total_extensions;

	extension = req->extension;
	qdf_list_peek_front(extension_list, &node);
	while (node) {
		ext_priv = qdf_container_of(node,
					   struct action_oui_extension_priv,
					   item);
		*extension = ext_priv->extension;
		status = qdf_list_peek_next(extension_list, node,
						&next_node);
		if (!QDF_IS_STATUS_SUCCESS(status))
			break;
		node = next_node;
		next_node = NULL;
		extension++;
	}

	qdf_mutex_release(&oui_priv->extension_lock);

	status = tgt_action_oui_send(psoc_priv->psoc, req);
	qdf_mem_free(req);

	return status;
}

/**
 * check_for_vendor_oui_data() - compares for vendor OUI data from IE
 * and returns true if OUI data matches with the ini
 * @extension: pointer to action oui extension data
 * @oui_ptr: pointer to Vendor IE in the beacon
 *
 * Return: true or false
 */
static bool
check_for_vendor_oui_data(struct action_oui_extension *extension,
			  const uint8_t *oui_ptr)
{
	const uint8_t *data;
	uint8_t i, j, elem_len, data_len;
	uint8_t data_mask = 0x80;

	elem_len = oui_ptr[1];
	if (elem_len < extension->oui_length)
		return false;

	data_len = elem_len - extension->oui_length;
	if (data_len < extension->data_length)
		return false;

	data = &oui_ptr[2 + extension->oui_length];
	for (i = 0, j = 0;
	     (i < data_len && j < extension->data_mask_length);
	     i++) {
		if ((extension->data_mask[j] & data_mask) &&
		    !(extension->data[i] == data[i]))
			return false;
		data_mask = data_mask >> 1;
		if (!data_mask) {
			data_mask = 0x80;
			j++;
		}
	}

	return true;
}

/**
 * check_for_vendor_ap_mac() - compares for vendor AP MAC in the ini with
 * bssid from the session and returns true if matches
 * @extension: pointer to action oui extension data
 * @attr: pointer to structure containing mac_addr (bssid) of AP
 *
 * Return: true or false
 */
static bool
check_for_vendor_ap_mac(struct action_oui_extension *extension,
			struct action_oui_search_attr *attr)
{
	uint8_t i;
	uint8_t mac_mask = 0x80;
	uint8_t *mac_addr = attr->mac_addr;

	for (i = 0; i < QDF_MAC_ADDR_SIZE; i++) {
		if ((*extension->mac_mask & mac_mask) &&
		    !(extension->mac_addr[i] == mac_addr[i]))
			return false;
		mac_mask = mac_mask >> 1;
	}

	return true;
}

/**
 * check_for_vendor_ap_capabilities() - Compares various Vendor AP
 * capabilities like NSS, HT, VHT, Band from the ini with the AP's capability
 * from the beacon and returns true if all the capability matches
 * @extension: pointer to oui extension data
 * @attr: pointer to structure containing type of action, ap capabilities
 *
 * Return: true or false
 */
static bool
check_for_vendor_ap_capabilities(struct action_oui_extension *extension,
				 struct action_oui_search_attr *attr)
{
	uint8_t nss_mask;

	if (extension->info_mask & ACTION_OUI_INFO_AP_CAPABILITY_NSS) {
		nss_mask = 1 << (attr->nss - 1);
		if (!((*extension->capability &
		    ACTION_OUI_CAPABILITY_NSS_MASK) &
		    nss_mask))
		return false;
	}

	if (extension->info_mask & ACTION_OUI_INFO_AP_CAPABILITY_HT) {
		if (*extension->capability &
		    ACTION_OUI_CAPABILITY_HT_ENABLE_MASK) {
			if (!attr->ht_cap)
				return false;
		} else {
			if (attr->ht_cap)
				return false;
		}
	}

	if (extension->info_mask & ACTION_OUI_INFO_AP_CAPABILITY_VHT) {
		if (*extension->capability &
		    ACTION_OUI_CAPABILITY_VHT_ENABLE_MASK) {
			if (!attr->vht_cap)
				return false;
		} else {
			if (attr->vht_cap)
				return false;
		}
	}

	if (extension->info_mask & ACTION_OUI_INFO_AP_CAPABILITY_BAND) {
		if ((*extension->capability &
		    ACTION_OUI_CAPABILITY_2G_BAND_MASK) &&
		    !attr->enable_2g)
			return false;
		if ((*extension->capability &
		    ACTION_CAPABILITY_5G_BAND_MASK) &&
		    !attr->enable_5g)
			return false;
	}

	return true;
}

bool
action_oui_search(struct action_oui_psoc_priv *psoc_priv,
		  struct action_oui_search_attr *attr,
		  enum action_oui_id action_id)
{
	struct action_oui_priv *oui_priv;
	struct action_oui_extension_priv *priv_ext;
	struct action_oui_extension *extension;
	qdf_list_node_t *node = NULL;
	qdf_list_node_t *next_node = NULL;
	qdf_list_t *extension_list;
	QDF_STATUS qdf_status;
	const uint8_t *oui_ptr;

	oui_priv = psoc_priv->oui_priv[action_id];
	if (!oui_priv) {
		action_oui_debug("action oui for id %d is empty",
				 action_id);
		return false;
	}

	extension_list = &oui_priv->extension_list;
	qdf_mutex_acquire(&oui_priv->extension_lock);
	if (qdf_list_empty(extension_list)) {
		qdf_mutex_release(&oui_priv->extension_lock);
		action_oui_debug("OUI List Empty");
		return false;
	}

	qdf_list_peek_front(extension_list, &node);
	while (node) {
		priv_ext = qdf_container_of(node,
					   struct action_oui_extension_priv,
					   item);
		extension = &priv_ext->extension;
		oui_ptr = wlan_get_vendor_ie_ptr_from_oui(extension->oui,
							 extension->oui_length,
							 attr->ie_data,
							 attr->ie_length);
		if (!oui_ptr) {
			action_oui_debug("No matching IE found for OUI");
			QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
					   QDF_TRACE_LEVEL_DEBUG,
					   extension->oui,
					   extension->oui_length);
			goto next;
		}

		action_oui_debug("IE found for OUI");
		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
				   QDF_TRACE_LEVEL_DEBUG,
				   extension->oui,
				   extension->oui_length);

		if (extension->data_length &&
		    !check_for_vendor_oui_data(extension, oui_ptr)) {
			action_oui_debug("Vendor IE Data mismatch");
			goto next;
		}

		if ((extension->info_mask & ACTION_OUI_INFO_MAC_ADDRESS) &&
		    !check_for_vendor_ap_mac(extension, attr)) {
			action_oui_debug("Vendor IE MAC Mismatch");
			goto next;
		}

		if (!check_for_vendor_ap_capabilities(extension, attr)) {
			action_oui_debug("Vendor IE capabilties mismatch");
			goto next;
		}

		action_oui_debug("Vendor AP found for OUI");
		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
				   extension->oui, extension->oui_length);
		qdf_mutex_release(&oui_priv->extension_lock);
		return true;
next:
		qdf_status = qdf_list_peek_next(extension_list,
						node, &next_node);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
			break;

		node = next_node;
		next_node = NULL;
	}

	qdf_mutex_release(&oui_priv->extension_lock);
	return false;
}
