OSDN Git Service

N WifiScanner HAL Changes
authorMitchell Wills <mwills@google.com>
Thu, 12 Nov 2015 23:00:33 +0000 (15:00 -0800)
committerMitchell Wills <mwills@google.com>
Tue, 19 Jan 2016 19:44:50 +0000 (11:44 -0800)
Merge on_scan_results_available and on_scan_event gscan callbacks
Indicate which buckets were scanned in results callbacks
Add report scan to context hub flag
Add ePNO scoring parameters

Remove unused/superceeded functions
 * ssid hotlist
 * ssid whitelist
 * gscan roam
 * bssid preference

Change-Id: Ie1df191c77e967d3f53d625be8cc5eb76607c08f

include/hardware_legacy/gscan.h
include/hardware_legacy/wifi_hal.h

index d43fa28..0c22748 100644 (file)
@@ -1,4 +1,3 @@
-
 #include "wifi_hal.h"
 
 #ifndef __WIFI_HAL_GSCAN_H__
@@ -20,7 +19,7 @@ const unsigned MAX_CHANNELS                = 16;
 const unsigned MAX_BUCKETS                 = 16;
 const unsigned MAX_HOTLIST_APS             = 128;
 const unsigned MAX_SIGNIFICANT_CHANGE_APS  = 64;
-const unsigned MAX_PNO_SSID                = 64;
+const unsigned MAX_EPNO_NETWORKS           = 64;
 const unsigned MAX_HOTLIST_SSID            = 8;
 const unsigned MAX_BLACKLIST_BSSID         = 16;
 const unsigned MAX_AP_CACHE_PER_SCAN       = 32;
@@ -51,8 +50,21 @@ wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle,
         wifi_gscan_capabilities *capabilities);
 
 typedef enum {
-   WIFI_SCAN_BUFFER_FULL,
-   WIFI_SCAN_COMPLETE,
+    WIFI_SCAN_RESULTS_AVAILABLE,   // reported when REPORT_EVENTS_EACH_SCAN is set and a scan
+                                   // completes. WIFI_SCAN_THRESHOLD_NUM_SCANS or
+                                   // WIFI_SCAN_THRESHOLD_PERCENT can be reported instead if the
+                                   // reason for the event is available; however, at most one of
+                                   // these events should be reported per scan. If there are
+                                   // multiple buckets that were scanned this period and one has the
+                                   // EACH_SCAN flag set then this event should be prefered.
+    WIFI_SCAN_THRESHOLD_NUM_SCANS, // can be reported when REPORT_EVENTS_EACH_SCAN is not set and
+                                   // report_threshold_num_scans is reached.
+    WIFI_SCAN_THRESHOLD_PERCENT,   // can be reported when REPORT_EVENTS_EACH_SCAN is not set and
+                                   // report_threshold_percent is reached.
+    WIFI_SCAN_DISABLED,            // reported when currently executing gscans are disabled.
+                                   // start_gscan will need to be called again in order to continue
+                                   // scanning. This is intended to indicate abnormal scan
+                                   // terminations (not those as a result of stop_gscan).
 } wifi_scan_event;
 
 
@@ -81,16 +93,20 @@ typedef struct {
     // other fields
 } wifi_scan_result;
 
+static_assert(MAX_BUCKETS <= 8 * sizeof(unsigned),
+        "The buckets_scanned bitset is represented by an unsigned int and cannot support this many "
+        "buckets on this platform.");
 typedef struct {
-    /* reported when report_threshold is reached in scan cache */
-    void (*on_scan_results_available) (wifi_request_id id, unsigned num_results_available);
-
     /* reported when each probe response is received, if report_events
-     * enabled in wifi_scan_cmd_params */
-    void (*on_full_scan_result) (wifi_request_id id, wifi_scan_result *result);
+     * enabled in wifi_scan_cmd_params. buckets_scanned is a bitset of the
+     * buckets that are currently being scanned. See the buckets_scanned field
+     * in the wifi_cached_scan_results struct for more details.
+     */
+    void (*on_full_scan_result) (wifi_request_id id, wifi_scan_result *result,
+                                 unsigned buckets_scanned);
 
-    /* optional event - indicates progress of scanning statemachine */
-    void (*on_scan_event) (wifi_scan_event event, unsigned status);
+    /* indicates progress of scanning statemachine */
+    void (*on_scan_event) (wifi_request_id id, wifi_scan_event event);
 
 } wifi_scan_result_handler;
 
@@ -101,10 +117,10 @@ typedef struct {
     /* Add channel class */
 } wifi_scan_channel_spec;
 
-#define REPORT_EVENTS_BUFFER_FULL      0
-#define REPORT_EVENTS_EACH_SCAN        1
-#define REPORT_EVENTS_FULL_RESULTS     2
-#define REPORT_EVENTS_NO_BATCH         4
+#define REPORT_EVENTS_EACH_SCAN        (1 << 0)
+#define REPORT_EVENTS_FULL_RESULTS     (1 << 1)
+#define REPORT_EVENTS_NO_BATCH         (1 << 2)
+#define REPORT_EVENTS_CONTEXT_HUB      (1 << 3)
 
 typedef struct {
     int bucket;                         // bucket index, 0 based
@@ -115,13 +131,18 @@ typedef struct {
                                         // for exponential backoff bucket this is the min_period
     /* report_events semantics -
      *  This is a bit field; which defines following bits -
-     *  REPORT_EVENTS_BUFFER_FULL  => report only when scan history is % full
-     *  REPORT_EVENTS_EACH_SCAN    => report a scan completion event after scan
+     *  REPORT_EVENTS_EACH_SCAN    => report a scan completion event after scan. If this is not set
+     *                                 then scan completion events should be reported if
+     *                                 report_threshold_percent or report_threshold_num_scans is
+     *                                 reached.
      *  REPORT_EVENTS_FULL_RESULTS => forward scan results (beacons/probe responses + IEs)
      *                                 in real time to HAL, in addition to completion events
      *                                 Note: To keep backward compatibility, fire completion
      *                                 events regardless of REPORT_EVENTS_EACH_SCAN.
-     *  REPORT_EVENTS_NO_BATCH     => controls batching, 0 => batching, 1 => no batching
+     *  REPORT_EVENTS_NO_BATCH     => controls if scans for this bucket should be placed in the
+     *                                 history buffer
+     *  REPORT_EVENTS_CONTEXT_HUB  => forward full scan results in real time and completion events
+     *                                 to context hub
      */
     byte report_events;
     int max_period; // if max_period is non zero or different than period, then this bucket is
@@ -150,7 +171,28 @@ typedef struct {
     wifi_scan_bucket_spec buckets[MAX_BUCKETS];
 } wifi_scan_cmd_params;
 
-/* Start periodic GSCAN */
+/*
+ * Start periodic GSCAN
+ * When this is called all requested buckets should be scanned, starting the beginning of the cycle
+ *
+ * For example:
+ * If there are two buckets specified
+ *  - Bucket 1: period=10s
+ *  - Bucket 2: period=20s
+ *  - Bucket 3: period=30s
+ * Then the following scans should occur
+ *  - t=0  buckets 1, 2, and 3 are scanned
+ *  - t=10 bucket 1 is scanned
+ *  - t=20 bucket 1 and 2 are scanned
+ *  - t=30 bucket 1 and 3 are scanned
+ *  - t=40 bucket 1 and 2 are scanned
+ *  - t=50 bucket 1 is scanned
+ *  - t=60 buckets 1, 2, and 3 are scanned
+ *  - and the patter repeats
+ *
+ * If any scan does not occur or is incomplete (error, interrupted, etc) then a cached scan result
+ * should still be recorded with the WIFI_SCAN_FLAG_INTERRUPTED flag set.
+ */
 wifi_error wifi_start_gscan(wifi_request_id id, wifi_interface_handle iface,
         wifi_scan_cmd_params params, wifi_scan_result_handler handler);
 
@@ -165,8 +207,14 @@ typedef enum {
 /* Get the GSCAN cached scan results */
 typedef struct {
     int scan_id;                                     // a unique identifier for the scan unit
-    int flags;                                       // a bitmask with additional 
-                                                     // information about scan
+    int flags;                                       // a bitmask with additional
+                                                     // information about scan.
+    unsigned buckets_scanned;                        // a bitset of the buckets that were scanned.
+                                                     // for example a value of 13 (0b1101) would
+                                                     // indicate that buckets 0, 2 and 3 were
+                                                     // scanned to produce this list of results.
+                                                     // should be set to 0 if this information is
+                                                     // not available.
     int num_results;                                 // number of bssids retrieved by the scan
     wifi_scan_result results[MAX_AP_CACHE_PER_SCAN]; // scan results - one for each bssid
 } wifi_cached_scan_results;
@@ -222,15 +270,6 @@ typedef struct {
     ssid_threshold_param ssid[MAX_HOTLIST_SSID];    // hotlist SSIDs
 } wifi_ssid_hotlist_params;
 
-
-/* Set the SSID Hotlist */
-wifi_error wifi_set_ssid_hotlist(wifi_request_id id, wifi_interface_handle iface,
-        wifi_ssid_hotlist_params params, wifi_hotlist_ssid_handler handler);
-
-/* Clear the SSID Hotlist */
-wifi_error wifi_reset_ssid_hotlist(wifi_request_id id, wifi_interface_handle iface);
-
-
 /* BSSID blacklist */
 typedef struct {
     int num_bssid;                           // number of blacklisted BSSIDs
@@ -241,7 +280,6 @@ typedef struct {
 wifi_error wifi_set_bssid_blacklist(wifi_request_id id, wifi_interface_handle iface,
         wifi_bssid_params params);
 
-
 /* Significant wifi change */
 typedef struct {
     mac_addr bssid;                     // BSSID
@@ -278,44 +316,78 @@ wifi_error wifi_reset_significant_change_handler(wifi_request_id id, wifi_interf
 /* Random MAC OUI for PNO */
 wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui);
 
-// Whether directed scan needs to be performed (for hidden SSIDs)
-#define WIFI_PNO_FLAG_DIRECTED_SCAN = 1
-// Whether PNO event shall be triggered if the network is found on A band
-#define WIFI_PNO_FLAG_A_BAND = 2
-// Whether PNO event shall be triggered if the network is found on G band
-#define WIFI_PNO_FLAG_G_BAND = 4
-// Whether strict matching is required (i.e. firmware shall not match on the entire SSID)
-#define WIFI_PNO_FLAG_STRICT_MATCH = 8
-
-// Code for matching the beacon AUTH IE - additional codes TBD
-#define WIFI_PNO_AUTH_CODE_OPEN  1 // open
-#define WIFI_PNO_AUTH_CODE_PSK   2 // WPA_PSK or WPA2PSK
-#define WIFI_PNO_AUTH_CODE_EAPOL 4 // any EAPOL
 
 // Enhanced PNO:
 // Enhanced PNO feature is expected to be enabled all of the time (e.g. screen lit) and may thus
-// requires firmware to store a large number of networks, covering the whole list of known network.
+// require firmware to store a large number of networks, covering the whole list of known networks.
 // Therefore, it is acceptable for firmware to store a crc24, crc32 or other short hash of the SSID,
 // such that a low but non-zero probability of collision exist. With that scheme it should be
 // possible for firmware to keep an entry as small as 4 bytes for each pno network.
 // For instance, a firmware pn0 entry can be implemented in the form of:
-//          PNO ENTRY = crc24(3 bytes) | RSSI_THRESHOLD>>3 (5 bits) | auth flags(3 bits)
+//          PNO ENTRY = crc24(3 bytes) | flags>>3 (5 bits) | auth flags(3 bits)
+//
+// No scans should be automatically performed by the chip. Instead all scan results from gscan
+// should be scored and the wifi_epno_handler on_network_found callback should be called with
+// the scan results.
 //
 // A PNO network shall be reported once, that is, once a network is reported by firmware
 // its entry shall be marked as "done" until framework calls wifi_set_epno_list again.
 // Calling wifi_set_epno_list shall reset the "done" status of pno networks in firmware.
+//
+// A network should only be considered found if its RSSI is above the minimum RSSI for its
+// frequency range (min5GHz_rssi and min24GHz_rssi for 5GHz and 2.4GHz networks respectively).
+// When disconnected the list of scan results should be returned if any network is found.
+// When connected the scan results shall be reported only if the score of any network in the scan
+// is greater than that of the currently connected BSSID.
+//
+// The FW should calculate the score of all the candidates (including currently connected one)
+//   with following equation:
+//     RSSI score = (RSSI + 85) * 4;
+//     If RSSI score > initial_score_max , RSSI score = initial_score_max;
+//     final score = RSSI score
+//         + current_connection_bonus (if currently connected BSSID)
+//         + same_network_bonus (if network has SAME_NETWORK flag)
+//         + secure_bonus (if the network is not open)
+//         + band5GHz_bonus (if BSSID is on 5G)
+//     If there is a BSSID’s score > current BSSID’s score, then report the cached scan results
+//         at the end of the scan (excluding the ones on blacklist) to the upper layer.
+// Additionally, all BSSIDs that are in the BSSID blacklist should be ignored by Enhanced PNO
+
+// Whether directed scan needs to be performed (for hidden SSIDs)
+#define WIFI_PNO_FLAG_DIRECTED_SCAN (1 << 0)
+// Whether PNO event shall be triggered if the network is found on A band
+#define WIFI_PNO_FLAG_A_BAND (1 << 1)
+// Whether PNO event shall be triggered if the network is found on G band
+#define WIFI_PNO_FLAG_G_BAND (1 << 2)
+// Whether strict matching is required
+// If required then the firmware must store the network's SSID and not just a hash
+#define WIFI_PNO_FLAG_STRICT_MATCH (1 << 3)
+// If this SSID should be considered the same network as the currently connected one for scoring
+#define WIFI_PNO_FLAG_SAME_NETWORK (1 << 4)
+
+// Code for matching the beacon AUTH IE - additional codes TBD
+#define WIFI_PNO_AUTH_CODE_OPEN  (1 << 0) // open
+#define WIFI_PNO_AUTH_CODE_PSK   (1 << 1) // WPA_PSK or WPA2PSK
+#define WIFI_PNO_AUTH_CODE_EAPOL (1 << 2) // any EAPOL
+
 typedef struct {
-    char ssid[32+1];
-    byte rssi_threshold; // threshold for considering this SSID as found, required granularity for
-                         // this threshold is 4dBm to 8dBm
-    byte flags;          //  WIFI_PNO_FLAG_XXX
+    char ssid[32+1];     // null terminated
+    byte flags;          // WIFI_PNO_FLAG_XXX
     byte auth_bit_field; // auth bit field for matching WPA IE
 } wifi_epno_network;
 
-/* PNO list */
+/* ePNO Parameters */
 typedef struct {
-    int num_networks;                 // number of SSIDs
-    wifi_epno_network networks[];     // PNO networks
+    int min5GHz_rssi;               // minimum 5GHz RSSI for a BSSID to be considered
+    int min24GHz_rssi;              // minimum 2.4GHz RSSI for a BSSID to be considered
+    int initial_score_max;          // the maximum score that a network can have before bonuses
+    int current_connection_bonus;   // only report when there is a network's score this much higher
+                                    // than the current connection.
+    int same_network_bonus;         // score bonus for all networks with the same network flag
+    int secure_bonus;               // score bonus for networks that are not open
+    int band5GHz_bonus;             // 5GHz RSSI score bonus (applied to all 5GHz networks)
+    int num_networks;               // number of wifi_epno_network objects
+    wifi_epno_network networks[MAX_EPNO_NETWORKS];   // PNO networks
 } wifi_epno_params;
 
 typedef struct {
@@ -325,113 +397,13 @@ typedef struct {
 } wifi_epno_handler;
 
 
-/* Set the PNO list */
+/* Set the ePNO list - enable ePNO with the given parameters */
 wifi_error wifi_set_epno_list(wifi_request_id id, wifi_interface_handle iface,
-        int num_networks, wifi_epno_network *networks, wifi_epno_handler handler);
+        const wifi_epno_params *epno_params, wifi_epno_handler handler);
 
+/* Reset the ePNO list - no ePNO networks should be matched after this */
+wifi_error wifi_reset_epno_list(wifi_request_id id, wifi_interface_handle iface);
 
-/* SSID white list */
-/* Note that this feature requires firmware to be able to indicate to kernel sme and wpa_supplicant
- * that the SSID of the network has changed
- * and thus requires further changed in cfg80211 stack, for instance,
- * the below function would change:
-
- void __cfg80211_roamed(struct wireless_dev *wdev,
-                      struct cfg80211_bss *bss,
-                      const u8 *req_ie, size_t req_ie_len,
-                      const u8 *resp_ie, size_t resp_ie_len)
- * when firmware roam to a new SSID the corresponding link layer stats info need to be updated:
-     struct wifi_interface_link_layer_info;
- */
-typedef struct {
-    char ssid[32+1]; // null terminated
-} wifi_ssid;
-
-wifi_error wifi_set_ssid_white_list(wifi_request_id id, wifi_interface_handle iface,
-        int num_networks, wifi_ssid *ssids);
-
-/* Set G-SCAN roam parameters */
-/**
- * Firmware roaming is implemented with two modes:
- *   1- "Alert" mode roaming, (Note: alert roaming is the pre-L roaming, whereas firmware is
- *      "urgently" hunting for another BSSID because the RSSI is low, or because many successive
- *      beacons have been lost or other bad link conditions).
- *   2- "Lazy" mode, where firmware is hunting for a better BSSID or white listed SSID even though
- *      the RSSI of the link is good.
- *      Lazy mode is configured thru G-scan, that is, the results of G-scans are compared to the
- *      current RSSI and fed thru the roaming engine.
- *      Lazy scan will be enabled (and or throttled down by reducing the number of G-scans) by
- *      framework only in certain conditions, such as:
- *          - no real time (VO/VI) traffic at the interface
- *          - low packet rate for BE/BK packets a the interface
- *          - system conditions (screen lit/dark) etc...
- *
- * For consistency, the roam parameters will always be configured by framework such that:
- *
- * condition 1- A_band_boost_threshold >= (alert_roam_rssi_trigger + 10)
- * This condition ensures that Lazy roam doesn't cause the device to roam to a 5GHz BSSID whose RSSI
- * is lower than the alert threshold, which would consequently trigger a roam to a low RSSI BSSID,
- * hence triggering alert mode roaming.
- * In other words, in alert mode, the A_band parameters may safely be ignored by WiFi chipset.
- *
- * condition 2- A_band_boost_threshold > A_band_penalty_factor
- *
- */
-
-/**
- * Example:
- * A_band_boost_threshold = -65
- * A_band_penalty_threshold = -75
- * A_band_boost_factor = 4
- * A_band_penalty_factor = 2
- * A_band_max_boost = 50
- *
- * a 5GHz RSSI value is transformed as below:
- * -20 -> -20+ 50 = 30
- * -60 -> -60 + 4 * (-60 - A_band_boost_threshold) = -60 + 16 = -44
- * -70 -> -70
- * -80 -> -80 - 2 * (A_band_penalty_threshold - (-80)) = -80 - 10 = -90
- */
-
-typedef struct {
-    // Lazy roam parameters
-    // A_band_XX parameters are applied to 5GHz BSSIDs when comparing with a 2.4GHz BSSID
-    // they may not be applied when comparing two 5GHz BSSIDs
-    int A_band_boost_threshold;     // RSSI threshold above which 5GHz RSSI is favored
-    int A_band_penalty_threshold;   // RSSI threshold below which 5GHz RSSI is penalized
-    int A_band_boost_factor;        // factor by which 5GHz RSSI is boosted
-                               // boost=RSSI_measured-5GHz_boost_threshold)*5GHz_boost_factor
-    int A_band_penalty_factor;      // factor by which 5GHz RSSI is penalized
-                               // penalty=(5GHz_penalty_factor-RSSI_measured)*5GHz_penalty_factor
-    int A_band_max_boost;           // maximum boost that can be applied to a 5GHz RSSI
-
-    // Hysteresis: ensuring the currently associated BSSID is favored
-    // so as to prevent ping-pong situations
-    int lazy_roam_hysteresis;       // boost applied to current BSSID
-
-    // Alert mode enable, i.e. configuring when firmware enters alert mode
-    int alert_roam_rssi_trigger;    // RSSI below which "Alert" roam is enabled
-} wifi_roam_params;
-
-wifi_error wifi_set_gscan_roam_params(wifi_request_id id, wifi_interface_handle iface,
-                                        wifi_roam_params * params);
-
-/**
- * Enable/Disable "Lazy" roam
- */
-wifi_error wifi_enable_lazy_roam(wifi_request_id id, wifi_interface_handle iface, int enable);
-
-/**
- * Per BSSID preference
- */
-typedef struct {
-    mac_addr bssid;
-    int rssi_modifier;  // modifier applied to the RSSI of the BSSID for the purpose of comparing
-                        // it with other roam candidate
-} wifi_bssid_preference;
-
-wifi_error wifi_set_bssid_preference(wifi_request_id id, wifi_interface_handle iface,
-                                    int num_bssid, wifi_bssid_preference *prefs);
 
 typedef struct {
     int  id;                            // identifier of this network block, report this in event
@@ -460,4 +432,3 @@ wifi_error wifi_set_passpoint_list(wifi_request_id id, wifi_interface_handle ifa
 wifi_error wifi_reset_passpoint_list(wifi_request_id id, wifi_interface_handle iface);
 
 #endif
-
index e3a6703..387a3c8 100644 (file)
@@ -245,8 +245,9 @@ typedef struct {
     wifi_error (* wifi_get_rtt_capabilities)(wifi_interface_handle, wifi_rtt_capabilities *);
     wifi_error (* wifi_set_nodfs_flag)(wifi_interface_handle, u32);
     wifi_error (* wifi_start_logging)(wifi_interface_handle, u32, u32, u32, u32, char *);
-    wifi_error (* wifi_set_epno_list)(int, wifi_interface_info *, int, wifi_epno_network *,
-            wifi_epno_handler);
+    wifi_error (* wifi_set_epno_list)(wifi_request_id, wifi_interface_handle,
+            const wifi_epno_params *, wifi_epno_handler);
+    wifi_error (* wifi_reset_epno_list)(wifi_request_id, wifi_interface_handle);
     wifi_error (* wifi_set_country_code)(wifi_interface_handle, const char *);
     wifi_error (* wifi_get_firmware_memory_dump)( wifi_interface_handle iface,
             wifi_firmware_memory_dump_handler handler);
@@ -276,14 +277,6 @@ typedef struct {
     wifi_error (* wifi_reset_passpoint_list)(wifi_request_id id, wifi_interface_handle iface);
     wifi_error (*wifi_set_bssid_blacklist)(wifi_request_id id, wifi_interface_handle iface,
                   wifi_bssid_params params);
-    wifi_error (*wifi_enable_lazy_roam)(wifi_request_id id,
-                wifi_interface_handle iface, int enable);
-    wifi_error (*wifi_set_bssid_preference)(wifi_request_id id, wifi_interface_handle iface,
-                                            int num_bssid, wifi_bssid_preference *prefs);
-    wifi_error (*wifi_set_gscan_roam_params)(wifi_request_id id, wifi_interface_handle iface,
-                                                wifi_roam_params * params);
-    wifi_error (*wifi_set_ssid_white_list)(wifi_request_id id, wifi_interface_handle iface,
-                               int num_networks, wifi_ssid *ssids);
     wifi_error (*wifi_set_lci) (wifi_request_id id, wifi_interface_handle iface,
                                     wifi_lci_information *lci);
     wifi_error (*wifi_set_lcr) (wifi_request_id id, wifi_interface_handle iface,