DivestOS/Patches/Linux_CVEs/CVE-2017-11022/qcacld-3.0/0002.patch
2017-11-07 18:55:10 -05:00

1298 lines
43 KiB
Diff

From f41e3dbc92d448d3d56cae5517e41a4bafafdf3f Mon Sep 17 00:00:00 2001
From: Rajeev Kumar Sirasanagandla <rsirasan@codeaurora.org>
Date: Tue, 3 Jan 2017 00:22:10 +0530
Subject: qcacld-3.0: Add support to include selective scan IEs only
qcacld-2.0 to qcacld-3.0 propagation
Add support to include only selective IEs in probe requests in
order to improve user's privacy.
Change-Id: Ib874af7ec2f5453282ffe0e8fc2e50934460b745
CRs-Fixed: 1086582
---
core/hdd/inc/wlan_hdd_cfg.h | 313 +++++++++++++++++++++
core/hdd/inc/wlan_hdd_main.h | 5 +
core/hdd/src/wlan_hdd_cfg.c | 283 ++++++++++++++++++-
core/hdd/src/wlan_hdd_cfg80211.c | 14 +-
core/hdd/src/wlan_hdd_main.c | 18 ++
core/hdd/src/wlan_hdd_power.c | 2 +
core/hdd/src/wlan_hdd_scan.c | 76 ++++-
core/hdd/src/wlan_hdd_scan.h | 21 +-
core/mac/inc/sir_api.h | 35 ++-
core/mac/src/pe/lim/lim_process_sme_req_messages.c | 24 +-
core/sme/inc/csr_api.h | 6 +
core/sme/src/common/sme_power_save.c | 9 +-
core/sme/src/csr/csr_api_scan.c | 53 +++-
core/wma/src/wma_scan_roam.c | 36 +++
14 files changed, 880 insertions(+), 15 deletions(-)
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 92c8669..d2cb3be 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -61,6 +61,8 @@
/* Number of items that can be configured */
#define MAX_CFG_INI_ITEMS 1024
+#define MAX_PRB_REQ_VENDOR_OUI_INI_LEN 160
+#define VENDOR_SPECIFIC_IE_BITMAP 0x20000000
/* Defines for all of the things we read from the configuration (registry). */
@@ -10049,6 +10051,261 @@ enum dot11p_mode {
#define CFG_ARP_AC_CATEGORY_MAX (3)
#define CFG_ARP_AC_CATEGORY_DEFAULT (3)
+
+/*
+ * <ini>
+ * g_enable_probereq_whitelist_ies - Enable IE white listing
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable probe request IE white listing feature.
+ * Values 0 and 1 are used to disable and enable respectively, by default this
+ * feature is disabled.
+ *
+ * Related: None
+ *
+ * Supported Feature: Probe request IE whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PRB_REQ_IE_WHITELIST_NAME "g_enable_probereq_whitelist_ies"
+#define CFG_PRB_REQ_IE_WHITELIST_MIN (0)
+#define CFG_PRB_REQ_IE_WHITELIST_MAX (1)
+#define CFG_PRB_REQ_IE_WHITELIST_DEFAULT (0)
+
+/*
+ * For IE white listing in Probe Req, following ini parameters from
+ * g_probe_req_ie_bitmap_0 to g_probe_req_ie_bitmap_7 are used. User needs to
+ * input this values in hexa decimal format, when bit is set in bitmap,
+ * corresponding IE needs to be included in probe request.
+ *
+ * Example:
+ * ========
+ * If IE 221 needs to be in the probe request, set the corresponding bit
+ * as follows:
+ * a= IE/32 = 221/32 = 6 = g_probe_req_ie_bitmap_6
+ * b = IE modulo 32 = 29,
+ * means set the bth bit in g_probe_req_ie_bitmap_a,
+ * therefore set 29th bit in g_probe_req_ie_bitmap_6,
+ * as a result, g_probe_req_ie_bitmap_6=20000000
+ *
+ * Note: For IE 221, its mandatory to set the gProbeReqOUIs.
+ */
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_0 - Used to set the bitmap of IEs from 0 to 31
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 0 to 31 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PRB_REQ_IE_BIT_MAP0_NAME "g_probe_req_ie_bitmap_0"
+#define CFG_PRB_REQ_IE_BIT_MAP0_MIN (0x00000000)
+#define CFG_PRB_REQ_IE_BIT_MAP0_MAX (0xFFFFFFFF)
+#define CFG_PRB_REQ_IE_BIT_MAP0_DEFAULT (0x00000000)
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_1 - Used to set the bitmap of IEs from 32 to 63
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 32 to 63 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PRB_REQ_IE_BIT_MAP1_NAME "g_probe_req_ie_bitmap_1"
+#define CFG_PRB_REQ_IE_BIT_MAP1_MIN (0x00000000)
+#define CFG_PRB_REQ_IE_BIT_MAP1_MAX (0xFFFFFFFF)
+#define CFG_PRB_REQ_IE_BIT_MAP1_DEFAULT (0x00000000)
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_2 - Used to set the bitmap of IEs from 64 to 95
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 64 to 95 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PRB_REQ_IE_BIT_MAP2_NAME "g_probe_req_ie_bitmap_2"
+#define CFG_PRB_REQ_IE_BIT_MAP2_MIN (0x00000000)
+#define CFG_PRB_REQ_IE_BIT_MAP2_MAX (0xFFFFFFFF)
+#define CFG_PRB_REQ_IE_BIT_MAP2_DEFAULT (0x00000000)
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_3 - Used to set the bitmap of IEs from 96 to 127
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 96 to 127 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PRB_REQ_IE_BIT_MAP3_NAME "g_probe_req_ie_bitmap_3"
+#define CFG_PRB_REQ_IE_BIT_MAP3_MIN (0x00000000)
+#define CFG_PRB_REQ_IE_BIT_MAP3_MAX (0xFFFFFFFF)
+#define CFG_PRB_REQ_IE_BIT_MAP3_DEFAULT (0x00000000)
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_4 - Used to set the bitmap of IEs from 128 to 159
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 128 to 159 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PRB_REQ_IE_BIT_MAP4_NAME "g_probe_req_ie_bitmap_4"
+#define CFG_PRB_REQ_IE_BIT_MAP4_MIN (0x00000000)
+#define CFG_PRB_REQ_IE_BIT_MAP4_MAX (0xFFFFFFFF)
+#define CFG_PRB_REQ_IE_BIT_MAP4_DEFAULT (0x00000000)
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_5 - Used to set the bitmap of IEs from 160 to 191
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 160 to 191 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PRB_REQ_IE_BIT_MAP5_NAME "g_probe_req_ie_bitmap_5"
+#define CFG_PRB_REQ_IE_BIT_MAP5_MIN (0x00000000)
+#define CFG_PRB_REQ_IE_BIT_MAP5_MAX (0xFFFFFFFF)
+#define CFG_PRB_REQ_IE_BIT_MAP5_DEFAULT (0x00000000)
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_6 - Used to set the bitmap of IEs from 192 to 223
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 192 to 223 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PRB_REQ_IE_BIT_MAP6_NAME "g_probe_req_ie_bitmap_6"
+#define CFG_PRB_REQ_IE_BIT_MAP6_MIN (0x00000000)
+#define CFG_PRB_REQ_IE_BIT_MAP6_MAX (0xFFFFFFFF)
+#define CFG_PRB_REQ_IE_BIT_MAP6_DEFAULT (0x00000000)
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_7 - Used to set the bitmap of IEs from 224 to 255
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 224 to 255 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PRB_REQ_IE_BIT_MAP7_NAME "g_probe_req_ie_bitmap_7"
+#define CFG_PRB_REQ_IE_BIT_MAP7_MIN (0x00000000)
+#define CFG_PRB_REQ_IE_BIT_MAP7_MAX (0xFFFFFFFF)
+#define CFG_PRB_REQ_IE_BIT_MAP7_DEFAULT (0x00000000)
+
+/*
+ * For vendor specific IE, Probe Req OUI types and sub types which are
+ * to be white listed are specified in gProbeReqOUIs in the following
+ * example format - gProbeReqOUIs=AABBCCDD EEFF1122
+ */
+
+/*
+ * <ini>
+ * gProbeReqOUIs - Used to specify vendor specific OUIs
+ * @Default: Empty string
+ *
+ * This ini is used to include the specified OUIs in vendor specific IE
+ * of probe request.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies and
+ * vendor specific IE should be set in g_probe_req_ie_bitmap_6.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PROBE_REQ_OUI_NAME "gProbeReqOUIs"
+#define CFG_PROBE_REQ_OUI_DEFAULT ""
+
+
/*---------------------------------------------------------------------------
Type declarations
-------------------------------------------------------------------------*/
@@ -10779,6 +11036,20 @@ struct hdd_config {
uint8_t packet_filters_bitmap;
uint32_t arp_ac_category;
+
+ bool probe_req_ie_whitelist;
+ /* probe request bit map ies */
+ uint32_t probe_req_ie_bitmap_0;
+ uint32_t probe_req_ie_bitmap_1;
+ uint32_t probe_req_ie_bitmap_2;
+ uint32_t probe_req_ie_bitmap_3;
+ uint32_t probe_req_ie_bitmap_4;
+ uint32_t probe_req_ie_bitmap_5;
+ uint32_t probe_req_ie_bitmap_6;
+ uint32_t probe_req_ie_bitmap_7;
+
+ /* Probe Request multiple vendor OUIs */
+ uint8_t probe_req_ouis[MAX_PRB_REQ_VENDOR_OUI_INI_LEN];
};
#define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))
@@ -10891,6 +11162,48 @@ static __inline unsigned long util_min(unsigned long a, unsigned long b)
/* Function declarations and documenation */
QDF_STATUS hdd_parse_config_ini(hdd_context_t *pHddCtx);
+
+/**
+ * hdd_validate_prb_req_ie_bitmap - validates user input for ie bit map
+ * @hdd_ctx: the pointer to hdd context
+ *
+ * This function checks whether user has entered valid probe request
+ * ie bitmap and also verifies vendor ouis if vendor specific ie is set
+ *
+ * Return: status of verification
+ * true - valid input
+ * false - invalid input
+ */
+bool hdd_validate_prb_req_ie_bitmap(hdd_context_t *hdd_ctx);
+
+/**
+ * hdd_parse_probe_req_ouis - form ouis from ini gProbeReqOUIs
+ * @hdd_ctx: the pointer to hdd context
+ *
+ * This function parses the ini string gProbeReqOUIs which needs be to in the
+ * following format:
+ * "<8 characters of [0-9] or [A-F]>space<8 characters from [0-9] etc.,"
+ * example: "AABBCCDD 1122EEFF"
+ * and the logic counts the number of OUIS and allocates the memory
+ * for every valid OUI and is stored in hdd_context_t
+ *
+ * Return: status of parsing
+ * 0 - success
+ * negative value - failure
+ */
+int hdd_parse_probe_req_ouis(hdd_context_t *hdd_ctx);
+
+/**
+ * hdd_free_probe_req_ouis - de-allocates the probe req ouis
+ * @hdd_ctx: the pointer to hdd context
+ *
+ * This function de-alloactes the probe req ouis which are
+ * allocated while parsing of ini string gProbeReqOUIs
+ *
+ * Return: None
+ */
+void hdd_free_probe_req_ouis(hdd_context_t *hdd_ctx);
+
QDF_STATUS hdd_update_mac_config(hdd_context_t *pHddCtx);
QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx);
QDF_STATUS hdd_set_sme_chan_list(hdd_context_t *hdd_ctx);
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index d0d0531..38522ea 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -285,6 +285,8 @@ typedef enum {
eHDD_SAP_EAPOL_IN_PROGRESS,
} scan_reject_states;
+#define MAX_PROBE_REQ_OUIS 16
+
/*
* Generic asynchronous request/response support
*
@@ -1658,6 +1660,9 @@ struct hdd_context_s {
bool rcpi_enabled;
bool imps_enabled;
int user_configured_pkt_filter_rules;
+
+ uint32_t no_of_probe_req_ouis;
+ struct vendor_oui *probe_req_voui;
};
/*---------------------------------------------------------------------------
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index 0ab8662..72a1647 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -4408,6 +4408,74 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_ARP_AC_CATEGORY_DEFAULT,
CFG_ARP_AC_CATEGORY_MIN,
CFG_ARP_AC_CATEGORY_MAX),
+
+ REG_VARIABLE(CFG_PRB_REQ_IE_WHITELIST_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, probe_req_ie_whitelist,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_PRB_REQ_IE_WHITELIST_DEFAULT,
+ CFG_PRB_REQ_IE_WHITELIST_MIN,
+ CFG_PRB_REQ_IE_WHITELIST_MAX),
+
+ REG_VARIABLE(CFG_PRB_REQ_IE_BIT_MAP0_NAME, WLAN_PARAM_HexInteger,
+ struct hdd_config, probe_req_ie_bitmap_0,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP0_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP0_MIN,
+ CFG_PRB_REQ_IE_BIT_MAP0_MAX),
+
+ REG_VARIABLE(CFG_PRB_REQ_IE_BIT_MAP1_NAME, WLAN_PARAM_HexInteger,
+ struct hdd_config, probe_req_ie_bitmap_1,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP1_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP1_MIN,
+ CFG_PRB_REQ_IE_BIT_MAP1_MAX),
+
+ REG_VARIABLE(CFG_PRB_REQ_IE_BIT_MAP2_NAME, WLAN_PARAM_HexInteger,
+ struct hdd_config, probe_req_ie_bitmap_2,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP2_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP2_MIN,
+ CFG_PRB_REQ_IE_BIT_MAP2_MAX),
+
+ REG_VARIABLE(CFG_PRB_REQ_IE_BIT_MAP3_NAME, WLAN_PARAM_HexInteger,
+ struct hdd_config, probe_req_ie_bitmap_3,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP3_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP3_MIN,
+ CFG_PRB_REQ_IE_BIT_MAP3_MAX),
+
+ REG_VARIABLE(CFG_PRB_REQ_IE_BIT_MAP4_NAME, WLAN_PARAM_HexInteger,
+ struct hdd_config, probe_req_ie_bitmap_4,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP4_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP4_MIN,
+ CFG_PRB_REQ_IE_BIT_MAP4_MAX),
+
+ REG_VARIABLE(CFG_PRB_REQ_IE_BIT_MAP5_NAME, WLAN_PARAM_HexInteger,
+ struct hdd_config, probe_req_ie_bitmap_5,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP5_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP5_MIN,
+ CFG_PRB_REQ_IE_BIT_MAP5_MAX),
+
+ REG_VARIABLE(CFG_PRB_REQ_IE_BIT_MAP6_NAME, WLAN_PARAM_HexInteger,
+ struct hdd_config, probe_req_ie_bitmap_6,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP6_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP6_MIN,
+ CFG_PRB_REQ_IE_BIT_MAP6_MAX),
+
+ REG_VARIABLE(CFG_PRB_REQ_IE_BIT_MAP7_NAME, WLAN_PARAM_HexInteger,
+ struct hdd_config, probe_req_ie_bitmap_7,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP7_DEFAULT,
+ CFG_PRB_REQ_IE_BIT_MAP7_MIN,
+ CFG_PRB_REQ_IE_BIT_MAP7_MAX),
+
+ REG_VARIABLE_STRING(CFG_PROBE_REQ_OUI_NAME, WLAN_PARAM_String,
+ struct hdd_config, probe_req_ouis,
+ VAR_FLAGS_OPTIONAL,
+ (void *)CFG_PROBE_REQ_OUI_DEFAULT),
};
/**
@@ -5898,8 +5966,38 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
hdd_debug("Name = [%s] Value = [%d]",
CFG_ARP_AC_CATEGORY,
pHddCtx->config->arp_ac_category);
-}
+ hdd_info("Name = [%s] Value = [%x] ",
+ CFG_PRB_REQ_IE_WHITELIST_NAME,
+ pHddCtx->config->probe_req_ie_whitelist);
+ hdd_info("Name = [%s] Value = [%x] ",
+ CFG_PRB_REQ_IE_BIT_MAP0_NAME,
+ pHddCtx->config->probe_req_ie_bitmap_0);
+ hdd_info("Name = [%s] Value = [%x] ",
+ CFG_PRB_REQ_IE_BIT_MAP1_NAME,
+ pHddCtx->config->probe_req_ie_bitmap_1);
+ hdd_info("Name = [%s] Value = [%x] ",
+ CFG_PRB_REQ_IE_BIT_MAP2_NAME,
+ pHddCtx->config->probe_req_ie_bitmap_2);
+ hdd_info("Name = [%s] Value = [%x] ",
+ CFG_PRB_REQ_IE_BIT_MAP3_NAME,
+ pHddCtx->config->probe_req_ie_bitmap_3);
+ hdd_info("Name = [%s] Value = [%x] ",
+ CFG_PRB_REQ_IE_BIT_MAP4_NAME,
+ pHddCtx->config->probe_req_ie_bitmap_4);
+ hdd_info("Name = [%s] Value = [%x] ",
+ CFG_PRB_REQ_IE_BIT_MAP5_NAME,
+ pHddCtx->config->probe_req_ie_bitmap_5);
+ hdd_info("Name = [%s] Value = [%x] ",
+ CFG_PRB_REQ_IE_BIT_MAP6_NAME,
+ pHddCtx->config->probe_req_ie_bitmap_6);
+ hdd_info("Name = [%s] Value = [%x] ",
+ CFG_PRB_REQ_IE_BIT_MAP7_NAME,
+ pHddCtx->config->probe_req_ie_bitmap_7);
+ hdd_info("Name = [%s] Value =[%s]",
+ CFG_PROBE_REQ_OUI_NAME,
+ pHddCtx->config->probe_req_ouis);
+}
/**
* hdd_update_mac_config() - update MAC address from cfg file
@@ -6160,8 +6258,7 @@ QDF_STATUS hdd_parse_config_ini(hdd_context_t *pHddCtx)
buffer = i_trim(buffer);
if (strlen(buffer) > 0) {
value = buffer;
- while (!i_isspace(*buffer)
- && *buffer != '\0')
+ while (*buffer != '\0')
buffer++;
*buffer = '\0';
cfgIniTable[i].name = name;
@@ -7682,3 +7779,183 @@ QDF_STATUS hdd_update_nss(hdd_context_t *hdd_ctx, uint8_t nss)
return (status == false) ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS;
}
+
+bool hdd_validate_prb_req_ie_bitmap(hdd_context_t *hdd_ctx)
+{
+ if (!(hdd_ctx->config->probe_req_ie_bitmap_0 ||
+ hdd_ctx->config->probe_req_ie_bitmap_1 ||
+ hdd_ctx->config->probe_req_ie_bitmap_2 ||
+ hdd_ctx->config->probe_req_ie_bitmap_3 ||
+ hdd_ctx->config->probe_req_ie_bitmap_4 ||
+ hdd_ctx->config->probe_req_ie_bitmap_5 ||
+ hdd_ctx->config->probe_req_ie_bitmap_6 ||
+ hdd_ctx->config->probe_req_ie_bitmap_7))
+ return false;
+
+ /*
+ * check whether vendor oui IE is set and OUIs are present, each OUI
+ * is entered in the form of string of 8 characters from ini, therefore,
+ * for atleast one OUI, minimum length is 8 and hence this string length
+ * is checked for minimum of 8
+ */
+ if ((hdd_ctx->config->probe_req_ie_bitmap_6 &
+ VENDOR_SPECIFIC_IE_BITMAP) &&
+ (strlen(hdd_ctx->config->probe_req_ouis) < 8))
+ return false;
+
+ /* check whether vendor oui IE is not set but OUIs are present */
+ if (!(hdd_ctx->config->probe_req_ie_bitmap_6 &
+ VENDOR_SPECIFIC_IE_BITMAP) &&
+ (strlen(hdd_ctx->config->probe_req_ouis) > 0))
+ return false;
+
+ return true;
+}
+
+/**
+ * probe_req_voui_convert_to_hex - converts str of 8 chars into two hex values
+ * @temp: string to be converted
+ * @voui: contains the type and subtype values
+ *
+ * This function converts the string length of 8 characters into two
+ * hexa-decimal values, oui_type and oui_subtype, where oui_type is the
+ * hexa decimal value converted from first 6 characters and oui_subtype is
+ * hexa decimal value converted from last 2 characters.
+ * strings which doesn't match with the specified pattern are ignored.
+ *
+ * Return: status of conversion
+ * true - if conversion is successful
+ * false - if conversion is failed
+ */
+static bool hdd_probe_req_voui_convert_to_hex(uint8_t *temp,
+ struct vendor_oui *voui)
+{
+ uint32_t hex_value[4] = {0};
+ uint32_t i = 0;
+ uint32_t indx = 0;
+
+ memset(voui, 0x00, sizeof(*voui));
+
+ /* convert string to hex */
+ for (i = 0; i < 8; i++) {
+ if (temp[i] >= '0' && temp[i] <= '9') {
+ hex_value[indx] = (temp[i] - '0') << 4;
+ } else if (temp[i] >= 'A' && temp[i] <= 'F') {
+ hex_value[indx] = (temp[i] - 'A') + 0xA;
+ hex_value[indx] = hex_value[indx] << 4;
+ } else {
+ /* invalid character in oui */
+ return false;
+ }
+
+ if (temp[i + 1] >= '0' && temp[i + 1] <= '9') {
+ hex_value[indx] |= (temp[i + 1] - '0');
+ i = i + 1;
+ indx = indx + 1;
+ } else if (temp[i + 1] >= 'A' && temp[i + 1] <= 'F') {
+ hex_value[indx] |= ((temp[i + 1] - 'A') + 0xA);
+ i = i + 1;
+ indx = indx + 1;
+ } else {
+ /* invalid character in oui */
+ return false;
+ }
+ }
+
+ voui->oui_type = (hex_value[0] | (hex_value[1] << 8) |
+ (hex_value[2] << 16));
+ voui->oui_subtype = hex_value[3];
+
+ hdd_info("OUI_type = %x and OUI_subtype = %x",
+ voui->oui_type, voui->oui_subtype);
+
+ return true;
+}
+
+int hdd_parse_probe_req_ouis(hdd_context_t *hdd_ctx)
+{
+ struct vendor_oui voui[MAX_PROBE_REQ_OUIS];
+ uint8_t *str;
+ uint8_t temp[9];
+ uint32_t start = 0, end = 0;
+ uint32_t oui_indx = 0;
+ uint32_t i = 0;
+
+ hdd_ctx->config->probe_req_ouis[MAX_PRB_REQ_VENDOR_OUI_INI_LEN - 1] =
+ '\0';
+ if (!strlen(hdd_ctx->config->probe_req_ouis)) {
+ hdd_ctx->no_of_probe_req_ouis = 0;
+ hdd_ctx->probe_req_voui = NULL;
+ hdd_info("NO OUIS to parse");
+ return 0;
+ }
+
+ str = (uint8_t *)(hdd_ctx->config->probe_req_ouis);
+
+ while (str[i] != '\0') {
+ if (str[i] == ' ') {
+ if ((end - start) != 8) {
+ end = start = 0;
+ i++;
+ continue;
+ } else {
+ memcpy(temp, &str[i - 8], 8);
+ i++;
+ temp[8] = '\0';
+ if (hdd_probe_req_voui_convert_to_hex(temp,
+ &voui[oui_indx]) == 0) {
+ continue;
+ }
+ oui_indx++;
+ if (oui_indx > MAX_PROBE_REQ_OUIS) {
+ /*
+ * Max number of OUIs supported is 16,
+ * ignoring the rest
+ */
+ hdd_info("Max OUIs-supported: 16");
+ return 0;
+ }
+ }
+ start = end = 0;
+ } else {
+ i++;
+ end++;
+ }
+ }
+
+ if ((end - start) == 8) {
+ memcpy(temp, &str[i - 8], 8);
+ temp[8] = '\0';
+ if (hdd_probe_req_voui_convert_to_hex(temp,
+ &voui[oui_indx]) == 1)
+ oui_indx++;
+ }
+
+ if (!oui_indx)
+ return 0;
+
+ hdd_ctx->probe_req_voui = qdf_mem_malloc(oui_indx *
+ sizeof(*hdd_ctx->probe_req_voui));
+ if (hdd_ctx->probe_req_voui == NULL) {
+ hdd_err("Not Enough memory for OUI");
+ hdd_ctx->no_of_probe_req_ouis = 0;
+ return -ENOMEM;
+ }
+ hdd_ctx->no_of_probe_req_ouis = oui_indx;
+ qdf_mem_copy(hdd_ctx->probe_req_voui, voui,
+ oui_indx * sizeof(*hdd_ctx->probe_req_voui));
+
+ return 0;
+}
+
+void hdd_free_probe_req_ouis(hdd_context_t *hdd_ctx)
+{
+ struct vendor_oui *probe_req_voui = hdd_ctx->probe_req_voui;
+
+ if (probe_req_voui) {
+ hdd_ctx->probe_req_voui = NULL;
+ qdf_mem_free(probe_req_voui);
+ }
+
+ hdd_ctx->no_of_probe_req_ouis = 0;
+}
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index 2f3a7f9..836d6dc 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -1987,7 +1987,10 @@ __wlan_hdd_cfg80211_set_scanning_mac_oui(struct wiphy *wiphy,
hdd_err("Invalid ATTR");
return -EINVAL;
}
- pReqMsg = qdf_mem_malloc(sizeof(*pReqMsg));
+ pReqMsg = qdf_mem_malloc(sizeof(*pReqMsg) +
+ (pHddCtx->no_of_probe_req_ouis) *
+ (sizeof(struct vendor_oui)));
+
if (!pReqMsg) {
hdd_err("qdf_mem_malloc failed");
return -ENOMEM;
@@ -2006,6 +2009,15 @@ __wlan_hdd_cfg80211_set_scanning_mac_oui(struct wiphy *wiphy,
hdd_debug("Oui (%02x:%02x:%02x), vdev_id = %d", pReqMsg->oui[0],
pReqMsg->oui[1], pReqMsg->oui[2], pReqMsg->vdev_id);
+
+ if (pHddCtx->config->probe_req_ie_whitelist)
+ wlan_hdd_fill_whitelist_ie_attrs(&pReqMsg->ie_whitelist,
+ pReqMsg->probe_req_ie_bitmap,
+ &pReqMsg->num_vendor_oui,
+ (struct vendor_oui *)((uint8_t *)pReqMsg +
+ sizeof(*pReqMsg)),
+ pHddCtx);
+
status = sme_set_scanning_mac_oui(pHddCtx->hHal, pReqMsg);
if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("sme_set_scanning_mac_oui failed(err=%d)", status);
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index c726f88..103f529 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -4993,6 +4993,8 @@ static void hdd_context_destroy(hdd_context_t *hdd_ctx)
hdd_context_deinit(hdd_ctx);
+ hdd_free_probe_req_ouis(hdd_ctx);
+
qdf_mem_free(hdd_ctx->config);
hdd_ctx->config = NULL;
@@ -6875,6 +6877,21 @@ static hdd_context_t *hdd_context_create(struct device *dev)
hdd_debug("Setting configuredMcastBcastFilter: %d",
hdd_ctx->config->mcastBcastFilterSetting);
+ if (hdd_ctx->config->probe_req_ie_whitelist) {
+ if (hdd_validate_prb_req_ie_bitmap(hdd_ctx)) {
+ /* parse ini string probe req oui */
+ if (hdd_parse_probe_req_ouis(hdd_ctx)) {
+ hdd_err("Error parsing probe req ouis");
+ hdd_err("disable probe req ie whitelisting");
+ hdd_ctx->config->probe_req_ie_whitelist = false;
+ }
+ } else {
+ hdd_err("invalid probe req ie bitmap and ouis");
+ hdd_err("disable probe req ie whitelisting");
+ hdd_ctx->config->probe_req_ie_whitelist = false;
+ }
+ }
+
if (hdd_ctx->config->fhostNSOffload)
hdd_ctx->ns_offload_enable = true;
@@ -6934,6 +6951,7 @@ err_free_config:
qdf_mem_free(hdd_ctx->config);
err_free_hdd_context:
+ hdd_free_probe_req_ouis(hdd_ctx);
wiphy_free(hdd_ctx->wiphy);
err_out:
diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c
index 8b48f42..5e3ecb2 100644
--- a/core/hdd/src/wlan_hdd_power.c
+++ b/core/hdd/src/wlan_hdd_power.c
@@ -1673,6 +1673,8 @@ err_wiphy_unregister:
ptt_sock_deactivate_svc();
nl_srv_exit();
+ hdd_free_probe_req_ouis(pHddCtx);
+
/* Free up dynamically allocated members inside HDD Adapter */
qdf_mem_free(pHddCtx->config);
pHddCtx->config = NULL;
diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c
index 84b14ed..1f97c66 100644
--- a/core/hdd/src/wlan_hdd_scan.c
+++ b/core/hdd/src/wlan_hdd_scan.c
@@ -1557,6 +1557,7 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
+ hdd_station_ctx_t *station_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
struct hdd_config *cfg_param = NULL;
tCsrScanRequest scan_req;
uint8_t *channelList = NULL, i;
@@ -1970,6 +1971,27 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
wlan_hdd_update_scan_rand_attrs((void *)&scan_req, (void *)request,
WLAN_HDD_HOST_SCAN);
+ if (!hdd_conn_is_connected(station_ctx) &&
+ (pHddCtx->config->probe_req_ie_whitelist)) {
+ if (pHddCtx->no_of_probe_req_ouis != 0) {
+ scan_req.voui = qdf_mem_malloc(
+ pHddCtx->no_of_probe_req_ouis *
+ sizeof(struct vendor_oui));
+ if (!scan_req.voui) {
+ hdd_info("Not enough memory for voui");
+ scan_req.num_vendor_oui = 0;
+ status = -ENOMEM;
+ goto free_mem;
+ }
+ }
+
+ wlan_hdd_fill_whitelist_ie_attrs(&scan_req.ie_whitelist,
+ scan_req.probe_req_ie_bitmap,
+ &scan_req.num_vendor_oui,
+ scan_req.voui,
+ pHddCtx);
+ }
+
qdf_runtime_pm_prevent_suspend(&pHddCtx->runtime_context.scan);
status = sme_scan_request(WLAN_HDD_GET_HAL_CTX(pAdapter),
pAdapter->sessionId, &scan_req,
@@ -2005,6 +2027,9 @@ free_mem:
if (status == 0)
scan_ebusy_cnt = 0;
+ if (scan_req.voui)
+ qdf_mem_free(scan_req.voui);
+
EXIT();
return status;
}
@@ -2796,6 +2821,7 @@ static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
hdd_scaninfo_t *pScanInfo = &pAdapter->scan_info;
struct hdd_config *config = NULL;
uint32_t num_ignore_dfs_ch = 0;
+ hdd_station_ctx_t *station_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
ENTER();
@@ -2853,7 +2879,15 @@ static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
}
}
- pPnoRequest = (tpSirPNOScanReq) qdf_mem_malloc(sizeof(tSirPNOScanReq));
+ if (!hdd_conn_is_connected(station_ctx) &&
+ (pHddCtx->config->probe_req_ie_whitelist))
+ pPnoRequest =
+ (tpSirPNOScanReq)qdf_mem_malloc(sizeof(tSirPNOScanReq) +
+ (pHddCtx->no_of_probe_req_ouis) *
+ (sizeof(struct vendor_oui)));
+ else
+ pPnoRequest = qdf_mem_malloc(sizeof(tSirPNOScanReq));
+
if (NULL == pPnoRequest) {
hdd_err("qdf_mem_malloc failed");
return -ENOMEM;
@@ -3013,6 +3047,16 @@ static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
wlan_hdd_update_scan_rand_attrs((void *)pPnoRequest, (void *)request,
WLAN_HDD_PNO_SCAN);
+ if (pHddCtx->config->probe_req_ie_whitelist &&
+ !hdd_conn_is_connected(station_ctx))
+ wlan_hdd_fill_whitelist_ie_attrs(&pPnoRequest->ie_whitelist,
+ pPnoRequest->probe_req_ie_bitmap,
+ &pPnoRequest->num_vendor_oui,
+ (struct vendor_oui *)(
+ (uint8_t *)pPnoRequest +
+ sizeof(*pPnoRequest)),
+ pHddCtx);
+
status = sme_set_preferred_network_list(WLAN_HDD_GET_HAL_CTX(pAdapter),
pPnoRequest,
pAdapter->sessionId,
@@ -3322,3 +3366,33 @@ int hdd_scan_context_init(hdd_context_t *hdd_ctx)
return 0;
}
+
+void wlan_hdd_fill_whitelist_ie_attrs(bool *ie_whitelist,
+ uint32_t *probe_req_ie_bitmap,
+ uint32_t *num_vendor_oui,
+ struct vendor_oui *voui,
+ hdd_context_t *hdd_ctx)
+{
+ uint32_t i = 0;
+
+ *ie_whitelist = true;
+ probe_req_ie_bitmap[0] = hdd_ctx->config->probe_req_ie_bitmap_0;
+ probe_req_ie_bitmap[1] = hdd_ctx->config->probe_req_ie_bitmap_1;
+ probe_req_ie_bitmap[2] = hdd_ctx->config->probe_req_ie_bitmap_2;
+ probe_req_ie_bitmap[3] = hdd_ctx->config->probe_req_ie_bitmap_3;
+ probe_req_ie_bitmap[4] = hdd_ctx->config->probe_req_ie_bitmap_4;
+ probe_req_ie_bitmap[5] = hdd_ctx->config->probe_req_ie_bitmap_5;
+ probe_req_ie_bitmap[6] = hdd_ctx->config->probe_req_ie_bitmap_6;
+ probe_req_ie_bitmap[7] = hdd_ctx->config->probe_req_ie_bitmap_7;
+
+ *num_vendor_oui = 0;
+
+ if ((hdd_ctx->no_of_probe_req_ouis != 0) && (voui != NULL)) {
+ *num_vendor_oui = hdd_ctx->no_of_probe_req_ouis;
+ for (i = 0; i < hdd_ctx->no_of_probe_req_ouis; i++) {
+ voui[i].oui_type = hdd_ctx->probe_req_voui[i].oui_type;
+ voui[i].oui_subtype =
+ hdd_ctx->probe_req_voui[i].oui_subtype;
+ }
+ }
+}
diff --git a/core/hdd/src/wlan_hdd_scan.h b/core/hdd/src/wlan_hdd_scan.h
index 96c96f4..49cce33 100644
--- a/core/hdd/src/wlan_hdd_scan.h
+++ b/core/hdd/src/wlan_hdd_scan.h
@@ -129,5 +129,24 @@ void hdd_cleanup_scan_queue(hdd_context_t *hdd_ctx);
void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
struct wireless_dev *wdev);
#endif
-#endif /* end #if !defined(WLAN_HDD_SCAN_H) */
+/**
+ * wlan_hdd_fill_whitelist_ie_attrs - fill the white list members
+ * @ie_whitelist: enables whitelist
+ * @probe_req_ie_bitmap: bitmap to be filled
+ * @num_vendor_oui: pointer to no of ouis
+ * @voui: pointer to ouis to be filled
+ * @hdd_ctx: pointer to hdd ctx
+ *
+ * This function fills the ie bitmap and vendor oui fields with the
+ * corresponding values present in config and hdd_ctx
+ *
+ * Return: None
+ */
+void wlan_hdd_fill_whitelist_ie_attrs(bool *ie_whitelist,
+ uint32_t *probe_req_ie_bitmap,
+ uint32_t *num_vendor_oui,
+ struct vendor_oui *voui,
+ hdd_context_t *hdd_ctx);
+
+#endif /* end #if !defined(WLAN_HDD_SCAN_H) */
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index f414035..644b8a8 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -910,6 +910,13 @@ typedef struct sSirSmeScanReq {
uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
uint8_t mac_addr_mask[QDF_MAC_ADDR_SIZE];
+ /* probe req ie whitelisting attrs */
+ bool ie_whitelist;
+ uint32_t probe_req_ie_bitmap[PROBE_REQ_BITMAP_LEN];
+ uint32_t num_vendor_oui;
+ uint32_t oui_field_len;
+ uint32_t oui_field_offset;
+
/* channelList MUST be the last field of this structure */
tSirChannelList channelList;
/*-----------------------------
@@ -928,7 +935,10 @@ typedef struct sSirSmeScanReq {
----------------------------- <--+
... variable size uIEFiled
up to uIEFieldLen (can be 0)
- -----------------------------*/
+ -----------------------------
+ ... variable size upto num_vendor_oui
+ struct vendor_oui voui;
+ -----------------------------------*/
} tSirSmeScanReq, *tpSirSmeScanReq;
typedef struct sSirSmeScanAbortReq {
@@ -2972,6 +2982,12 @@ typedef struct sSirPNOScanReq {
bool relative_rssi_set;
int8_t relative_rssi;
struct connected_pno_band_rssi_pref band_rssi_pref;
+
+ /* probe req ie whitelisting attrs */
+ bool ie_whitelist;
+ uint32_t probe_req_ie_bitmap[PROBE_REQ_BITMAP_LEN];
+ uint32_t num_vendor_oui;
+ /* followed by one or more struct vendor_oui */
} tSirPNOScanReq, *tpSirPNOScanReq;
/* Preferred Network Found Indication */
@@ -3819,6 +3835,13 @@ typedef struct sSirScanOffloadReq {
uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
uint8_t mac_addr_mask[QDF_MAC_ADDR_SIZE];
+ /* probe req ie whitelisting attrs */
+ bool ie_whitelist;
+ uint32_t probe_req_ie_bitmap[PROBE_REQ_BITMAP_LEN];
+ uint32_t num_vendor_oui;
+ uint32_t oui_field_len;
+ uint32_t oui_field_offset;
+
tSirChannelList channelList;
/*-----------------------------
sSirScanOffloadReq....
@@ -3836,7 +3859,10 @@ typedef struct sSirScanOffloadReq {
----------------------------- <--+
... variable size uIEField
up to uIEFieldLen (can be 0)
- -----------------------------*/
+ -----------------------------
+ ... variable size upto num_vendor_oui
+ struct vendor_oui voui;
+ ------------------------*/
} tSirScanOffloadReq, *tpSirScanOffloadReq;
/**
@@ -4999,6 +5025,11 @@ typedef struct {
uint8_t oui[WIFI_SCANNING_MAC_OUI_LENGTH];
uint32_t vdev_id;
bool enb_probe_req_sno_randomization;
+ /* probe req ie whitelisting attrs */
+ bool ie_whitelist;
+ uint32_t probe_req_ie_bitmap[PROBE_REQ_BITMAP_LEN];
+ uint32_t num_vendor_oui;
+ /* Followed by 0 or more struct vendor_oui */
} tSirScanMacOui, *tpSirScanMacOui;
enum {
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 4c653fb..0703dec 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
@@ -1222,7 +1222,6 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac,
uint8_t *p;
tSirMsgQ msg;
uint16_t i, len;
- uint16_t addn_ie_len = 0;
tSirRetStatus status, rc = eSIR_SUCCESS;
tDot11fIEExtCap extracted_extcap = {0};
bool extcap_present = true;
@@ -1255,7 +1254,7 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac,
*/
len = sizeof(tSirScanOffloadReq) +
(pScanReq->channelList.numChannels - 1) +
- pScanReq->uIEFieldLen;
+ pScanReq->uIEFieldLen + pScanReq->oui_field_len;
pScanOffloadReq = qdf_mem_malloc(len);
if (NULL == pScanOffloadReq) {
@@ -1335,8 +1334,8 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac,
p[i] = pScanReq->channelList.channelNumber[i];
pScanOffloadReq->uIEFieldLen = pScanReq->uIEFieldLen;
- pScanOffloadReq->uIEFieldOffset = len - addn_ie_len -
- pScanOffloadReq->uIEFieldLen;
+ pScanOffloadReq->uIEFieldOffset = len - pScanOffloadReq->uIEFieldLen -
+ pScanReq->oui_field_len;
qdf_mem_copy((uint8_t *) pScanOffloadReq +
pScanOffloadReq->uIEFieldOffset,
(uint8_t *) pScanReq + pScanReq->uIEFieldOffset,
@@ -1351,6 +1350,23 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac,
pScanReq->mac_addr_mask, QDF_MAC_ADDR_SIZE);
}
+ pScanOffloadReq->oui_field_len = pScanReq->oui_field_len;
+ pScanOffloadReq->num_vendor_oui = pScanReq->num_vendor_oui;
+ pScanOffloadReq->ie_whitelist = pScanReq->ie_whitelist;
+ if (pScanOffloadReq->ie_whitelist)
+ qdf_mem_copy(pScanOffloadReq->probe_req_ie_bitmap,
+ pScanReq->probe_req_ie_bitmap,
+ PROBE_REQ_BITMAP_LEN * sizeof(uint32_t));
+ pScanOffloadReq->oui_field_offset = sizeof(tSirScanOffloadReq) +
+ (pScanOffloadReq->channelList.numChannels - 1) +
+ pScanOffloadReq->uIEFieldLen;
+ if (pScanOffloadReq->num_vendor_oui != 0) {
+ qdf_mem_copy(
+ (uint8_t *) pScanOffloadReq + pScanOffloadReq->oui_field_offset,
+ (uint8_t *) pScanReq + pScanReq->oui_field_offset,
+ pScanReq->oui_field_len);
+ }
+
rc = wma_post_ctrl_msg(pMac, &msg);
if (rc != eSIR_SUCCESS) {
lim_log(pMac, LOGE, FL("wma_post_ctrl_msg() return failure"));
diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h
index 788e688..211d489 100644
--- a/core/sme/inc/csr_api.h
+++ b/core/sme/inc/csr_api.h
@@ -297,6 +297,12 @@ typedef struct tagCsrScanRequest {
bool enable_scan_randomization;
uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
uint8_t mac_addr_mask[QDF_MAC_ADDR_SIZE];
+
+ /* probe req ie whitelisting attrs */
+ bool ie_whitelist;
+ uint32_t probe_req_ie_bitmap[PROBE_REQ_BITMAP_LEN];
+ uint32_t num_vendor_oui;
+ struct vendor_oui *voui;
} tCsrScanRequest;
typedef struct tagCsrScanResultInfo {
diff --git a/core/sme/src/common/sme_power_save.c b/core/sme/src/common/sme_power_save.c
index 4ded194..298e0b5 100644
--- a/core/sme/src/common/sme_power_save.c
+++ b/core/sme/src/common/sme_power_save.c
@@ -771,14 +771,19 @@ QDF_STATUS sme_set_ps_preferred_network_list(tHalHandle hal_ctx,
return QDF_STATUS_E_FAILURE;
}
- request_buf = qdf_mem_malloc(sizeof(tSirPNOScanReq));
+ request_buf = qdf_mem_malloc(sizeof(tSirPNOScanReq) +
+ (request->num_vendor_oui) *
+ (sizeof(struct vendor_oui)));
+
if (NULL == request_buf) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
FL("Not able to allocate memory for PNO request"));
return QDF_STATUS_E_NOMEM;
}
- qdf_mem_copy(request_buf, request, sizeof(tSirPNOScanReq));
+ qdf_mem_copy(request_buf, request, sizeof(tSirPNOScanReq) +
+ (request->num_vendor_oui) *
+ (sizeof(struct vendor_oui)));
/*Must translate the mode first */
uc_dot11_mode = (uint8_t) csr_translate_to_wni_cfg_dot11_mode(mac_ctx,
diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c
index bb53967..a810f14 100644
--- a/core/sme/src/csr/csr_api_scan.c
+++ b/core/sme/src/csr/csr_api_scan.c
@@ -5066,7 +5066,8 @@ static QDF_STATUS csr_send_mb_scan_req(tpAniSirGlobal pMac, uint16_t sessionId,
sizeof(pMsg->channelList.channelNumber) +
(sizeof(pMsg->channelList.channelNumber) *
pScanReq->ChannelInfo.numOfChannels)) +
- (pScanReq->uIEFieldLen);
+ (pScanReq->uIEFieldLen) +
+ pScanReq->num_vendor_oui * sizeof(*pScanReq->voui);
pMsg = qdf_mem_malloc(msgLen);
if (NULL == pMsg) {
@@ -5237,6 +5238,26 @@ static QDF_STATUS csr_send_mb_scan_req(tpAniSirGlobal pMac, uint16_t sessionId,
QDF_MAC_ADDR_SIZE);
}
+ pMsg->ie_whitelist = pScanReq->ie_whitelist;
+ if (pMsg->ie_whitelist)
+ qdf_mem_copy(pMsg->probe_req_ie_bitmap,
+ pScanReq->probe_req_ie_bitmap,
+ PROBE_REQ_BITMAP_LEN * sizeof(uint32_t));
+ pMsg->num_vendor_oui = pScanReq->num_vendor_oui;
+ pMsg->oui_field_len = pScanReq->num_vendor_oui *
+ sizeof(*pScanReq->voui);
+ pMsg->oui_field_offset = (sizeof(tSirSmeScanReq) -
+ sizeof(pMsg->channelList.channelNumber) +
+ (sizeof(pMsg->channelList.channelNumber) *
+ pScanReq->ChannelInfo.numOfChannels)) +
+ pScanReq->uIEFieldLen;
+
+ if (pScanReq->num_vendor_oui != 0) {
+ qdf_mem_copy((uint8_t *)pMsg + pMsg->oui_field_offset,
+ (uint8_t *)(pScanReq->voui),
+ pMsg->oui_field_len);
+ }
+
send_scan_req:
sms_log(pMac, LOGD,
FL("scanId %d domainIdCurrent %d scanType %s (%d) bssType %s (%d) requestType %s (%d) numChannels %d"),
@@ -5652,6 +5673,7 @@ QDF_STATUS csr_scan_copy_request(tpAniSirGlobal mac_ctx,
dst_req->pIEField = NULL;
dst_req->ChannelInfo.ChannelList = NULL;
dst_req->SSIDs.SSIDList = NULL;
+ dst_req->voui = NULL;
if (src_req->uIEFieldLen) {
dst_req->pIEField =
@@ -5809,6 +5831,29 @@ QDF_STATUS csr_scan_copy_request(tpAniSirGlobal mac_ctx,
dst_req->scan_id = src_req->scan_id;
dst_req->timestamp = src_req->timestamp;
+ if (src_req->num_vendor_oui == 0) {
+ dst_req->num_vendor_oui = 0;
+ dst_req->voui = NULL;
+ } else {
+ dst_req->voui = qdf_mem_malloc(src_req->num_vendor_oui *
+ sizeof(*dst_req->voui));
+ if (!dst_req->voui)
+ status = QDF_STATUS_E_NOMEM;
+ else
+ status = QDF_STATUS_SUCCESS;
+
+ if (QDF_IS_STATUS_SUCCESS(status)) {
+ dst_req->num_vendor_oui = src_req->num_vendor_oui;
+ qdf_mem_copy(dst_req->voui,
+ src_req->voui,
+ src_req->num_vendor_oui *
+ sizeof(*dst_req->voui));
+ } else {
+ dst_req->num_vendor_oui = 0;
+ sms_log(mac_ctx, LOGE, FL("No memory for voui"));
+ }
+ }
+
complete:
if (!QDF_IS_STATUS_SUCCESS(status)) {
csr_scan_free_request(mac_ctx, dst_req);
@@ -5836,6 +5881,12 @@ QDF_STATUS csr_scan_free_request(tpAniSirGlobal pMac, tCsrScanRequest *pReq)
}
pReq->SSIDs.numOfSSIDs = 0;
+ if (pReq->voui) {
+ qdf_mem_free(pReq->voui);
+ pReq->voui = NULL;
+ }
+ pReq->num_vendor_oui = 0;
+
return QDF_STATUS_SUCCESS;
}
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index d2dceca..8a78323 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -283,6 +283,17 @@ QDF_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle,
qdf_mem_copy(cmd->mac_addr_mask, scan_req->mac_addr_mask,
QDF_MAC_ADDR_SIZE);
+ /* probe req ie whitelisting attributes */
+ cmd->ie_whitelist = scan_req->ie_whitelist;
+ if (cmd->ie_whitelist) {
+ for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++)
+ cmd->probe_req_ie_bitmap[i] =
+ scan_req->probe_req_ie_bitmap[i];
+ cmd->num_vendor_oui = scan_req->num_vendor_oui;
+ cmd->oui_field_len = scan_req->oui_field_len;
+ cmd->voui = (uint8_t *)scan_req + scan_req->oui_field_offset;
+ }
+
if (!scan_req->p2pScanType) {
WMA_LOGD("Normal Scan request");
cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES;
@@ -3174,6 +3185,18 @@ QDF_STATUS wma_pno_start(tp_wma_handle wma, tpSirPNOScanReq pno)
params->band_rssi_pref.band = pno->band_rssi_pref.band;
params->band_rssi_pref.rssi = pno->band_rssi_pref.rssi;
+ /* probe req ie whitelisting attributes */
+ params->ie_whitelist = pno->ie_whitelist;
+ if (params->ie_whitelist) {
+ for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++)
+ params->probe_req_ie_bitmap[i] =
+ pno->probe_req_ie_bitmap[i];
+ params->num_vendor_oui = pno->num_vendor_oui;
+ params->oui_field_len = pno->num_vendor_oui *
+ sizeof(struct vendor_oui);
+ params->voui = (uint8_t *)pno;
+ }
+
status = wmi_unified_pno_start_cmd(wma->wmi_handle,
params, channel_list);
if (QDF_IS_STATUS_SUCCESS(status)) {
@@ -5599,6 +5622,7 @@ QDF_STATUS wma_reset_passpoint_network_list(tp_wma_handle wma,
QDF_STATUS wma_scan_probe_setoui(tp_wma_handle wma, tSirScanMacOui *psetoui)
{
struct scan_mac_oui set_oui;
+ uint32_t i = 0;
qdf_mem_set(&set_oui, sizeof(struct scan_mac_oui), 0);
@@ -5614,6 +5638,18 @@ QDF_STATUS wma_scan_probe_setoui(tp_wma_handle wma, tSirScanMacOui *psetoui)
set_oui.enb_probe_req_sno_randomization =
psetoui->enb_probe_req_sno_randomization;
+ /* probe req ie whitelisting attributes */
+ set_oui.ie_whitelist = psetoui->ie_whitelist;
+ if (set_oui.ie_whitelist) {
+ for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++)
+ set_oui.probe_req_ie_bitmap[i] =
+ psetoui->probe_req_ie_bitmap[i];
+ set_oui.num_vendor_oui = psetoui->num_vendor_oui;
+ set_oui.oui_field_len = psetoui->num_vendor_oui *
+ sizeof(struct vendor_oui);
+ set_oui.voui = (uint8_t *)psetoui;
+ }
+
return wmi_unified_scan_probe_setoui_cmd(wma->wmi_handle,
&set_oui);
}
--
cgit v1.1