From f41e3dbc92d448d3d56cae5517e41a4bafafdf3f Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Sirasanagandla 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) + +/* + * + * 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 + * + * + */ +#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. + */ + +/* + * + * 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 + * + * + */ +#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) + +/* + * + * 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 + * + * + */ +#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) + +/* + * + * 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 + * + * + */ +#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) + +/* + * + * 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 + * + * + */ +#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) + +/* + * + * 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 + * + * + */ +#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) + +/* + * + * 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 + * + * + */ +#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) + +/* + * + * 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 + * + * + */ +#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) + +/* + * + * 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 + * + * + */ +#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 + */ + +/* + * + * 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 + * + * + */ +#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