LCOV - code coverage report
Current view: top level - wpa_supplicant - scan.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1426431149 Lines: 844 1230 68.6 %
Date: 2015-03-15 Functions: 47 53 88.7 %

          Line data    Source code
       1             : /*
       2             :  * WPA Supplicant - Scanning
       3             :  * Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "utils/includes.h"
      10             : 
      11             : #include "utils/common.h"
      12             : #include "utils/eloop.h"
      13             : #include "common/ieee802_11_defs.h"
      14             : #include "common/wpa_ctrl.h"
      15             : #include "config.h"
      16             : #include "wpa_supplicant_i.h"
      17             : #include "driver_i.h"
      18             : #include "wps_supplicant.h"
      19             : #include "p2p_supplicant.h"
      20             : #include "p2p/p2p.h"
      21             : #include "hs20_supplicant.h"
      22             : #include "notify.h"
      23             : #include "bss.h"
      24             : #include "scan.h"
      25             : #include "mesh.h"
      26             : 
      27             : 
      28           2 : static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
      29             : {
      30             :         struct wpa_ssid *ssid;
      31             :         union wpa_event_data data;
      32             : 
      33           2 :         ssid = wpa_supplicant_get_ssid(wpa_s);
      34           2 :         if (ssid == NULL)
      35           3 :                 return;
      36             : 
      37           1 :         if (wpa_s->current_ssid == NULL) {
      38           0 :                 wpa_s->current_ssid = ssid;
      39           0 :                 if (wpa_s->current_ssid != NULL)
      40           0 :                         wpas_notify_network_changed(wpa_s);
      41             :         }
      42           1 :         wpa_supplicant_initiate_eapol(wpa_s);
      43           1 :         wpa_dbg(wpa_s, MSG_DEBUG, "Already associated with a configured "
      44             :                 "network - generating associated event");
      45           1 :         os_memset(&data, 0, sizeof(data));
      46           1 :         wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data);
      47             : }
      48             : 
      49             : 
      50             : #ifdef CONFIG_WPS
      51        2020 : static int wpas_wps_in_use(struct wpa_supplicant *wpa_s,
      52             :                            enum wps_request_type *req_type)
      53             : {
      54             :         struct wpa_ssid *ssid;
      55        2020 :         int wps = 0;
      56             : 
      57        3541 :         for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
      58        1627 :                 if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
      59        1216 :                         continue;
      60             : 
      61         411 :                 wps = 1;
      62         411 :                 *req_type = wpas_wps_get_req_type(ssid);
      63         411 :                 if (!ssid->eap.phase1)
      64           0 :                         continue;
      65             : 
      66         411 :                 if (os_strstr(ssid->eap.phase1, "pbc=1"))
      67         106 :                         return 2;
      68             :         }
      69             : 
      70             : #ifdef CONFIG_P2P
      71        3809 :         if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p &&
      72        1895 :             !wpa_s->conf->p2p_disabled) {
      73        1895 :                 wpa_s->wps->dev.p2p = 1;
      74        1895 :                 if (!wps) {
      75        1592 :                         wps = 1;
      76        1592 :                         *req_type = WPS_REQ_ENROLLEE_INFO;
      77             :                 }
      78             :         }
      79             : #endif /* CONFIG_P2P */
      80             : 
      81        1914 :         return wps;
      82             : }
      83             : #endif /* CONFIG_WPS */
      84             : 
      85             : 
      86             : /**
      87             :  * wpa_supplicant_enabled_networks - Check whether there are enabled networks
      88             :  * @wpa_s: Pointer to wpa_supplicant data
      89             :  * Returns: 0 if no networks are enabled, >0 if networks are enabled
      90             :  *
      91             :  * This function is used to figure out whether any networks (or Interworking
      92             :  * with enabled credentials and auto_interworking) are present in the current
      93             :  * configuration.
      94             :  */
      95        3837 : int wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s)
      96             : {
      97        3837 :         struct wpa_ssid *ssid = wpa_s->conf->ssid;
      98        3837 :         int count = 0, disabled = 0;
      99             : 
     100        3837 :         if (wpa_s->p2p_mgmt)
     101           8 :                 return 0; /* no normal network profiles on p2p_mgmt interface */
     102             : 
     103       10140 :         while (ssid) {
     104        2482 :                 if (!wpas_network_disabled(wpa_s, ssid))
     105        2318 :                         count++;
     106             :                 else
     107         164 :                         disabled++;
     108        2482 :                 ssid = ssid->next;
     109             :         }
     110        4077 :         if (wpa_s->conf->cred && wpa_s->conf->interworking &&
     111         248 :             wpa_s->conf->auto_interworking)
     112          28 :                 count++;
     113        3829 :         if (count == 0 && disabled > 0) {
     114          23 :                 wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks (%d disabled "
     115             :                         "networks)", disabled);
     116             :         }
     117        3829 :         return count;
     118             : }
     119             : 
     120             : 
     121          14 : static void wpa_supplicant_assoc_try(struct wpa_supplicant *wpa_s,
     122             :                                      struct wpa_ssid *ssid)
     123             : {
     124          31 :         while (ssid) {
     125          15 :                 if (!wpas_network_disabled(wpa_s, ssid))
     126          12 :                         break;
     127           3 :                 ssid = ssid->next;
     128             :         }
     129             : 
     130             :         /* ap_scan=2 mode - try to associate with each SSID. */
     131          14 :         if (ssid == NULL) {
     132           2 :                 wpa_dbg(wpa_s, MSG_DEBUG, "wpa_supplicant_assoc_try: Reached "
     133             :                         "end of scan list - go back to beginning");
     134           2 :                 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
     135           2 :                 wpa_supplicant_req_scan(wpa_s, 0, 0);
     136          16 :                 return;
     137             :         }
     138          12 :         if (ssid->next) {
     139             :                 /* Continue from the next SSID on the next attempt. */
     140           3 :                 wpa_s->prev_scan_ssid = ssid;
     141             :         } else {
     142             :                 /* Start from the beginning of the SSID list. */
     143           9 :                 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
     144             :         }
     145          12 :         wpa_supplicant_associate(wpa_s, NULL, ssid);
     146             : }
     147             : 
     148             : 
     149        2048 : static void wpas_trigger_scan_cb(struct wpa_radio_work *work, int deinit)
     150             : {
     151        2048 :         struct wpa_supplicant *wpa_s = work->wpa_s;
     152        2048 :         struct wpa_driver_scan_params *params = work->ctx;
     153             :         int ret;
     154             : 
     155        2048 :         if (deinit) {
     156          15 :                 if (!work->started) {
     157           0 :                         wpa_scan_free_params(params);
     158           0 :                         return;
     159             :                 }
     160          15 :                 wpa_supplicant_notify_scanning(wpa_s, 0);
     161          15 :                 wpas_notify_scan_done(wpa_s, 0);
     162          15 :                 wpa_s->scan_work = NULL;
     163          15 :                 return;
     164             :         }
     165             : 
     166        2033 :         if (wpas_update_random_addr_disassoc(wpa_s) < 0) {
     167           0 :                 wpa_msg(wpa_s, MSG_INFO,
     168             :                         "Failed to assign random MAC address for a scan");
     169           0 :                 radio_work_done(work);
     170           0 :                 return;
     171             :         }
     172             : 
     173        2033 :         wpa_supplicant_notify_scanning(wpa_s, 1);
     174             : 
     175        2033 :         if (wpa_s->clear_driver_scan_cache) {
     176        1242 :                 wpa_printf(MSG_DEBUG,
     177             :                            "Request driver to clear scan cache due to local BSS flush");
     178        1242 :                 params->only_new_results = 1;
     179             :         }
     180        2033 :         ret = wpa_drv_scan(wpa_s, params);
     181        2033 :         wpa_scan_free_params(params);
     182        2033 :         work->ctx = NULL;
     183        2033 :         if (ret) {
     184           3 :                 int retry = wpa_s->last_scan_req != MANUAL_SCAN_REQ;
     185             : 
     186           3 :                 if (wpa_s->disconnected)
     187           0 :                         retry = 0;
     188             : 
     189           3 :                 wpa_supplicant_notify_scanning(wpa_s, 0);
     190           3 :                 wpas_notify_scan_done(wpa_s, 0);
     191           3 :                 if (wpa_s->wpa_state == WPA_SCANNING)
     192           2 :                         wpa_supplicant_set_state(wpa_s,
     193             :                                                  wpa_s->scan_prev_wpa_state);
     194           3 :                 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_FAILED "ret=%d%s",
     195             :                         ret, retry ? " retry=1" : "");
     196           3 :                 radio_work_done(work);
     197             : 
     198           3 :                 if (retry) {
     199             :                         /* Restore scan_req since we will try to scan again */
     200           1 :                         wpa_s->scan_req = wpa_s->last_scan_req;
     201           1 :                         wpa_supplicant_req_scan(wpa_s, 1, 0);
     202             :                 }
     203           3 :                 return;
     204             :         }
     205             : 
     206        2030 :         os_get_reltime(&wpa_s->scan_trigger_time);
     207        2030 :         wpa_s->scan_runs++;
     208        2030 :         wpa_s->normal_scans++;
     209        2030 :         wpa_s->own_scan_requested = 1;
     210        2030 :         wpa_s->clear_driver_scan_cache = 0;
     211        2030 :         wpa_s->scan_work = work;
     212             : }
     213             : 
     214             : 
     215             : /**
     216             :  * wpa_supplicant_trigger_scan - Request driver to start a scan
     217             :  * @wpa_s: Pointer to wpa_supplicant data
     218             :  * @params: Scan parameters
     219             :  * Returns: 0 on success, -1 on failure
     220             :  */
     221        2035 : int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
     222             :                                 struct wpa_driver_scan_params *params)
     223             : {
     224             :         struct wpa_driver_scan_params *ctx;
     225             : 
     226        2035 :         if (wpa_s->scan_work) {
     227           1 :                 wpa_dbg(wpa_s, MSG_INFO, "Reject scan trigger since one is already pending");
     228           1 :                 return -1;
     229             :         }
     230             : 
     231        2034 :         ctx = wpa_scan_clone_params(params);
     232        2034 :         if (ctx == NULL)
     233           1 :                 return -1;
     234             : 
     235        2033 :         if (radio_add_work(wpa_s, 0, "scan", 0, wpas_trigger_scan_cb, ctx) < 0)
     236             :         {
     237           0 :                 wpa_scan_free_params(ctx);
     238           0 :                 return -1;
     239             :         }
     240             : 
     241        2033 :         return 0;
     242             : }
     243             : 
     244             : 
     245             : static void
     246           0 : wpa_supplicant_delayed_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx)
     247             : {
     248           0 :         struct wpa_supplicant *wpa_s = eloop_ctx;
     249             : 
     250           0 :         wpa_dbg(wpa_s, MSG_DEBUG, "Starting delayed sched scan");
     251             : 
     252           0 :         if (wpa_supplicant_req_sched_scan(wpa_s))
     253           0 :                 wpa_supplicant_req_scan(wpa_s, 0, 0);
     254           0 : }
     255             : 
     256             : 
     257             : static void
     258           0 : wpa_supplicant_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx)
     259             : {
     260           0 :         struct wpa_supplicant *wpa_s = eloop_ctx;
     261             : 
     262           0 :         wpa_dbg(wpa_s, MSG_DEBUG, "Sched scan timeout - stopping it");
     263             : 
     264           0 :         wpa_s->sched_scan_timed_out = 1;
     265           0 :         wpa_supplicant_cancel_sched_scan(wpa_s);
     266           0 : }
     267             : 
     268             : 
     269           0 : int wpa_supplicant_start_sched_scan(struct wpa_supplicant *wpa_s,
     270             :                                     struct wpa_driver_scan_params *params,
     271             :                                     int interval)
     272             : {
     273             :         int ret;
     274             : 
     275           0 :         wpa_supplicant_notify_scanning(wpa_s, 1);
     276           0 :         ret = wpa_drv_sched_scan(wpa_s, params, interval * 1000);
     277           0 :         if (ret)
     278           0 :                 wpa_supplicant_notify_scanning(wpa_s, 0);
     279             :         else
     280           0 :                 wpa_s->sched_scanning = 1;
     281             : 
     282           0 :         return ret;
     283             : }
     284             : 
     285             : 
     286           0 : int wpa_supplicant_stop_sched_scan(struct wpa_supplicant *wpa_s)
     287             : {
     288             :         int ret;
     289             : 
     290           0 :         ret = wpa_drv_stop_sched_scan(wpa_s);
     291           0 :         if (ret) {
     292           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "stopping sched_scan failed!");
     293             :                 /* TODO: what to do if stopping fails? */
     294           0 :                 return -1;
     295             :         }
     296             : 
     297           0 :         return ret;
     298             : }
     299             : 
     300             : 
     301             : static struct wpa_driver_scan_filter *
     302        2020 : wpa_supplicant_build_filter_ssids(struct wpa_config *conf, size_t *num_ssids)
     303             : {
     304             :         struct wpa_driver_scan_filter *ssids;
     305             :         struct wpa_ssid *ssid;
     306             :         size_t count;
     307             : 
     308        2020 :         *num_ssids = 0;
     309        2020 :         if (!conf->filter_ssids)
     310        2017 :                 return NULL;
     311             : 
     312           7 :         for (count = 0, ssid = conf->ssid; ssid; ssid = ssid->next) {
     313           4 :                 if (ssid->ssid && ssid->ssid_len)
     314           2 :                         count++;
     315             :         }
     316           3 :         if (count == 0)
     317           1 :                 return NULL;
     318           2 :         ssids = os_calloc(count, sizeof(struct wpa_driver_scan_filter));
     319           2 :         if (ssids == NULL)
     320           0 :                 return NULL;
     321             : 
     322           5 :         for (ssid = conf->ssid; ssid; ssid = ssid->next) {
     323           3 :                 if (!ssid->ssid || !ssid->ssid_len)
     324           1 :                         continue;
     325           2 :                 os_memcpy(ssids[*num_ssids].ssid, ssid->ssid, ssid->ssid_len);
     326           2 :                 ssids[*num_ssids].ssid_len = ssid->ssid_len;
     327           2 :                 (*num_ssids)++;
     328             :         }
     329             : 
     330           2 :         return ssids;
     331             : }
     332             : 
     333             : 
     334        2020 : static void wpa_supplicant_optimize_freqs(
     335             :         struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params)
     336             : {
     337             : #ifdef CONFIG_P2P
     338        2266 :         if (params->freqs == NULL && wpa_s->p2p_in_provisioning &&
     339         246 :             wpa_s->go_params) {
     340             :                 /* Optimize provisioning state scan based on GO information */
     341         488 :                 if (wpa_s->p2p_in_provisioning < 5 &&
     342         242 :                     wpa_s->go_params->freq > 0) {
     343         242 :                         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO "
     344             :                                 "preferred frequency %d MHz",
     345             :                                 wpa_s->go_params->freq);
     346         242 :                         params->freqs = os_calloc(2, sizeof(int));
     347         484 :                         if (params->freqs)
     348         242 :                                 params->freqs[0] = wpa_s->go_params->freq;
     349           8 :                 } else if (wpa_s->p2p_in_provisioning < 8 &&
     350           4 :                            wpa_s->go_params->freq_list[0]) {
     351           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only common "
     352             :                                 "channels");
     353           0 :                         int_array_concat(&params->freqs,
     354           0 :                                          wpa_s->go_params->freq_list);
     355           0 :                         if (params->freqs)
     356           0 :                                 int_array_sort_unique(params->freqs);
     357             :                 }
     358         246 :                 wpa_s->p2p_in_provisioning++;
     359             :         }
     360             : 
     361        2020 :         if (params->freqs == NULL && wpa_s->p2p_in_invitation) {
     362             :                 /*
     363             :                  * Optimize scan based on GO information during persistent
     364             :                  * group reinvocation
     365             :                  */
     366          30 :                 if (wpa_s->p2p_in_invitation < 5 &&
     367          15 :                     wpa_s->p2p_invite_go_freq > 0) {
     368          12 :                         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO preferred frequency %d MHz during invitation",
     369             :                                 wpa_s->p2p_invite_go_freq);
     370          12 :                         params->freqs = os_calloc(2, sizeof(int));
     371          12 :                         if (params->freqs)
     372          12 :                                 params->freqs[0] = wpa_s->p2p_invite_go_freq;
     373             :                 }
     374          15 :                 wpa_s->p2p_in_invitation++;
     375          15 :                 if (wpa_s->p2p_in_invitation > 20) {
     376             :                         /*
     377             :                          * This should not really happen since the variable is
     378             :                          * cleared on group removal, but if it does happen, make
     379             :                          * sure we do not get stuck in special invitation scan
     380             :                          * mode.
     381             :                          */
     382           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Clear p2p_in_invitation");
     383           0 :                         wpa_s->p2p_in_invitation = 0;
     384             :                 }
     385             :         }
     386             : #endif /* CONFIG_P2P */
     387             : 
     388             : #ifdef CONFIG_WPS
     389        2020 :         if (params->freqs == NULL && wpa_s->after_wps && wpa_s->wps_freq) {
     390             :                 /*
     391             :                  * Optimize post-provisioning scan based on channel used
     392             :                  * during provisioning.
     393             :                  */
     394          33 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz "
     395             :                         "that was used during provisioning", wpa_s->wps_freq);
     396          33 :                 params->freqs = os_calloc(2, sizeof(int));
     397          33 :                 if (params->freqs)
     398          33 :                         params->freqs[0] = wpa_s->wps_freq;
     399          33 :                 wpa_s->after_wps--;
     400        1987 :         } else if (wpa_s->after_wps)
     401           1 :                 wpa_s->after_wps--;
     402             : 
     403        2020 :         if (params->freqs == NULL && wpa_s->known_wps_freq && wpa_s->wps_freq)
     404             :         {
     405             :                 /* Optimize provisioning scan based on already known channel */
     406          81 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz",
     407             :                         wpa_s->wps_freq);
     408          81 :                 params->freqs = os_calloc(2, sizeof(int));
     409          81 :                 if (params->freqs)
     410          81 :                         params->freqs[0] = wpa_s->wps_freq;
     411          81 :                 wpa_s->known_wps_freq = 0; /* only do this once */
     412             :         }
     413             : #endif /* CONFIG_WPS */
     414        2020 : }
     415             : 
     416             : 
     417             : #ifdef CONFIG_INTERWORKING
     418         673 : static void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s,
     419             :                                            struct wpabuf *buf)
     420             : {
     421         673 :         if (wpa_s->conf->interworking == 0)
     422         673 :                 return;
     423             : 
     424         673 :         wpabuf_put_u8(buf, WLAN_EID_EXT_CAPAB);
     425         673 :         wpabuf_put_u8(buf, 6);
     426         673 :         wpabuf_put_u8(buf, 0x00);
     427         673 :         wpabuf_put_u8(buf, 0x00);
     428         673 :         wpabuf_put_u8(buf, 0x00);
     429         673 :         wpabuf_put_u8(buf, 0x80); /* Bit 31 - Interworking */
     430         673 :         wpabuf_put_u8(buf, 0x00);
     431             : #ifdef CONFIG_HS20
     432         673 :         wpabuf_put_u8(buf, 0x40); /* Bit 46 - WNM-Notification */
     433             : #else /* CONFIG_HS20 */
     434             :         wpabuf_put_u8(buf, 0x00);
     435             : #endif /* CONFIG_HS20 */
     436             : 
     437         673 :         wpabuf_put_u8(buf, WLAN_EID_INTERWORKING);
     438         673 :         wpabuf_put_u8(buf, is_zero_ether_addr(wpa_s->conf->hessid) ? 1 :
     439             :                       1 + ETH_ALEN);
     440         673 :         wpabuf_put_u8(buf, wpa_s->conf->access_network_type);
     441             :         /* No Venue Info */
     442         673 :         if (!is_zero_ether_addr(wpa_s->conf->hessid))
     443           4 :                 wpabuf_put_data(buf, wpa_s->conf->hessid, ETH_ALEN);
     444             : }
     445             : #endif /* CONFIG_INTERWORKING */
     446             : 
     447             : 
     448        2020 : static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
     449             : {
     450        2020 :         struct wpabuf *extra_ie = NULL;
     451             : #ifdef CONFIG_WPS
     452        2020 :         int wps = 0;
     453        2020 :         enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO;
     454             : #endif /* CONFIG_WPS */
     455             : 
     456             : #ifdef CONFIG_INTERWORKING
     457        2693 :         if (wpa_s->conf->interworking &&
     458         673 :             wpabuf_resize(&extra_ie, 100) == 0)
     459         673 :                 wpas_add_interworking_elements(wpa_s, extra_ie);
     460             : #endif /* CONFIG_INTERWORKING */
     461             : 
     462             : #ifdef CONFIG_WPS
     463        2020 :         wps = wpas_wps_in_use(wpa_s, &req_type);
     464             : 
     465        2020 :         if (wps) {
     466             :                 struct wpabuf *wps_ie;
     467        4006 :                 wps_ie = wps_build_probe_req_ie(wps == 2 ? DEV_PW_PUSHBUTTON :
     468             :                                                 DEV_PW_DEFAULT,
     469        2003 :                                                 &wpa_s->wps->dev,
     470        2003 :                                                 wpa_s->wps->uuid, req_type,
     471             :                                                 0, NULL);
     472        2003 :                 if (wps_ie) {
     473        2003 :                         if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0)
     474        2002 :                                 wpabuf_put_buf(extra_ie, wps_ie);
     475        2003 :                         wpabuf_free(wps_ie);
     476             :                 }
     477             :         }
     478             : 
     479             : #ifdef CONFIG_P2P
     480        2020 :         if (wps) {
     481        2003 :                 size_t ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
     482        2003 :                 if (wpabuf_resize(&extra_ie, ielen) == 0)
     483        2003 :                         wpas_p2p_scan_ie(wpa_s, extra_ie);
     484             :         }
     485             : #endif /* CONFIG_P2P */
     486             : 
     487        2020 :         wpa_supplicant_mesh_add_scan_ie(wpa_s, &extra_ie);
     488             : 
     489             : #endif /* CONFIG_WPS */
     490             : 
     491             : #ifdef CONFIG_HS20
     492        2020 :         if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 7) == 0)
     493         673 :                 wpas_hs20_add_indication(extra_ie, -1);
     494             : #endif /* CONFIG_HS20 */
     495             : 
     496        2020 :         return extra_ie;
     497             : }
     498             : 
     499             : 
     500             : #ifdef CONFIG_P2P
     501             : 
     502             : /*
     503             :  * Check whether there are any enabled networks or credentials that could be
     504             :  * used for a non-P2P connection.
     505             :  */
     506          42 : static int non_p2p_network_enabled(struct wpa_supplicant *wpa_s)
     507             : {
     508             :         struct wpa_ssid *ssid;
     509             : 
     510          44 :         for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
     511          44 :                 if (wpas_network_disabled(wpa_s, ssid))
     512           2 :                         continue;
     513          42 :                 if (!ssid->p2p_group)
     514          42 :                         return 1;
     515             :         }
     516             : 
     517           0 :         if (wpa_s->conf->cred && wpa_s->conf->interworking &&
     518           0 :             wpa_s->conf->auto_interworking)
     519           0 :                 return 1;
     520             : 
     521           0 :         return 0;
     522             : }
     523             : 
     524             : #endif /* CONFIG_P2P */
     525             : 
     526             : 
     527           2 : static struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
     528             :                                           u16 num_modes,
     529             :                                           enum hostapd_hw_mode mode)
     530             : {
     531             :         u16 i;
     532             : 
     533           3 :         for (i = 0; i < num_modes; i++) {
     534           3 :                 if (modes[i].mode == mode)
     535           2 :                         return &modes[i];
     536             :         }
     537             : 
     538           0 :         return NULL;
     539             : }
     540             : 
     541             : 
     542           2 : static void wpa_setband_scan_freqs_list(struct wpa_supplicant *wpa_s,
     543             :                                         enum hostapd_hw_mode band,
     544             :                                         struct wpa_driver_scan_params *params)
     545             : {
     546             :         /* Include only supported channels for the specified band */
     547             :         struct hostapd_hw_modes *mode;
     548             :         int count, i;
     549             : 
     550           2 :         mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band);
     551           2 :         if (mode == NULL) {
     552             :                 /* No channels supported in this band - use empty list */
     553           0 :                 params->freqs = os_zalloc(sizeof(int));
     554           0 :                 return;
     555             :         }
     556             : 
     557           2 :         params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
     558           2 :         if (params->freqs == NULL)
     559           0 :                 return;
     560          40 :         for (count = 0, i = 0; i < mode->num_channels; i++) {
     561          38 :                 if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
     562          14 :                         continue;
     563          24 :                 params->freqs[count++] = mode->channels[i].freq;
     564             :         }
     565             : }
     566             : 
     567             : 
     568        2020 : static void wpa_setband_scan_freqs(struct wpa_supplicant *wpa_s,
     569             :                                    struct wpa_driver_scan_params *params)
     570             : {
     571        2020 :         if (wpa_s->hw.modes == NULL)
     572          15 :                 return; /* unknown what channels the driver supports */
     573        2005 :         if (params->freqs)
     574        1839 :                 return; /* already using a limited channel set */
     575         166 :         if (wpa_s->setband == WPA_SETBAND_5G)
     576           1 :                 wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A,
     577             :                                             params);
     578         165 :         else if (wpa_s->setband == WPA_SETBAND_2G)
     579           1 :                 wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G,
     580             :                                             params);
     581             : }
     582             : 
     583             : 
     584           2 : static void wpa_set_scan_ssids(struct wpa_supplicant *wpa_s,
     585             :                                struct wpa_driver_scan_params *params,
     586             :                                size_t max_ssids)
     587             : {
     588             :         unsigned int i;
     589             :         struct wpa_ssid *ssid;
     590             : 
     591           6 :         for (i = 0; i < wpa_s->scan_id_count; i++) {
     592             :                 unsigned int j;
     593             : 
     594           4 :                 ssid = wpa_config_get_network(wpa_s->conf, wpa_s->scan_id[i]);
     595           4 :                 if (!ssid || !ssid->scan_ssid)
     596           1 :                         continue;
     597             : 
     598           4 :                 for (j = 0; j < params->num_ssids; j++) {
     599           1 :                         if (params->ssids[j].ssid_len == ssid->ssid_len &&
     600           0 :                             params->ssids[j].ssid &&
     601           0 :                             os_memcmp(params->ssids[j].ssid, ssid->ssid,
     602             :                                       ssid->ssid_len) == 0)
     603           0 :                                 break;
     604             :                 }
     605           3 :                 if (j < params->num_ssids)
     606           0 :                         continue; /* already in the list */
     607             : 
     608           3 :                 if (params->num_ssids + 1 > max_ssids) {
     609           0 :                         wpa_printf(MSG_DEBUG,
     610             :                                    "Over max scan SSIDs for manual request");
     611           0 :                         break;
     612             :                 }
     613             : 
     614           6 :                 wpa_printf(MSG_DEBUG, "Scan SSID (manual request): %s",
     615           3 :                            wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
     616           3 :                 params->ssids[params->num_ssids].ssid = ssid->ssid;
     617           3 :                 params->ssids[params->num_ssids].ssid_len = ssid->ssid_len;
     618           3 :                 params->num_ssids++;
     619             :         }
     620             : 
     621           2 :         wpa_s->scan_id_count = 0;
     622           2 : }
     623             : 
     624             : 
     625        3047 : static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
     626             : {
     627        3047 :         struct wpa_supplicant *wpa_s = eloop_ctx;
     628             :         struct wpa_ssid *ssid;
     629             :         int ret, p2p_in_prog;
     630        3047 :         struct wpabuf *extra_ie = NULL;
     631             :         struct wpa_driver_scan_params params;
     632             :         struct wpa_driver_scan_params *scan_params;
     633             :         size_t max_ssids;
     634        3047 :         int connect_without_scan = 0;
     635             : 
     636        3047 :         if (wpa_s->pno || wpa_s->pno_sched_pending) {
     637           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - PNO is in progress");
     638           0 :                 return;
     639             :         }
     640             : 
     641        3047 :         if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
     642           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - interface disabled");
     643           0 :                 return;
     644             :         }
     645             : 
     646        3047 :         if (wpa_s->disconnected && wpa_s->scan_req == NORMAL_SCAN_REQ) {
     647           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Disconnected - do not scan");
     648           0 :                 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
     649           0 :                 return;
     650             :         }
     651             : 
     652        3047 :         if (wpa_s->scanning) {
     653             :                 /*
     654             :                  * If we are already in scanning state, we shall reschedule the
     655             :                  * the incoming scan request.
     656             :                  */
     657           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Already scanning - Reschedule the incoming scan req");
     658           0 :                 wpa_supplicant_req_scan(wpa_s, 1, 0);
     659           0 :                 return;
     660             :         }
     661             : 
     662        4206 :         if (!wpa_supplicant_enabled_networks(wpa_s) &&
     663        1159 :             wpa_s->scan_req == NORMAL_SCAN_REQ) {
     664         678 :                 wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan");
     665         678 :                 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
     666         678 :                 return;
     667             :         }
     668             : 
     669        4736 :         if (wpa_s->conf->ap_scan != 0 &&
     670        2367 :             (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)) {
     671           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Using wired authentication - "
     672             :                         "overriding ap_scan configuration");
     673           0 :                 wpa_s->conf->ap_scan = 0;
     674           0 :                 wpas_notify_ap_scan_changed(wpa_s);
     675             :         }
     676             : 
     677        2369 :         if (wpa_s->conf->ap_scan == 0) {
     678           2 :                 wpa_supplicant_gen_assoc_event(wpa_s);
     679           2 :                 return;
     680             :         }
     681             : 
     682        2367 :         ssid = NULL;
     683        4077 :         if (wpa_s->scan_req != MANUAL_SCAN_REQ &&
     684        1710 :             wpa_s->connect_without_scan) {
     685         332 :                 connect_without_scan = 1;
     686         364 :                 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
     687         364 :                         if (ssid == wpa_s->connect_without_scan)
     688         332 :                                 break;
     689             :                 }
     690             :         }
     691             : 
     692        2367 :         p2p_in_prog = wpas_p2p_in_progress(wpa_s);
     693        2367 :         if (p2p_in_prog && p2p_in_prog != 2 &&
     694          62 :             (!ssid ||
     695         124 :              (ssid->mode != WPAS_MODE_AP && ssid->mode != WPAS_MODE_P2P_GO))) {
     696           1 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Delay station mode scan while P2P operation is in progress");
     697           1 :                 wpa_supplicant_req_scan(wpa_s, 5, 0);
     698           1 :                 return;
     699             :         }
     700             : 
     701        2366 :         if (wpa_s->conf->ap_scan == 2)
     702          16 :                 max_ssids = 1;
     703             :         else {
     704        2350 :                 max_ssids = wpa_s->max_scan_ssids;
     705        2350 :                 if (max_ssids > WPAS_MAX_SCAN_SSIDS)
     706          15 :                         max_ssids = WPAS_MAX_SCAN_SSIDS;
     707             :         }
     708             : 
     709        2366 :         wpa_s->last_scan_req = wpa_s->scan_req;
     710        2366 :         wpa_s->scan_req = NORMAL_SCAN_REQ;
     711             : 
     712        2366 :         if (connect_without_scan) {
     713         332 :                 wpa_s->connect_without_scan = NULL;
     714         332 :                 if (ssid) {
     715         332 :                         wpa_printf(MSG_DEBUG, "Start a pre-selected network "
     716             :                                    "without scan step");
     717         332 :                         wpa_supplicant_associate(wpa_s, NULL, ssid);
     718         332 :                         return;
     719             :                 }
     720             :         }
     721             : 
     722        2034 :         os_memset(&params, 0, sizeof(params));
     723             : 
     724        2034 :         wpa_s->scan_prev_wpa_state = wpa_s->wpa_state;
     725        3209 :         if (wpa_s->wpa_state == WPA_DISCONNECTED ||
     726        1175 :             wpa_s->wpa_state == WPA_INACTIVE)
     727        1582 :                 wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
     728             : 
     729             :         /*
     730             :          * If autoscan has set its own scanning parameters
     731             :          */
     732        2034 :         if (wpa_s->autoscan_params != NULL) {
     733           0 :                 scan_params = wpa_s->autoscan_params;
     734           0 :                 goto scan;
     735             :         }
     736             : 
     737             : #ifdef CONFIG_P2P
     738        2295 :         if ((wpa_s->p2p_in_provisioning || wpa_s->show_group_started) &&
     739         507 :             wpa_s->go_params && !wpa_s->conf->passive_scan) {
     740         239 :                 wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during P2P group formation (p2p_in_provisioning=%d show_group_started=%d)",
     741             :                            wpa_s->p2p_in_provisioning,
     742             :                            wpa_s->show_group_started);
     743         239 :                 params.ssids[0].ssid = wpa_s->go_params->ssid;
     744         239 :                 params.ssids[0].ssid_len = wpa_s->go_params->ssid_len;
     745         239 :                 params.num_ssids = 1;
     746         239 :                 goto ssid_list_set;
     747             :         }
     748             : 
     749        1795 :         if (wpa_s->p2p_in_invitation) {
     750          15 :                 if (wpa_s->current_ssid) {
     751           5 :                         wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during invitation");
     752           5 :                         params.ssids[0].ssid = wpa_s->current_ssid->ssid;
     753           5 :                         params.ssids[0].ssid_len =
     754           5 :                                 wpa_s->current_ssid->ssid_len;
     755           5 :                         params.num_ssids = 1;
     756             :                 } else {
     757          10 :                         wpa_printf(MSG_DEBUG, "P2P: No specific SSID known for scan during invitation");
     758             :                 }
     759          15 :                 goto ssid_list_set;
     760             :         }
     761             : #endif /* CONFIG_P2P */
     762             : 
     763             :         /* Find the starting point from which to continue scanning */
     764        1780 :         ssid = wpa_s->conf->ssid;
     765        1780 :         if (wpa_s->prev_scan_ssid != WILDCARD_SSID_SCAN) {
     766          12 :                 while (ssid) {
     767           6 :                         if (ssid == wpa_s->prev_scan_ssid) {
     768           4 :                                 ssid = ssid->next;
     769           4 :                                 break;
     770             :                         }
     771           2 :                         ssid = ssid->next;
     772             :                 }
     773             :         }
     774             : 
     775        2904 :         if (wpa_s->last_scan_req != MANUAL_SCAN_REQ &&
     776        1124 :             wpa_s->conf->ap_scan == 2) {
     777          14 :                 wpa_s->connect_without_scan = NULL;
     778          14 :                 wpa_s->prev_scan_wildcard = 0;
     779          14 :                 wpa_supplicant_assoc_try(wpa_s, ssid);
     780          14 :                 return;
     781        1766 :         } else if (wpa_s->conf->ap_scan == 2) {
     782             :                 /*
     783             :                  * User-initiated scan request in ap_scan == 2; scan with
     784             :                  * wildcard SSID.
     785             :                  */
     786           2 :                 ssid = NULL;
     787        1764 :         } else if (wpa_s->reattach && wpa_s->current_ssid != NULL) {
     788             :                 /*
     789             :                  * Perform single-channel single-SSID scan for
     790             :                  * reassociate-to-same-BSS operation.
     791             :                  */
     792             :                 /* Setup SSID */
     793           1 :                 ssid = wpa_s->current_ssid;
     794           2 :                 wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
     795           1 :                                   ssid->ssid, ssid->ssid_len);
     796           1 :                 params.ssids[0].ssid = ssid->ssid;
     797           1 :                 params.ssids[0].ssid_len = ssid->ssid_len;
     798           1 :                 params.num_ssids = 1;
     799             : 
     800             :                 /*
     801             :                  * Allocate memory for frequency array, allocate one extra
     802             :                  * slot for the zero-terminator.
     803             :                  */
     804           1 :                 params.freqs = os_malloc(sizeof(int) * 2);
     805           1 :                 if (params.freqs == NULL) {
     806           0 :                         wpa_dbg(wpa_s, MSG_ERROR, "Memory allocation failed");
     807           0 :                         return;
     808             :                 }
     809           1 :                 params.freqs[0] = wpa_s->assoc_freq;
     810           1 :                 params.freqs[1] = 0;
     811             : 
     812             :                 /*
     813             :                  * Reset the reattach flag so that we fall back to full scan if
     814             :                  * this scan fails.
     815             :                  */
     816           1 :                 wpa_s->reattach = 0;
     817             :         } else {
     818        1763 :                 struct wpa_ssid *start = ssid, *tssid;
     819        1763 :                 int freqs_set = 0;
     820        1763 :                 if (ssid == NULL && max_ssids > 1)
     821         467 :                         ssid = wpa_s->conf->ssid;
     822        4862 :                 while (ssid) {
     823        2630 :                         if (!wpas_network_disabled(wpa_s, ssid) &&
     824        1289 :                             ssid->scan_ssid) {
     825          28 :                                 wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
     826          14 :                                                   ssid->ssid, ssid->ssid_len);
     827          28 :                                 params.ssids[params.num_ssids].ssid =
     828          14 :                                         ssid->ssid;
     829          28 :                                 params.ssids[params.num_ssids].ssid_len =
     830          14 :                                         ssid->ssid_len;
     831          14 :                                 params.num_ssids++;
     832          14 :                                 if (params.num_ssids + 1 >= max_ssids)
     833           4 :                                         break;
     834             :                         }
     835        1337 :                         ssid = ssid->next;
     836        1337 :                         if (ssid == start)
     837           1 :                                 break;
     838        2615 :                         if (ssid == NULL && max_ssids > 1 &&
     839        1279 :                             start != wpa_s->conf->ssid)
     840           0 :                                 ssid = wpa_s->conf->ssid;
     841             :                 }
     842             : 
     843        1765 :                 if (wpa_s->scan_id_count &&
     844           2 :                     wpa_s->last_scan_req == MANUAL_SCAN_REQ)
     845           2 :                         wpa_set_scan_ssids(wpa_s, &params, max_ssids);
     846             : 
     847        4681 :                 for (tssid = wpa_s->conf->ssid;
     848        5182 :                      wpa_s->last_scan_req != MANUAL_SCAN_REQ && tssid;
     849        1155 :                      tssid = tssid->next) {
     850        1155 :                         if (wpas_network_disabled(wpa_s, tssid))
     851          30 :                                 continue;
     852        1125 :                         if ((params.freqs || !freqs_set) && tssid->scan_freq) {
     853         875 :                                 int_array_concat(&params.freqs,
     854         875 :                                                  tssid->scan_freq);
     855             :                         } else {
     856         250 :                                 os_free(params.freqs);
     857         250 :                                 params.freqs = NULL;
     858             :                         }
     859        1125 :                         freqs_set = 1;
     860             :                 }
     861        1763 :                 int_array_sort_unique(params.freqs);
     862             :         }
     863             : 
     864        1766 :         if (ssid && max_ssids == 1) {
     865             :                 /*
     866             :                  * If the driver is limited to 1 SSID at a time interleave
     867             :                  * wildcard SSID scans with specific SSID scans to avoid
     868             :                  * waiting a long time for a wildcard scan.
     869             :                  */
     870           4 :                 if (!wpa_s->prev_scan_wildcard) {
     871           1 :                         params.ssids[0].ssid = NULL;
     872           1 :                         params.ssids[0].ssid_len = 0;
     873           1 :                         wpa_s->prev_scan_wildcard = 1;
     874           1 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for "
     875             :                                 "wildcard SSID (Interleave with specific)");
     876             :                 } else {
     877           1 :                         wpa_s->prev_scan_ssid = ssid;
     878           1 :                         wpa_s->prev_scan_wildcard = 0;
     879           1 :                         wpa_dbg(wpa_s, MSG_DEBUG,
     880             :                                 "Starting AP scan for specific SSID: %s",
     881             :                                 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
     882             :                 }
     883        1764 :         } else if (ssid) {
     884             :                 /* max_ssids > 1 */
     885             : 
     886           3 :                 wpa_s->prev_scan_ssid = ssid;
     887           3 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Include wildcard SSID in "
     888             :                         "the scan request");
     889           3 :                 params.num_ssids++;
     890        1761 :         } else if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
     891           2 :                    wpa_s->manual_scan_passive && params.num_ssids == 0) {
     892           2 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Use passive scan based on manual request");
     893        1759 :         } else if (wpa_s->conf->passive_scan) {
     894           7 :                 wpa_dbg(wpa_s, MSG_DEBUG,
     895             :                         "Use passive scan based on configuration");
     896             :         } else {
     897        1752 :                 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
     898        1752 :                 params.num_ssids++;
     899        1752 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for wildcard "
     900             :                         "SSID");
     901             :         }
     902             : #ifdef CONFIG_P2P
     903             : ssid_list_set:
     904             : #endif /* CONFIG_P2P */
     905             : 
     906        2020 :         wpa_supplicant_optimize_freqs(wpa_s, &params);
     907        2020 :         extra_ie = wpa_supplicant_extra_ies(wpa_s);
     908             : 
     909        2020 :         if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
     910             :             wpa_s->manual_scan_only_new) {
     911         165 :                 wpa_printf(MSG_DEBUG,
     912             :                            "Request driver to clear scan cache due to manual only_new=1 scan");
     913         165 :                 params.only_new_results = 1;
     914             :         }
     915             : 
     916        2675 :         if (wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs == NULL &&
     917         655 :             wpa_s->manual_scan_freqs) {
     918         619 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Limit manual scan to specified channels");
     919         619 :                 params.freqs = wpa_s->manual_scan_freqs;
     920         619 :                 wpa_s->manual_scan_freqs = NULL;
     921             :         }
     922             : 
     923        2020 :         if (params.freqs == NULL && wpa_s->next_scan_freqs) {
     924           2 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Optimize scan based on previously "
     925             :                         "generated frequency list");
     926           2 :                 params.freqs = wpa_s->next_scan_freqs;
     927             :         } else
     928        2018 :                 os_free(wpa_s->next_scan_freqs);
     929        2020 :         wpa_s->next_scan_freqs = NULL;
     930        2020 :         wpa_setband_scan_freqs(wpa_s, &params);
     931             : 
     932             :         /* See if user specified frequencies. If so, scan only those. */
     933        2020 :         if (wpa_s->conf->freq_list && !params.freqs) {
     934           0 :                 wpa_dbg(wpa_s, MSG_DEBUG,
     935             :                         "Optimize scan based on conf->freq_list");
     936           0 :                 int_array_concat(&params.freqs, wpa_s->conf->freq_list);
     937             :         }
     938             : 
     939             :         /* Use current associated channel? */
     940        2020 :         if (wpa_s->conf->scan_cur_freq && !params.freqs) {
     941           0 :                 unsigned int num = wpa_s->num_multichan_concurrent;
     942             : 
     943           0 :                 params.freqs = os_calloc(num + 1, sizeof(int));
     944           0 :                 if (params.freqs) {
     945           0 :                         num = get_shared_radio_freqs(wpa_s, params.freqs, num);
     946           0 :                         if (num > 0) {
     947           0 :                                 wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the "
     948             :                                         "current operating channels since "
     949             :                                         "scan_cur_freq is enabled");
     950             :                         } else {
     951           0 :                                 os_free(params.freqs);
     952           0 :                                 params.freqs = NULL;
     953             :                         }
     954             :                 }
     955             :         }
     956             : 
     957        2020 :         params.filter_ssids = wpa_supplicant_build_filter_ssids(
     958             :                 wpa_s->conf, &params.num_filter_ssids);
     959        2020 :         if (extra_ie) {
     960        2020 :                 params.extra_ies = wpabuf_head(extra_ie);
     961        2020 :                 params.extra_ies_len = wpabuf_len(extra_ie);
     962             :         }
     963             : 
     964             : #ifdef CONFIG_P2P
     965        3779 :         if (wpa_s->p2p_in_provisioning || wpa_s->p2p_in_invitation ||
     966        1759 :             (wpa_s->show_group_started && wpa_s->go_params)) {
     967             :                 /*
     968             :                  * The interface may not yet be in P2P mode, so we have to
     969             :                  * explicitly request P2P probe to disable CCK rates.
     970             :                  */
     971         261 :                 params.p2p_probe = 1;
     972             :         }
     973             : #endif /* CONFIG_P2P */
     974             : 
     975        2020 :         if (wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCAN) {
     976           3 :                 params.mac_addr_rand = 1;
     977           3 :                 if (wpa_s->mac_addr_scan) {
     978           2 :                         params.mac_addr = wpa_s->mac_addr_scan;
     979           2 :                         params.mac_addr_mask = wpa_s->mac_addr_scan + ETH_ALEN;
     980             :                 }
     981             :         }
     982             : 
     983        2020 :         scan_params = &params;
     984             : 
     985             : scan:
     986             : #ifdef CONFIG_P2P
     987             :         /*
     988             :          * If the driver does not support multi-channel concurrency and a
     989             :          * virtual interface that shares the same radio with the wpa_s interface
     990             :          * is operating there may not be need to scan other channels apart from
     991             :          * the current operating channel on the other virtual interface. Filter
     992             :          * out other channels in case we are trying to find a connection for a
     993             :          * station interface when we are not configured to prefer station
     994             :          * connection and a concurrent operation is already in process.
     995             :          */
     996        2225 :         if (wpa_s->scan_for_connection &&
     997         381 :             wpa_s->last_scan_req == NORMAL_SCAN_REQ &&
     998         262 :             !scan_params->freqs && !params.freqs &&
     999          86 :             wpas_is_p2p_prioritized(wpa_s) &&
    1000          85 :             wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE &&
    1001          42 :             non_p2p_network_enabled(wpa_s)) {
    1002          42 :                 unsigned int num = wpa_s->num_multichan_concurrent;
    1003             : 
    1004          42 :                 params.freqs = os_calloc(num + 1, sizeof(int));
    1005          42 :                 if (params.freqs) {
    1006          42 :                         num = get_shared_radio_freqs(wpa_s, params.freqs, num);
    1007          42 :                         if (num > 0 && num == wpa_s->num_multichan_concurrent) {
    1008           0 :                                 wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the current operating channels since all channels are already used");
    1009             :                         } else {
    1010          42 :                                 os_free(params.freqs);
    1011          42 :                                 params.freqs = NULL;
    1012             :                         }
    1013             :                 }
    1014             :         }
    1015             : #endif /* CONFIG_P2P */
    1016             : 
    1017        2020 :         ret = wpa_supplicant_trigger_scan(wpa_s, scan_params);
    1018             : 
    1019        2020 :         if (ret && wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs &&
    1020           0 :             !wpa_s->manual_scan_freqs) {
    1021             :                 /* Restore manual_scan_freqs for the next attempt */
    1022           0 :                 wpa_s->manual_scan_freqs = params.freqs;
    1023           0 :                 params.freqs = NULL;
    1024             :         }
    1025             : 
    1026        2020 :         wpabuf_free(extra_ie);
    1027        2020 :         os_free(params.freqs);
    1028        2020 :         os_free(params.filter_ssids);
    1029             : 
    1030        2020 :         if (ret) {
    1031           0 :                 wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate AP scan");
    1032           0 :                 if (wpa_s->scan_prev_wpa_state != wpa_s->wpa_state)
    1033           0 :                         wpa_supplicant_set_state(wpa_s,
    1034             :                                                  wpa_s->scan_prev_wpa_state);
    1035             :                 /* Restore scan_req since we will try to scan again */
    1036           0 :                 wpa_s->scan_req = wpa_s->last_scan_req;
    1037           0 :                 wpa_supplicant_req_scan(wpa_s, 1, 0);
    1038             :         } else {
    1039        2020 :                 wpa_s->scan_for_connection = 0;
    1040             : #ifdef CONFIG_INTERWORKING
    1041        2020 :                 wpa_s->interworking_fast_assoc_tried = 0;
    1042             : #endif /* CONFIG_INTERWORKING */
    1043             :         }
    1044             : }
    1045             : 
    1046             : 
    1047          19 : void wpa_supplicant_update_scan_int(struct wpa_supplicant *wpa_s, int sec)
    1048             : {
    1049             :         struct os_reltime remaining, new_int;
    1050             :         int cancelled;
    1051             : 
    1052          19 :         cancelled = eloop_cancel_timeout_one(wpa_supplicant_scan, wpa_s, NULL,
    1053             :                                              &remaining);
    1054             : 
    1055          19 :         new_int.sec = sec;
    1056          19 :         new_int.usec = 0;
    1057          19 :         if (cancelled && os_reltime_before(&remaining, &new_int)) {
    1058           6 :                 new_int.sec = remaining.sec;
    1059           6 :                 new_int.usec = remaining.usec;
    1060             :         }
    1061             : 
    1062          19 :         if (cancelled) {
    1063           6 :                 eloop_register_timeout(new_int.sec, new_int.usec,
    1064             :                                        wpa_supplicant_scan, wpa_s, NULL);
    1065             :         }
    1066          19 :         wpa_s->scan_interval = sec;
    1067          19 : }
    1068             : 
    1069             : 
    1070             : /**
    1071             :  * wpa_supplicant_req_scan - Schedule a scan for neighboring access points
    1072             :  * @wpa_s: Pointer to wpa_supplicant data
    1073             :  * @sec: Number of seconds after which to scan
    1074             :  * @usec: Number of microseconds after which to scan
    1075             :  *
    1076             :  * This function is used to schedule a scan for neighboring access points after
    1077             :  * the specified time.
    1078             :  */
    1079        4417 : void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
    1080             : {
    1081             :         int res;
    1082             : 
    1083        4417 :         if (wpa_s->p2p_mgmt) {
    1084           2 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    1085             :                         "Ignore scan request (%d.%06d sec) on p2p_mgmt interface",
    1086             :                         sec, usec);
    1087        4419 :                 return;
    1088             :         }
    1089             : 
    1090        4415 :         res = eloop_deplete_timeout(sec, usec, wpa_supplicant_scan, wpa_s,
    1091             :                                     NULL);
    1092        4415 :         if (res == 1) {
    1093         106 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Rescheduling scan request: %d.%06d sec",
    1094             :                         sec, usec);
    1095        4309 :         } else if (res == 0) {
    1096         310 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Ignore new scan request for %d.%06d sec since an earlier request is scheduled to trigger sooner",
    1097             :                         sec, usec);
    1098             :         } else {
    1099        3999 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Setting scan request: %d.%06d sec",
    1100             :                         sec, usec);
    1101        3999 :                 eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL);
    1102             :         }
    1103             : }
    1104             : 
    1105             : 
    1106             : /**
    1107             :  * wpa_supplicant_delayed_sched_scan - Request a delayed scheduled scan
    1108             :  * @wpa_s: Pointer to wpa_supplicant data
    1109             :  * @sec: Number of seconds after which to scan
    1110             :  * @usec: Number of microseconds after which to scan
    1111             :  * Returns: 0 on success or -1 otherwise
    1112             :  *
    1113             :  * This function is used to schedule periodic scans for neighboring
    1114             :  * access points after the specified time.
    1115             :  */
    1116           0 : int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s,
    1117             :                                       int sec, int usec)
    1118             : {
    1119           0 :         if (!wpa_s->sched_scan_supported)
    1120           0 :                 return -1;
    1121             : 
    1122           0 :         eloop_register_timeout(sec, usec,
    1123             :                                wpa_supplicant_delayed_sched_scan_timeout,
    1124             :                                wpa_s, NULL);
    1125             : 
    1126           0 :         return 0;
    1127             : }
    1128             : 
    1129             : 
    1130             : /**
    1131             :  * wpa_supplicant_req_sched_scan - Start a periodic scheduled scan
    1132             :  * @wpa_s: Pointer to wpa_supplicant data
    1133             :  * Returns: 0 is sched_scan was started or -1 otherwise
    1134             :  *
    1135             :  * This function is used to schedule periodic scans for neighboring
    1136             :  * access points repeating the scan continuously.
    1137             :  */
    1138         216 : int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s)
    1139             : {
    1140             :         struct wpa_driver_scan_params params;
    1141             :         struct wpa_driver_scan_params *scan_params;
    1142             :         enum wpa_states prev_state;
    1143         216 :         struct wpa_ssid *ssid = NULL;
    1144         216 :         struct wpabuf *extra_ie = NULL;
    1145             :         int ret;
    1146             :         unsigned int max_sched_scan_ssids;
    1147         216 :         int wildcard = 0;
    1148             :         int need_ssids;
    1149             : 
    1150         216 :         if (!wpa_s->sched_scan_supported)
    1151         216 :                 return -1;
    1152             : 
    1153           0 :         if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS)
    1154           0 :                 max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS;
    1155             :         else
    1156           0 :                 max_sched_scan_ssids = wpa_s->max_sched_scan_ssids;
    1157           0 :         if (max_sched_scan_ssids < 1 || wpa_s->conf->disable_scan_offload)
    1158           0 :                 return -1;
    1159             : 
    1160           0 :         if (wpa_s->sched_scanning) {
    1161           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Already sched scanning");
    1162           0 :                 return 0;
    1163             :         }
    1164             : 
    1165           0 :         need_ssids = 0;
    1166           0 :         for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
    1167           0 :                 if (!wpas_network_disabled(wpa_s, ssid) && !ssid->scan_ssid) {
    1168             :                         /* Use wildcard SSID to find this network */
    1169           0 :                         wildcard = 1;
    1170           0 :                 } else if (!wpas_network_disabled(wpa_s, ssid) &&
    1171           0 :                            ssid->ssid_len)
    1172           0 :                         need_ssids++;
    1173             : 
    1174             : #ifdef CONFIG_WPS
    1175           0 :                 if (!wpas_network_disabled(wpa_s, ssid) &&
    1176           0 :                     ssid->key_mgmt == WPA_KEY_MGMT_WPS) {
    1177             :                         /*
    1178             :                          * Normal scan is more reliable and faster for WPS
    1179             :                          * operations and since these are for short periods of
    1180             :                          * time, the benefit of trying to use sched_scan would
    1181             :                          * be limited.
    1182             :                          */
    1183           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of "
    1184             :                                 "sched_scan for WPS");
    1185           0 :                         return -1;
    1186             :                 }
    1187             : #endif /* CONFIG_WPS */
    1188             :         }
    1189           0 :         if (wildcard)
    1190           0 :                 need_ssids++;
    1191             : 
    1192           0 :         if (wpa_s->normal_scans < 3 &&
    1193           0 :             (need_ssids <= wpa_s->max_scan_ssids ||
    1194           0 :              wpa_s->max_scan_ssids >= (int) max_sched_scan_ssids)) {
    1195             :                 /*
    1196             :                  * When normal scan can speed up operations, use that for the
    1197             :                  * first operations before starting the sched_scan to allow
    1198             :                  * user space sleep more. We do this only if the normal scan
    1199             :                  * has functionality that is suitable for this or if the
    1200             :                  * sched_scan does not have better support for multiple SSIDs.
    1201             :                  */
    1202           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of "
    1203             :                         "sched_scan for initial scans (normal_scans=%d)",
    1204             :                         wpa_s->normal_scans);
    1205           0 :                 return -1;
    1206             :         }
    1207             : 
    1208           0 :         os_memset(&params, 0, sizeof(params));
    1209             : 
    1210             :         /* If we can't allocate space for the filters, we just don't filter */
    1211           0 :         params.filter_ssids = os_calloc(wpa_s->max_match_sets,
    1212             :                                         sizeof(struct wpa_driver_scan_filter));
    1213             : 
    1214           0 :         prev_state = wpa_s->wpa_state;
    1215           0 :         if (wpa_s->wpa_state == WPA_DISCONNECTED ||
    1216           0 :             wpa_s->wpa_state == WPA_INACTIVE)
    1217           0 :                 wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
    1218             : 
    1219           0 :         if (wpa_s->autoscan_params != NULL) {
    1220           0 :                 scan_params = wpa_s->autoscan_params;
    1221           0 :                 goto scan;
    1222             :         }
    1223             : 
    1224             :         /* Find the starting point from which to continue scanning */
    1225           0 :         ssid = wpa_s->conf->ssid;
    1226           0 :         if (wpa_s->prev_sched_ssid) {
    1227           0 :                 while (ssid) {
    1228           0 :                         if (ssid == wpa_s->prev_sched_ssid) {
    1229           0 :                                 ssid = ssid->next;
    1230           0 :                                 break;
    1231             :                         }
    1232           0 :                         ssid = ssid->next;
    1233             :                 }
    1234             :         }
    1235             : 
    1236           0 :         if (!ssid || !wpa_s->prev_sched_ssid) {
    1237           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Beginning of SSID list");
    1238           0 :                 if (wpa_s->conf->sched_scan_interval)
    1239           0 :                         wpa_s->sched_scan_interval =
    1240           0 :                                 wpa_s->conf->sched_scan_interval;
    1241           0 :                 if (wpa_s->sched_scan_interval == 0)
    1242           0 :                         wpa_s->sched_scan_interval = 10;
    1243           0 :                 wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2;
    1244           0 :                 wpa_s->first_sched_scan = 1;
    1245           0 :                 ssid = wpa_s->conf->ssid;
    1246           0 :                 wpa_s->prev_sched_ssid = ssid;
    1247             :         }
    1248             : 
    1249           0 :         if (wildcard) {
    1250           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Add wildcard SSID to sched_scan");
    1251           0 :                 params.num_ssids++;
    1252             :         }
    1253             : 
    1254           0 :         while (ssid) {
    1255           0 :                 if (wpas_network_disabled(wpa_s, ssid))
    1256           0 :                         goto next;
    1257             : 
    1258           0 :                 if (params.num_filter_ssids < wpa_s->max_match_sets &&
    1259           0 :                     params.filter_ssids && ssid->ssid && ssid->ssid_len) {
    1260           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "add to filter ssid: %s",
    1261             :                                 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
    1262           0 :                         os_memcpy(params.filter_ssids[params.num_filter_ssids].ssid,
    1263             :                                   ssid->ssid, ssid->ssid_len);
    1264           0 :                         params.filter_ssids[params.num_filter_ssids].ssid_len =
    1265           0 :                                 ssid->ssid_len;
    1266           0 :                         params.num_filter_ssids++;
    1267           0 :                 } else if (params.filter_ssids && ssid->ssid && ssid->ssid_len)
    1268             :                 {
    1269           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Not enough room for SSID "
    1270             :                                 "filter for sched_scan - drop filter");
    1271           0 :                         os_free(params.filter_ssids);
    1272           0 :                         params.filter_ssids = NULL;
    1273           0 :                         params.num_filter_ssids = 0;
    1274             :                 }
    1275             : 
    1276           0 :                 if (ssid->scan_ssid && ssid->ssid && ssid->ssid_len) {
    1277           0 :                         if (params.num_ssids == max_sched_scan_ssids)
    1278           0 :                                 break; /* only room for broadcast SSID */
    1279           0 :                         wpa_dbg(wpa_s, MSG_DEBUG,
    1280             :                                 "add to active scan ssid: %s",
    1281             :                                 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
    1282           0 :                         params.ssids[params.num_ssids].ssid =
    1283           0 :                                 ssid->ssid;
    1284           0 :                         params.ssids[params.num_ssids].ssid_len =
    1285           0 :                                 ssid->ssid_len;
    1286           0 :                         params.num_ssids++;
    1287           0 :                         if (params.num_ssids >= max_sched_scan_ssids) {
    1288           0 :                                 wpa_s->prev_sched_ssid = ssid;
    1289             :                                 do {
    1290           0 :                                         ssid = ssid->next;
    1291           0 :                                 } while (ssid &&
    1292           0 :                                          (wpas_network_disabled(wpa_s, ssid) ||
    1293           0 :                                           !ssid->scan_ssid));
    1294           0 :                                 break;
    1295             :                         }
    1296             :                 }
    1297             : 
    1298             :         next:
    1299           0 :                 wpa_s->prev_sched_ssid = ssid;
    1300           0 :                 ssid = ssid->next;
    1301             :         }
    1302             : 
    1303           0 :         if (params.num_filter_ssids == 0) {
    1304           0 :                 os_free(params.filter_ssids);
    1305           0 :                 params.filter_ssids = NULL;
    1306             :         }
    1307             : 
    1308           0 :         extra_ie = wpa_supplicant_extra_ies(wpa_s);
    1309           0 :         if (extra_ie) {
    1310           0 :                 params.extra_ies = wpabuf_head(extra_ie);
    1311           0 :                 params.extra_ies_len = wpabuf_len(extra_ie);
    1312             :         }
    1313             : 
    1314           0 :         if (wpa_s->conf->filter_rssi)
    1315           0 :                 params.filter_rssi = wpa_s->conf->filter_rssi;
    1316             : 
    1317             :         /* See if user specified frequencies. If so, scan only those. */
    1318           0 :         if (wpa_s->conf->freq_list && !params.freqs) {
    1319           0 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    1320             :                         "Optimize scan based on conf->freq_list");
    1321           0 :                 int_array_concat(&params.freqs, wpa_s->conf->freq_list);
    1322             :         }
    1323             : 
    1324           0 :         scan_params = &params;
    1325             : 
    1326             : scan:
    1327           0 :         if (ssid || !wpa_s->first_sched_scan) {
    1328           0 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    1329             :                         "Starting sched scan: interval %d timeout %d",
    1330             :                         wpa_s->sched_scan_interval, wpa_s->sched_scan_timeout);
    1331             :         } else {
    1332           0 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    1333             :                         "Starting sched scan: interval %d (no timeout)",
    1334             :                         wpa_s->sched_scan_interval);
    1335             :         }
    1336             : 
    1337           0 :         wpa_setband_scan_freqs(wpa_s, scan_params);
    1338             : 
    1339           0 :         if (wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCHED_SCAN) {
    1340           0 :                 params.mac_addr_rand = 1;
    1341           0 :                 if (wpa_s->mac_addr_sched_scan) {
    1342           0 :                         params.mac_addr = wpa_s->mac_addr_sched_scan;
    1343           0 :                         params.mac_addr_mask = wpa_s->mac_addr_sched_scan +
    1344             :                                 ETH_ALEN;
    1345             :                 }
    1346             :         }
    1347             : 
    1348           0 :         ret = wpa_supplicant_start_sched_scan(wpa_s, scan_params,
    1349             :                                               wpa_s->sched_scan_interval);
    1350           0 :         wpabuf_free(extra_ie);
    1351           0 :         os_free(params.filter_ssids);
    1352           0 :         if (ret) {
    1353           0 :                 wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate sched scan");
    1354           0 :                 if (prev_state != wpa_s->wpa_state)
    1355           0 :                         wpa_supplicant_set_state(wpa_s, prev_state);
    1356           0 :                 return ret;
    1357             :         }
    1358             : 
    1359             :         /* If we have more SSIDs to scan, add a timeout so we scan them too */
    1360           0 :         if (ssid || !wpa_s->first_sched_scan) {
    1361           0 :                 wpa_s->sched_scan_timed_out = 0;
    1362           0 :                 eloop_register_timeout(wpa_s->sched_scan_timeout, 0,
    1363             :                                        wpa_supplicant_sched_scan_timeout,
    1364             :                                        wpa_s, NULL);
    1365           0 :                 wpa_s->first_sched_scan = 0;
    1366           0 :                 wpa_s->sched_scan_timeout /= 2;
    1367           0 :                 wpa_s->sched_scan_interval *= 2;
    1368           0 :                 if (wpa_s->sched_scan_timeout < wpa_s->sched_scan_interval) {
    1369           0 :                         wpa_s->sched_scan_interval = 10;
    1370           0 :                         wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2;
    1371             :                 }
    1372             :         }
    1373             : 
    1374             :         /* If there is no more ssids, start next time from the beginning */
    1375           0 :         if (!ssid)
    1376           0 :                 wpa_s->prev_sched_ssid = NULL;
    1377             : 
    1378           0 :         return 0;
    1379             : }
    1380             : 
    1381             : 
    1382             : /**
    1383             :  * wpa_supplicant_cancel_scan - Cancel a scheduled scan request
    1384             :  * @wpa_s: Pointer to wpa_supplicant data
    1385             :  *
    1386             :  * This function is used to cancel a scan request scheduled with
    1387             :  * wpa_supplicant_req_scan().
    1388             :  */
    1389        7354 : void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
    1390             : {
    1391        7354 :         wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling scan request");
    1392        7354 :         eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
    1393        7354 : }
    1394             : 
    1395             : 
    1396             : /**
    1397             :  * wpa_supplicant_cancel_delayed_sched_scan - Stop a delayed scheduled scan
    1398             :  * @wpa_s: Pointer to wpa_supplicant data
    1399             :  *
    1400             :  * This function is used to stop a delayed scheduled scan.
    1401             :  */
    1402         288 : void wpa_supplicant_cancel_delayed_sched_scan(struct wpa_supplicant *wpa_s)
    1403             : {
    1404         288 :         if (!wpa_s->sched_scan_supported)
    1405         576 :                 return;
    1406             : 
    1407           0 :         wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling delayed sched scan");
    1408           0 :         eloop_cancel_timeout(wpa_supplicant_delayed_sched_scan_timeout,
    1409             :                              wpa_s, NULL);
    1410             : }
    1411             : 
    1412             : 
    1413             : /**
    1414             :  * wpa_supplicant_cancel_sched_scan - Stop running scheduled scans
    1415             :  * @wpa_s: Pointer to wpa_supplicant data
    1416             :  *
    1417             :  * This function is used to stop a periodic scheduled scan.
    1418             :  */
    1419        5139 : void wpa_supplicant_cancel_sched_scan(struct wpa_supplicant *wpa_s)
    1420             : {
    1421        5139 :         if (!wpa_s->sched_scanning)
    1422       10278 :                 return;
    1423             : 
    1424           0 :         wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling sched scan");
    1425           0 :         eloop_cancel_timeout(wpa_supplicant_sched_scan_timeout, wpa_s, NULL);
    1426           0 :         wpa_supplicant_stop_sched_scan(wpa_s);
    1427             : }
    1428             : 
    1429             : 
    1430             : /**
    1431             :  * wpa_supplicant_notify_scanning - Indicate possible scan state change
    1432             :  * @wpa_s: Pointer to wpa_supplicant data
    1433             :  * @scanning: Whether scanning is currently in progress
    1434             :  *
    1435             :  * This function is to generate scanning notifycations. It is called whenever
    1436             :  * there may have been a change in scanning (scan started, completed, stopped).
    1437             :  * wpas_notify_scanning() is called whenever the scanning state changed from the
    1438             :  * previously notified state.
    1439             :  */
    1440       25991 : void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
    1441             :                                     int scanning)
    1442             : {
    1443       25991 :         if (wpa_s->scanning != scanning) {
    1444        4066 :                 wpa_s->scanning = scanning;
    1445        4066 :                 wpas_notify_scanning(wpa_s);
    1446             :         }
    1447       25991 : }
    1448             : 
    1449             : 
    1450        3936 : static int wpa_scan_get_max_rate(const struct wpa_scan_res *res)
    1451             : {
    1452        3936 :         int rate = 0;
    1453             :         const u8 *ie;
    1454             :         int i;
    1455             : 
    1456        3936 :         ie = wpa_scan_get_ie(res, WLAN_EID_SUPP_RATES);
    1457       35413 :         for (i = 0; ie && i < ie[1]; i++) {
    1458       31477 :                 if ((ie[i + 2] & 0x7f) > rate)
    1459       26873 :                         rate = ie[i + 2] & 0x7f;
    1460             :         }
    1461             : 
    1462        3936 :         ie = wpa_scan_get_ie(res, WLAN_EID_EXT_SUPP_RATES);
    1463       13152 :         for (i = 0; ie && i < ie[1]; i++) {
    1464        9216 :                 if ((ie[i + 2] & 0x7f) > rate)
    1465        9216 :                         rate = ie[i + 2] & 0x7f;
    1466             :         }
    1467             : 
    1468        3936 :         return rate;
    1469             : }
    1470             : 
    1471             : 
    1472             : /**
    1473             :  * wpa_scan_get_ie - Fetch a specified information element from a scan result
    1474             :  * @res: Scan result entry
    1475             :  * @ie: Information element identitifier (WLAN_EID_*)
    1476             :  * Returns: Pointer to the information element (id field) or %NULL if not found
    1477             :  *
    1478             :  * This function returns the first matching information element in the scan
    1479             :  * result.
    1480             :  */
    1481       29392 : const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie)
    1482             : {
    1483             :         const u8 *end, *pos;
    1484             : 
    1485       29392 :         pos = (const u8 *) (res + 1);
    1486       29392 :         end = pos + res->ie_len;
    1487             : 
    1488      212977 :         while (pos + 1 < end) {
    1489      171302 :                 if (pos + 2 + pos[1] > end)
    1490           0 :                         break;
    1491      171302 :                 if (pos[0] == ie)
    1492       17109 :                         return pos;
    1493      154193 :                 pos += 2 + pos[1];
    1494             :         }
    1495             : 
    1496       12283 :         return NULL;
    1497             : }
    1498             : 
    1499             : 
    1500             : /**
    1501             :  * wpa_scan_get_vendor_ie - Fetch vendor information element from a scan result
    1502             :  * @res: Scan result entry
    1503             :  * @vendor_type: Vendor type (four octets starting the IE payload)
    1504             :  * Returns: Pointer to the information element (id field) or %NULL if not found
    1505             :  *
    1506             :  * This function returns the first matching information element in the scan
    1507             :  * result.
    1508             :  */
    1509        9415 : const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
    1510             :                                   u32 vendor_type)
    1511             : {
    1512             :         const u8 *end, *pos;
    1513             : 
    1514        9415 :         pos = (const u8 *) (res + 1);
    1515        9415 :         end = pos + res->ie_len;
    1516             : 
    1517      101846 :         while (pos + 1 < end) {
    1518       85914 :                 if (pos + 2 + pos[1] > end)
    1519           0 :                         break;
    1520      102384 :                 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
    1521       16470 :                     vendor_type == WPA_GET_BE32(&pos[2]))
    1522        2898 :                         return pos;
    1523       83016 :                 pos += 2 + pos[1];
    1524             :         }
    1525             : 
    1526        6517 :         return NULL;
    1527             : }
    1528             : 
    1529             : 
    1530             : /**
    1531             :  * wpa_scan_get_vendor_ie_beacon - Fetch vendor information from a scan result
    1532             :  * @res: Scan result entry
    1533             :  * @vendor_type: Vendor type (four octets starting the IE payload)
    1534             :  * Returns: Pointer to the information element (id field) or %NULL if not found
    1535             :  *
    1536             :  * This function returns the first matching information element in the scan
    1537             :  * result.
    1538             :  *
    1539             :  * This function is like wpa_scan_get_vendor_ie(), but uses IE buffer only
    1540             :  * from Beacon frames instead of either Beacon or Probe Response frames.
    1541             :  */
    1542         323 : const u8 * wpa_scan_get_vendor_ie_beacon(const struct wpa_scan_res *res,
    1543             :                                          u32 vendor_type)
    1544             : {
    1545             :         const u8 *end, *pos;
    1546             : 
    1547         323 :         if (res->beacon_ie_len == 0)
    1548           0 :                 return NULL;
    1549             : 
    1550         323 :         pos = (const u8 *) (res + 1);
    1551         323 :         pos += res->ie_len;
    1552         323 :         end = pos + res->beacon_ie_len;
    1553             : 
    1554        4050 :         while (pos + 1 < end) {
    1555        3423 :                 if (pos + 2 + pos[1] > end)
    1556           0 :                         break;
    1557        3826 :                 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
    1558         403 :                     vendor_type == WPA_GET_BE32(&pos[2]))
    1559          19 :                         return pos;
    1560        3404 :                 pos += 2 + pos[1];
    1561             :         }
    1562             : 
    1563         304 :         return NULL;
    1564             : }
    1565             : 
    1566             : 
    1567             : /**
    1568             :  * wpa_scan_get_vendor_ie_multi - Fetch vendor IE data from a scan result
    1569             :  * @res: Scan result entry
    1570             :  * @vendor_type: Vendor type (four octets starting the IE payload)
    1571             :  * Returns: Pointer to the information element payload or %NULL if not found
    1572             :  *
    1573             :  * This function returns concatenated payload of possibly fragmented vendor
    1574             :  * specific information elements in the scan result. The caller is responsible
    1575             :  * for freeing the returned buffer.
    1576             :  */
    1577         788 : struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
    1578             :                                              u32 vendor_type)
    1579             : {
    1580             :         struct wpabuf *buf;
    1581             :         const u8 *end, *pos;
    1582             : 
    1583         788 :         buf = wpabuf_alloc(res->ie_len);
    1584         788 :         if (buf == NULL)
    1585           0 :                 return NULL;
    1586             : 
    1587         788 :         pos = (const u8 *) (res + 1);
    1588         788 :         end = pos + res->ie_len;
    1589             : 
    1590        9689 :         while (pos + 1 < end) {
    1591        8113 :                 if (pos + 2 + pos[1] > end)
    1592           0 :                         break;
    1593       10073 :                 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
    1594        1960 :                     vendor_type == WPA_GET_BE32(&pos[2]))
    1595         772 :                         wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4);
    1596        8113 :                 pos += 2 + pos[1];
    1597             :         }
    1598             : 
    1599         788 :         if (wpabuf_len(buf) == 0) {
    1600          17 :                 wpabuf_free(buf);
    1601          17 :                 buf = NULL;
    1602             :         }
    1603             : 
    1604         788 :         return buf;
    1605             : }
    1606             : 
    1607             : 
    1608             : /*
    1609             :  * Channels with a great SNR can operate at full rate. What is a great SNR?
    1610             :  * This doc https://supportforums.cisco.com/docs/DOC-12954 says, "the general
    1611             :  * rule of thumb is that any SNR above 20 is good." This one
    1612             :  * http://www.cisco.com/en/US/tech/tk722/tk809/technologies_q_and_a_item09186a00805e9a96.shtml#qa23
    1613             :  * recommends 25 as a minimum SNR for 54 Mbps data rate. 30 is chosen here as a
    1614             :  * conservative value.
    1615             :  */
    1616             : #define GREAT_SNR 30
    1617             : 
    1618             : #define IS_5GHZ(n) (n > 4000)
    1619             : 
    1620             : /* Compare function for sorting scan results. Return >0 if @b is considered
    1621             :  * better. */
    1622        1318 : static int wpa_scan_result_compar(const void *a, const void *b)
    1623             : {
    1624             : #define MIN(a,b) a < b ? a : b
    1625        1318 :         struct wpa_scan_res **_wa = (void *) a;
    1626        1318 :         struct wpa_scan_res **_wb = (void *) b;
    1627        1318 :         struct wpa_scan_res *wa = *_wa;
    1628        1318 :         struct wpa_scan_res *wb = *_wb;
    1629             :         int wpa_a, wpa_b;
    1630             :         int snr_a, snr_b, snr_a_full, snr_b_full;
    1631             : 
    1632             :         /* WPA/WPA2 support preferred */
    1633        2609 :         wpa_a = wpa_scan_get_vendor_ie(wa, WPA_IE_VENDOR_TYPE) != NULL ||
    1634        1291 :                 wpa_scan_get_ie(wa, WLAN_EID_RSN) != NULL;
    1635        2606 :         wpa_b = wpa_scan_get_vendor_ie(wb, WPA_IE_VENDOR_TYPE) != NULL ||
    1636        1288 :                 wpa_scan_get_ie(wb, WLAN_EID_RSN) != NULL;
    1637             : 
    1638        1318 :         if (wpa_b && !wpa_a)
    1639         126 :                 return 1;
    1640        1192 :         if (!wpa_b && wpa_a)
    1641         267 :                 return -1;
    1642             : 
    1643             :         /* privacy support preferred */
    1644        1284 :         if ((wa->caps & IEEE80211_CAP_PRIVACY) == 0 &&
    1645         359 :             (wb->caps & IEEE80211_CAP_PRIVACY))
    1646         122 :                 return 1;
    1647        1369 :         if ((wa->caps & IEEE80211_CAP_PRIVACY) &&
    1648         566 :             (wb->caps & IEEE80211_CAP_PRIVACY) == 0)
    1649          11 :                 return -1;
    1650             : 
    1651         792 :         if (wa->flags & wb->flags & WPA_SCAN_LEVEL_DBM) {
    1652         792 :                 snr_a_full = wa->snr;
    1653         792 :                 snr_a = MIN(wa->snr, GREAT_SNR);
    1654         792 :                 snr_b_full = wb->snr;
    1655         792 :                 snr_b = MIN(wa->snr, GREAT_SNR);
    1656             :         } else {
    1657             :                 /* Level is not in dBm, so we can't calculate
    1658             :                  * SNR. Just use raw level (units unknown). */
    1659           0 :                 snr_a = snr_a_full = wa->level;
    1660           0 :                 snr_b = snr_b_full = wb->level;
    1661             :         }
    1662             : 
    1663             :         /* if SNR is close, decide by max rate or frequency band */
    1664         792 :         if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) ||
    1665           0 :             (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) {
    1666         792 :                 if (wa->est_throughput != wb->est_throughput)
    1667          21 :                         return wb->est_throughput - wa->est_throughput;
    1668         771 :                 if (IS_5GHZ(wa->freq) ^ IS_5GHZ(wb->freq))
    1669           3 :                         return IS_5GHZ(wa->freq) ? -1 : 1;
    1670             :         }
    1671             : 
    1672             :         /* all things being equal, use SNR; if SNRs are
    1673             :          * identical, use quality values since some drivers may only report
    1674             :          * that value and leave the signal level zero */
    1675         768 :         if (snr_b_full == snr_a_full)
    1676         481 :                 return wb->qual - wa->qual;
    1677         287 :         return snr_b_full - snr_a_full;
    1678             : #undef MIN
    1679             : }
    1680             : 
    1681             : 
    1682             : #ifdef CONFIG_WPS
    1683             : /* Compare function for sorting scan results when searching a WPS AP for
    1684             :  * provisioning. Return >0 if @b is considered better. */
    1685         105 : static int wpa_scan_result_wps_compar(const void *a, const void *b)
    1686             : {
    1687         105 :         struct wpa_scan_res **_wa = (void *) a;
    1688         105 :         struct wpa_scan_res **_wb = (void *) b;
    1689         105 :         struct wpa_scan_res *wa = *_wa;
    1690         105 :         struct wpa_scan_res *wb = *_wb;
    1691             :         int uses_wps_a, uses_wps_b;
    1692             :         struct wpabuf *wps_a, *wps_b;
    1693             :         int res;
    1694             : 
    1695             :         /* Optimization - check WPS IE existence before allocated memory and
    1696             :          * doing full reassembly. */
    1697         105 :         uses_wps_a = wpa_scan_get_vendor_ie(wa, WPS_IE_VENDOR_TYPE) != NULL;
    1698         105 :         uses_wps_b = wpa_scan_get_vendor_ie(wb, WPS_IE_VENDOR_TYPE) != NULL;
    1699         105 :         if (uses_wps_a && !uses_wps_b)
    1700           6 :                 return -1;
    1701          99 :         if (!uses_wps_a && uses_wps_b)
    1702          19 :                 return 1;
    1703             : 
    1704          80 :         if (uses_wps_a && uses_wps_b) {
    1705          79 :                 wps_a = wpa_scan_get_vendor_ie_multi(wa, WPS_IE_VENDOR_TYPE);
    1706          79 :                 wps_b = wpa_scan_get_vendor_ie_multi(wb, WPS_IE_VENDOR_TYPE);
    1707          79 :                 res = wps_ap_priority_compar(wps_a, wps_b);
    1708          79 :                 wpabuf_free(wps_a);
    1709          79 :                 wpabuf_free(wps_b);
    1710          79 :                 if (res)
    1711          30 :                         return res;
    1712             :         }
    1713             : 
    1714             :         /*
    1715             :          * Do not use current AP security policy as a sorting criteria during
    1716             :          * WPS provisioning step since the AP may get reconfigured at the
    1717             :          * completion of provisioning.
    1718             :          */
    1719             : 
    1720             :         /* all things being equal, use signal level; if signal levels are
    1721             :          * identical, use quality values since some drivers may only report
    1722             :          * that value and leave the signal level zero */
    1723          50 :         if (wb->level == wa->level)
    1724          49 :                 return wb->qual - wa->qual;
    1725           1 :         return wb->level - wa->level;
    1726             : }
    1727             : #endif /* CONFIG_WPS */
    1728             : 
    1729             : 
    1730        2911 : static void dump_scan_res(struct wpa_scan_results *scan_res)
    1731             : {
    1732             : #ifndef CONFIG_NO_STDOUT_DEBUG
    1733             :         size_t i;
    1734             : 
    1735        2911 :         if (scan_res->res == NULL || scan_res->num == 0)
    1736        3169 :                 return;
    1737             : 
    1738        2653 :         wpa_printf(MSG_EXCESSIVE, "Sorted scan results");
    1739             : 
    1740        6589 :         for (i = 0; i < scan_res->num; i++) {
    1741        3936 :                 struct wpa_scan_res *r = scan_res->res[i];
    1742             :                 u8 *pos;
    1743        3936 :                 if (r->flags & WPA_SCAN_LEVEL_DBM) {
    1744        3936 :                         int noise_valid = !(r->flags & WPA_SCAN_NOISE_INVALID);
    1745             : 
    1746       31488 :                         wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d "
    1747             :                                    "noise=%d%s level=%d snr=%d%s flags=0x%x age=%u est=%u",
    1748       23616 :                                    MAC2STR(r->bssid), r->freq, r->qual,
    1749             :                                    r->noise, noise_valid ? "" : "~", r->level,
    1750        3936 :                                    r->snr, r->snr >= GREAT_SNR ? "*" : "",
    1751             :                                    r->flags,
    1752             :                                    r->age, r->est_throughput);
    1753             :                 } else {
    1754           0 :                         wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d "
    1755             :                                    "noise=%d level=%d flags=0x%x age=%u est=%u",
    1756           0 :                                    MAC2STR(r->bssid), r->freq, r->qual,
    1757             :                                    r->noise, r->level, r->flags, r->age,
    1758             :                                    r->est_throughput);
    1759             :                 }
    1760        3936 :                 pos = (u8 *) (r + 1);
    1761        3936 :                 if (r->ie_len)
    1762        3936 :                         wpa_hexdump(MSG_EXCESSIVE, "IEs", pos, r->ie_len);
    1763        3936 :                 pos += r->ie_len;
    1764        3936 :                 if (r->beacon_ie_len)
    1765        2076 :                         wpa_hexdump(MSG_EXCESSIVE, "Beacon IEs",
    1766             :                                     pos, r->beacon_ie_len);
    1767             :         }
    1768             : #endif /* CONFIG_NO_STDOUT_DEBUG */
    1769             : }
    1770             : 
    1771             : 
    1772             : /**
    1773             :  * wpa_supplicant_filter_bssid_match - Is the specified BSSID allowed
    1774             :  * @wpa_s: Pointer to wpa_supplicant data
    1775             :  * @bssid: BSSID to check
    1776             :  * Returns: 0 if the BSSID is filtered or 1 if not
    1777             :  *
    1778             :  * This function is used to filter out specific BSSIDs from scan reslts mainly
    1779             :  * for testing purposes (SET bssid_filter ctrl_iface command).
    1780             :  */
    1781        8135 : int wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s,
    1782             :                                       const u8 *bssid)
    1783             : {
    1784             :         size_t i;
    1785             : 
    1786        8135 :         if (wpa_s->bssid_filter == NULL)
    1787        8125 :                 return 1;
    1788             : 
    1789          13 :         for (i = 0; i < wpa_s->bssid_filter_count; i++) {
    1790          10 :                 if (os_memcmp(wpa_s->bssid_filter + i * ETH_ALEN, bssid,
    1791             :                               ETH_ALEN) == 0)
    1792           7 :                         return 1;
    1793             :         }
    1794             : 
    1795           3 :         return 0;
    1796             : }
    1797             : 
    1798             : 
    1799        2911 : static void filter_scan_res(struct wpa_supplicant *wpa_s,
    1800             :                             struct wpa_scan_results *res)
    1801             : {
    1802             :         size_t i, j;
    1803             : 
    1804        2911 :         if (wpa_s->bssid_filter == NULL)
    1805        5820 :                 return;
    1806             : 
    1807           6 :         for (i = 0, j = 0; i < res->num; i++) {
    1808           4 :                 if (wpa_supplicant_filter_bssid_match(wpa_s,
    1809           4 :                                                       res->res[i]->bssid)) {
    1810           2 :                         res->res[j++] = res->res[i];
    1811             :                 } else {
    1812           2 :                         os_free(res->res[i]);
    1813           2 :                         res->res[i] = NULL;
    1814             :                 }
    1815             :         }
    1816             : 
    1817           2 :         if (res->num != j) {
    1818           2 :                 wpa_printf(MSG_DEBUG, "Filtered out %d scan results",
    1819           2 :                            (int) (res->num - j));
    1820           2 :                 res->num = j;
    1821             :         }
    1822             : }
    1823             : 
    1824             : 
    1825             : /*
    1826             :  * Noise floor values to use when we have signal strength
    1827             :  * measurements, but no noise floor measurments. These values were
    1828             :  * measured in an office environment with many APs.
    1829             :  */
    1830             : #define DEFAULT_NOISE_FLOOR_2GHZ (-89)
    1831             : #define DEFAULT_NOISE_FLOOR_5GHZ (-92)
    1832             : 
    1833        3936 : static void scan_snr(struct wpa_scan_res *res)
    1834             : {
    1835        3936 :         if (res->flags & WPA_SCAN_NOISE_INVALID) {
    1836        2324 :                 res->noise = IS_5GHZ(res->freq) ?
    1837        1162 :                         DEFAULT_NOISE_FLOOR_5GHZ :
    1838             :                         DEFAULT_NOISE_FLOOR_2GHZ;
    1839             :         }
    1840             : 
    1841        3936 :         if (res->flags & WPA_SCAN_LEVEL_DBM) {
    1842        3936 :                 res->snr = res->level - res->noise;
    1843             :         } else {
    1844             :                 /* Level is not in dBm, so we can't calculate
    1845             :                  * SNR. Just use raw level (units unknown). */
    1846           0 :                 res->snr = res->level;
    1847             :         }
    1848        3936 : }
    1849             : 
    1850             : 
    1851        2895 : static unsigned int max_ht20_rate(int snr)
    1852             : {
    1853        2895 :         if (snr < 6)
    1854           0 :                 return 6500; /* HT20 MCS0 */
    1855        2895 :         if (snr < 8)
    1856           0 :                 return 13000; /* HT20 MCS1 */
    1857        2895 :         if (snr < 13)
    1858           0 :                 return 19500; /* HT20 MCS2 */
    1859        2895 :         if (snr < 17)
    1860           0 :                 return 26000; /* HT20 MCS3 */
    1861        2895 :         if (snr < 20)
    1862           0 :                 return 39000; /* HT20 MCS4 */
    1863        2895 :         if (snr < 23)
    1864           0 :                 return 52000; /* HT20 MCS5 */
    1865        2895 :         if (snr < 24)
    1866           0 :                 return 58500; /* HT20 MCS6 */
    1867        2895 :         return 65000; /* HT20 MCS7 */
    1868             : }
    1869             : 
    1870             : 
    1871          58 : static unsigned int max_ht40_rate(int snr)
    1872             : {
    1873          58 :         if (snr < 3)
    1874           0 :                 return 13500; /* HT40 MCS0 */
    1875          58 :         if (snr < 6)
    1876           0 :                 return 27000; /* HT40 MCS1 */
    1877          58 :         if (snr < 10)
    1878           0 :                 return 40500; /* HT40 MCS2 */
    1879          58 :         if (snr < 15)
    1880           0 :                 return 54000; /* HT40 MCS3 */
    1881          58 :         if (snr < 17)
    1882           0 :                 return 81000; /* HT40 MCS4 */
    1883          58 :         if (snr < 22)
    1884           0 :                 return 108000; /* HT40 MCS5 */
    1885          58 :         if (snr < 24)
    1886           0 :                 return 121500; /* HT40 MCS6 */
    1887          58 :         return 135000; /* HT40 MCS7 */
    1888             : }
    1889             : 
    1890             : 
    1891           9 : static unsigned int max_vht80_rate(int snr)
    1892             : {
    1893           9 :         if (snr < 1)
    1894           0 :                 return 0;
    1895           9 :         if (snr < 2)
    1896           0 :                 return 29300; /* VHT80 MCS0 */
    1897           9 :         if (snr < 5)
    1898           0 :                 return 58500; /* VHT80 MCS1 */
    1899           9 :         if (snr < 9)
    1900           0 :                 return 87800; /* VHT80 MCS2 */
    1901           9 :         if (snr < 11)
    1902           0 :                 return 117000; /* VHT80 MCS3 */
    1903           9 :         if (snr < 15)
    1904           0 :                 return 175500; /* VHT80 MCS4 */
    1905           9 :         if (snr < 16)
    1906           0 :                 return 234000; /* VHT80 MCS5 */
    1907           9 :         if (snr < 18)
    1908           0 :                 return 263300; /* VHT80 MCS6 */
    1909           9 :         if (snr < 20)
    1910           0 :                 return 292500; /* VHT80 MCS7 */
    1911           9 :         if (snr < 22)
    1912           0 :                 return 351000; /* VHT80 MCS8 */
    1913           9 :         return 390000; /* VHT80 MCS9 */
    1914             : }
    1915             : 
    1916             : 
    1917        3936 : static void scan_est_throughput(struct wpa_supplicant *wpa_s,
    1918             :                                 struct wpa_scan_res *res)
    1919             : {
    1920        3936 :         enum local_hw_capab capab = wpa_s->hw_capab;
    1921             :         int rate; /* max legacy rate in 500 kb/s units */
    1922             :         const u8 *ie;
    1923             :         unsigned int est, tmp;
    1924        3936 :         int snr = res->snr;
    1925             : 
    1926        3936 :         if (res->est_throughput)
    1927        3936 :                 return;
    1928             : 
    1929             :         /* Get maximum legacy rate */
    1930        3936 :         rate = wpa_scan_get_max_rate(res);
    1931             : 
    1932             :         /* Limit based on estimated SNR */
    1933        3936 :         if (rate > 1 * 2 && snr < 1)
    1934           0 :                 rate = 1 * 2;
    1935        3936 :         else if (rate > 2 * 2 && snr < 4)
    1936           0 :                 rate = 2 * 2;
    1937        3936 :         else if (rate > 6 * 2 && snr < 5)
    1938           0 :                 rate = 6 * 2;
    1939        3936 :         else if (rate > 9 * 2 && snr < 6)
    1940           0 :                 rate = 9 * 2;
    1941        3936 :         else if (rate > 12 * 2 && snr < 7)
    1942           0 :                 rate = 12 * 2;
    1943        3936 :         else if (rate > 18 * 2 && snr < 10)
    1944           0 :                 rate = 18 * 2;
    1945        3936 :         else if (rate > 24 * 2 && snr < 11)
    1946           0 :                 rate = 24 * 2;
    1947        3936 :         else if (rate > 36 * 2 && snr < 15)
    1948           0 :                 rate = 36 * 2;
    1949        3936 :         else if (rate > 48 * 2 && snr < 19)
    1950           0 :                 rate = 48 * 2;
    1951        3936 :         else if (rate > 54 * 2 && snr < 21)
    1952           0 :                 rate = 54 * 2;
    1953        3936 :         est = rate * 500;
    1954             : 
    1955        3936 :         if (capab == CAPAB_HT || capab == CAPAB_HT40 || capab == CAPAB_VHT) {
    1956        3907 :                 ie = wpa_scan_get_ie(res, WLAN_EID_HT_CAP);
    1957        3907 :                 if (ie) {
    1958        2880 :                         tmp = max_ht20_rate(snr);
    1959        2880 :                         if (tmp > est)
    1960        2880 :                                 est = tmp;
    1961             :                 }
    1962             :         }
    1963             : 
    1964        3936 :         if (capab == CAPAB_HT40 || capab == CAPAB_VHT) {
    1965        3907 :                 ie = wpa_scan_get_ie(res, WLAN_EID_HT_OPERATION);
    1966        6787 :                 if (ie && ie[1] >= 2 &&
    1967        2880 :                     (ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
    1968          47 :                         tmp = max_ht40_rate(snr);
    1969          47 :                         if (tmp > est)
    1970          47 :                                 est = tmp;
    1971             :                 }
    1972             :         }
    1973             : 
    1974        3936 :         if (capab == CAPAB_VHT) {
    1975             :                 /* Use +1 to assume VHT is always faster than HT */
    1976        3907 :                 ie = wpa_scan_get_ie(res, WLAN_EID_VHT_CAP);
    1977        3907 :                 if (ie) {
    1978          15 :                         tmp = max_ht20_rate(snr) + 1;
    1979          15 :                         if (tmp > est)
    1980           4 :                                 est = tmp;
    1981             : 
    1982          15 :                         ie = wpa_scan_get_ie(res, WLAN_EID_HT_OPERATION);
    1983          30 :                         if (ie && ie[1] >= 2 &&
    1984          15 :                             (ie[3] &
    1985             :                              HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
    1986          11 :                                 tmp = max_ht40_rate(snr) + 1;
    1987          11 :                                 if (tmp > est)
    1988          11 :                                         est = tmp;
    1989             :                         }
    1990             : 
    1991          15 :                         ie = wpa_scan_get_ie(res, WLAN_EID_VHT_OPERATION);
    1992          30 :                         if (ie && ie[1] >= 1 &&
    1993          15 :                             (ie[2] & VHT_OPMODE_CHANNEL_WIDTH_MASK)) {
    1994           9 :                                 tmp = max_vht80_rate(snr) + 1;
    1995           9 :                                 if (tmp > est)
    1996           9 :                                         est = tmp;
    1997             :                         }
    1998             :                 }
    1999             :         }
    2000             : 
    2001             :         /* TODO: channel utilization and AP load (e.g., from AP Beacon) */
    2002             : 
    2003        3936 :         res->est_throughput = est;
    2004             : }
    2005             : 
    2006             : 
    2007             : /**
    2008             :  * wpa_supplicant_get_scan_results - Get scan results
    2009             :  * @wpa_s: Pointer to wpa_supplicant data
    2010             :  * @info: Information about what was scanned or %NULL if not available
    2011             :  * @new_scan: Whether a new scan was performed
    2012             :  * Returns: Scan results, %NULL on failure
    2013             :  *
    2014             :  * This function request the current scan results from the driver and updates
    2015             :  * the local BSS list wpa_s->bss. The caller is responsible for freeing the
    2016             :  * results with wpa_scan_results_free().
    2017             :  */
    2018             : struct wpa_scan_results *
    2019        2911 : wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
    2020             :                                 struct scan_info *info, int new_scan)
    2021             : {
    2022             :         struct wpa_scan_results *scan_res;
    2023             :         size_t i;
    2024        2911 :         int (*compar)(const void *, const void *) = wpa_scan_result_compar;
    2025             : 
    2026        2911 :         scan_res = wpa_drv_get_scan_results2(wpa_s);
    2027        2911 :         if (scan_res == NULL) {
    2028           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results");
    2029           0 :                 return NULL;
    2030             :         }
    2031        2911 :         if (scan_res->fetch_time.sec == 0) {
    2032             :                 /*
    2033             :                  * Make sure we have a valid timestamp if the driver wrapper
    2034             :                  * does not set this.
    2035             :                  */
    2036        2911 :                 os_get_reltime(&scan_res->fetch_time);
    2037             :         }
    2038        2911 :         filter_scan_res(wpa_s, scan_res);
    2039             : 
    2040        6847 :         for (i = 0; i < scan_res->num; i++) {
    2041        3936 :                 struct wpa_scan_res *scan_res_item = scan_res->res[i];
    2042             : 
    2043        3936 :                 scan_snr(scan_res_item);
    2044        3936 :                 scan_est_throughput(wpa_s, scan_res_item);
    2045             :         }
    2046             : 
    2047             : #ifdef CONFIG_WPS
    2048        2911 :         if (wpas_wps_searching(wpa_s)) {
    2049         406 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Order scan results with WPS "
    2050             :                         "provisioning rules");
    2051         406 :                 compar = wpa_scan_result_wps_compar;
    2052             :         }
    2053             : #endif /* CONFIG_WPS */
    2054             : 
    2055        2911 :         qsort(scan_res->res, scan_res->num, sizeof(struct wpa_scan_res *),
    2056             :               compar);
    2057        2911 :         dump_scan_res(scan_res);
    2058             : 
    2059        2911 :         wpa_bss_update_start(wpa_s);
    2060        6847 :         for (i = 0; i < scan_res->num; i++)
    2061        3936 :                 wpa_bss_update_scan_res(wpa_s, scan_res->res[i],
    2062             :                                         &scan_res->fetch_time);
    2063        2911 :         wpa_bss_update_end(wpa_s, info, new_scan);
    2064             : 
    2065        2911 :         return scan_res;
    2066             : }
    2067             : 
    2068             : 
    2069             : /**
    2070             :  * wpa_supplicant_update_scan_results - Update scan results from the driver
    2071             :  * @wpa_s: Pointer to wpa_supplicant data
    2072             :  * Returns: 0 on success, -1 on failure
    2073             :  *
    2074             :  * This function updates the BSS table within wpa_supplicant based on the
    2075             :  * currently available scan results from the driver without requesting a new
    2076             :  * scan. This is used in cases where the driver indicates an association
    2077             :  * (including roaming within ESS) and wpa_supplicant does not yet have the
    2078             :  * needed information to complete the connection (e.g., to perform validation
    2079             :  * steps in 4-way handshake).
    2080             :  */
    2081          16 : int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s)
    2082             : {
    2083             :         struct wpa_scan_results *scan_res;
    2084          16 :         scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
    2085          16 :         if (scan_res == NULL)
    2086           0 :                 return -1;
    2087          16 :         wpa_scan_results_free(scan_res);
    2088             : 
    2089          16 :         return 0;
    2090             : }
    2091             : 
    2092             : 
    2093             : /**
    2094             :  * scan_only_handler - Reports scan results
    2095             :  */
    2096         290 : void scan_only_handler(struct wpa_supplicant *wpa_s,
    2097             :                        struct wpa_scan_results *scan_res)
    2098             : {
    2099         290 :         wpa_dbg(wpa_s, MSG_DEBUG, "Scan-only results received");
    2100         290 :         if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
    2101           3 :             wpa_s->manual_scan_use_id && wpa_s->own_scan_running) {
    2102           3 :                 wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS "id=%u",
    2103             :                              wpa_s->manual_scan_id);
    2104           3 :                 wpa_s->manual_scan_use_id = 0;
    2105             :         } else {
    2106         287 :                 wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
    2107             :         }
    2108         290 :         wpas_notify_scan_results(wpa_s);
    2109         290 :         wpas_notify_scan_done(wpa_s, 1);
    2110         290 :         if (wpa_s->scan_work) {
    2111         290 :                 struct wpa_radio_work *work = wpa_s->scan_work;
    2112         290 :                 wpa_s->scan_work = NULL;
    2113         290 :                 radio_work_done(work);
    2114             :         }
    2115         290 : }
    2116             : 
    2117             : 
    2118           0 : int wpas_scan_scheduled(struct wpa_supplicant *wpa_s)
    2119             : {
    2120           0 :         return eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL);
    2121             : }
    2122             : 
    2123             : 
    2124             : struct wpa_driver_scan_params *
    2125        2034 : wpa_scan_clone_params(const struct wpa_driver_scan_params *src)
    2126             : {
    2127             :         struct wpa_driver_scan_params *params;
    2128             :         size_t i;
    2129             :         u8 *n;
    2130             : 
    2131        2034 :         params = os_zalloc(sizeof(*params));
    2132        2034 :         if (params == NULL)
    2133           1 :                 return NULL;
    2134             : 
    2135        4059 :         for (i = 0; i < src->num_ssids; i++) {
    2136        2026 :                 if (src->ssids[i].ssid) {
    2137         269 :                         n = os_malloc(src->ssids[i].ssid_len);
    2138         269 :                         if (n == NULL)
    2139           0 :                                 goto failed;
    2140         269 :                         os_memcpy(n, src->ssids[i].ssid,
    2141             :                                   src->ssids[i].ssid_len);
    2142         269 :                         params->ssids[i].ssid = n;
    2143         269 :                         params->ssids[i].ssid_len = src->ssids[i].ssid_len;
    2144             :                 }
    2145             :         }
    2146        2033 :         params->num_ssids = src->num_ssids;
    2147             : 
    2148        2033 :         if (src->extra_ies) {
    2149        2021 :                 n = os_malloc(src->extra_ies_len);
    2150        2021 :                 if (n == NULL)
    2151           0 :                         goto failed;
    2152        2021 :                 os_memcpy(n, src->extra_ies, src->extra_ies_len);
    2153        2021 :                 params->extra_ies = n;
    2154        2021 :                 params->extra_ies_len = src->extra_ies_len;
    2155             :         }
    2156             : 
    2157        2033 :         if (src->freqs) {
    2158        1862 :                 int len = int_array_len(src->freqs);
    2159        1862 :                 params->freqs = os_malloc((len + 1) * sizeof(int));
    2160        1862 :                 if (params->freqs == NULL)
    2161           0 :                         goto failed;
    2162        1862 :                 os_memcpy(params->freqs, src->freqs, (len + 1) * sizeof(int));
    2163             :         }
    2164             : 
    2165        2033 :         if (src->filter_ssids) {
    2166           2 :                 params->filter_ssids = os_malloc(sizeof(*params->filter_ssids) *
    2167           2 :                                                  src->num_filter_ssids);
    2168           2 :                 if (params->filter_ssids == NULL)
    2169           0 :                         goto failed;
    2170           2 :                 os_memcpy(params->filter_ssids, src->filter_ssids,
    2171             :                           sizeof(*params->filter_ssids) *
    2172             :                           src->num_filter_ssids);
    2173           2 :                 params->num_filter_ssids = src->num_filter_ssids;
    2174             :         }
    2175             : 
    2176        2033 :         params->filter_rssi = src->filter_rssi;
    2177        2033 :         params->p2p_probe = src->p2p_probe;
    2178        2033 :         params->only_new_results = src->only_new_results;
    2179        2033 :         params->low_priority = src->low_priority;
    2180             : 
    2181        2033 :         if (src->mac_addr_rand) {
    2182           3 :                 params->mac_addr_rand = src->mac_addr_rand;
    2183             : 
    2184           3 :                 if (src->mac_addr && src->mac_addr_mask) {
    2185             :                         u8 *mac_addr;
    2186             : 
    2187           2 :                         mac_addr = os_malloc(2 * ETH_ALEN);
    2188           2 :                         if (!mac_addr)
    2189           0 :                                 goto failed;
    2190             : 
    2191           2 :                         os_memcpy(mac_addr, src->mac_addr, ETH_ALEN);
    2192           2 :                         os_memcpy(mac_addr + ETH_ALEN, src->mac_addr_mask,
    2193             :                                   ETH_ALEN);
    2194           2 :                         params->mac_addr = mac_addr;
    2195           2 :                         params->mac_addr_mask = mac_addr + ETH_ALEN;
    2196             :                 }
    2197             :         }
    2198        2033 :         return params;
    2199             : 
    2200             : failed:
    2201           0 :         wpa_scan_free_params(params);
    2202           0 :         return NULL;
    2203             : }
    2204             : 
    2205             : 
    2206        2797 : void wpa_scan_free_params(struct wpa_driver_scan_params *params)
    2207             : {
    2208             :         size_t i;
    2209             : 
    2210        2797 :         if (params == NULL)
    2211        2797 :                 return;
    2212             : 
    2213        5587 :         for (i = 0; i < params->num_ssids; i++)
    2214        2790 :                 os_free((u8 *) params->ssids[i].ssid);
    2215        2797 :         os_free((u8 *) params->extra_ies);
    2216        2797 :         os_free(params->freqs);
    2217        2797 :         os_free(params->filter_ssids);
    2218             : 
    2219             :         /*
    2220             :          * Note: params->mac_addr_mask points to same memory allocation and
    2221             :          * must not be freed separately.
    2222             :          */
    2223        2797 :         os_free((u8 *) params->mac_addr);
    2224             : 
    2225        2797 :         os_free(params);
    2226             : }
    2227             : 
    2228             : 
    2229           4 : int wpas_start_pno(struct wpa_supplicant *wpa_s)
    2230             : {
    2231             :         int ret, interval, prio;
    2232             :         size_t i, num_ssid, num_match_ssid;
    2233             :         struct wpa_ssid *ssid;
    2234             :         struct wpa_driver_scan_params params;
    2235             : 
    2236           4 :         if (!wpa_s->sched_scan_supported)
    2237           4 :                 return -1;
    2238             : 
    2239           0 :         if (wpa_s->pno || wpa_s->pno_sched_pending)
    2240           0 :                 return 0;
    2241             : 
    2242           0 :         if ((wpa_s->wpa_state > WPA_SCANNING) &&
    2243           0 :             (wpa_s->wpa_state <= WPA_COMPLETED)) {
    2244           0 :                 wpa_printf(MSG_ERROR, "PNO: In assoc process");
    2245           0 :                 return -EAGAIN;
    2246             :         }
    2247             : 
    2248           0 :         if (wpa_s->wpa_state == WPA_SCANNING) {
    2249           0 :                 wpa_supplicant_cancel_scan(wpa_s);
    2250           0 :                 if (wpa_s->sched_scanning) {
    2251           0 :                         wpa_printf(MSG_DEBUG, "Schedule PNO on completion of "
    2252             :                                    "ongoing sched scan");
    2253           0 :                         wpa_supplicant_cancel_sched_scan(wpa_s);
    2254           0 :                         wpa_s->pno_sched_pending = 1;
    2255           0 :                         return 0;
    2256             :                 }
    2257             :         }
    2258             : 
    2259           0 :         os_memset(&params, 0, sizeof(params));
    2260             : 
    2261           0 :         num_ssid = num_match_ssid = 0;
    2262           0 :         ssid = wpa_s->conf->ssid;
    2263           0 :         while (ssid) {
    2264           0 :                 if (!wpas_network_disabled(wpa_s, ssid)) {
    2265           0 :                         num_match_ssid++;
    2266           0 :                         if (ssid->scan_ssid)
    2267           0 :                                 num_ssid++;
    2268             :                 }
    2269           0 :                 ssid = ssid->next;
    2270             :         }
    2271             : 
    2272           0 :         if (num_match_ssid == 0) {
    2273           0 :                 wpa_printf(MSG_DEBUG, "PNO: No configured SSIDs");
    2274           0 :                 return -1;
    2275             :         }
    2276             : 
    2277           0 :         if (num_match_ssid > num_ssid) {
    2278           0 :                 params.num_ssids++; /* wildcard */
    2279           0 :                 num_ssid++;
    2280             :         }
    2281             : 
    2282           0 :         if (num_ssid > WPAS_MAX_SCAN_SSIDS) {
    2283           0 :                 wpa_printf(MSG_DEBUG, "PNO: Use only the first %u SSIDs from "
    2284             :                            "%u", WPAS_MAX_SCAN_SSIDS, (unsigned int) num_ssid);
    2285           0 :                 num_ssid = WPAS_MAX_SCAN_SSIDS;
    2286             :         }
    2287             : 
    2288           0 :         if (num_match_ssid > wpa_s->max_match_sets) {
    2289           0 :                 num_match_ssid = wpa_s->max_match_sets;
    2290           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "PNO: Too many SSIDs to match");
    2291             :         }
    2292           0 :         params.filter_ssids = os_calloc(num_match_ssid,
    2293             :                                         sizeof(struct wpa_driver_scan_filter));
    2294           0 :         if (params.filter_ssids == NULL)
    2295           0 :                 return -1;
    2296             : 
    2297           0 :         i = 0;
    2298           0 :         prio = 0;
    2299           0 :         ssid = wpa_s->conf->pssid[prio];
    2300           0 :         while (ssid) {
    2301           0 :                 if (!wpas_network_disabled(wpa_s, ssid)) {
    2302           0 :                         if (ssid->scan_ssid && params.num_ssids < num_ssid) {
    2303           0 :                                 params.ssids[params.num_ssids].ssid =
    2304           0 :                                         ssid->ssid;
    2305           0 :                                 params.ssids[params.num_ssids].ssid_len =
    2306           0 :                                          ssid->ssid_len;
    2307           0 :                                 params.num_ssids++;
    2308             :                         }
    2309           0 :                         os_memcpy(params.filter_ssids[i].ssid, ssid->ssid,
    2310             :                                   ssid->ssid_len);
    2311           0 :                         params.filter_ssids[i].ssid_len = ssid->ssid_len;
    2312           0 :                         params.num_filter_ssids++;
    2313           0 :                         i++;
    2314           0 :                         if (i == num_match_ssid)
    2315           0 :                                 break;
    2316             :                 }
    2317           0 :                 if (ssid->pnext)
    2318           0 :                         ssid = ssid->pnext;
    2319           0 :                 else if (prio + 1 == wpa_s->conf->num_prio)
    2320           0 :                         break;
    2321             :                 else
    2322           0 :                         ssid = wpa_s->conf->pssid[++prio];
    2323             :         }
    2324             : 
    2325           0 :         if (wpa_s->conf->filter_rssi)
    2326           0 :                 params.filter_rssi = wpa_s->conf->filter_rssi;
    2327             : 
    2328           0 :         interval = wpa_s->conf->sched_scan_interval ?
    2329           0 :                 wpa_s->conf->sched_scan_interval : 10;
    2330             : 
    2331           0 :         if (params.freqs == NULL && wpa_s->manual_sched_scan_freqs) {
    2332           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Limit sched scan to specified channels");
    2333           0 :                 params.freqs = wpa_s->manual_sched_scan_freqs;
    2334             :         }
    2335             : 
    2336           0 :         if (wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_PNO) {
    2337           0 :                 params.mac_addr_rand = 1;
    2338           0 :                 if (wpa_s->mac_addr_pno) {
    2339           0 :                         params.mac_addr = wpa_s->mac_addr_pno;
    2340           0 :                         params.mac_addr_mask = wpa_s->mac_addr_pno + ETH_ALEN;
    2341             :                 }
    2342             :         }
    2343             : 
    2344           0 :         ret = wpa_supplicant_start_sched_scan(wpa_s, &params, interval);
    2345           0 :         os_free(params.filter_ssids);
    2346           0 :         if (ret == 0)
    2347           0 :                 wpa_s->pno = 1;
    2348             :         else
    2349           0 :                 wpa_msg(wpa_s, MSG_ERROR, "Failed to schedule PNO");
    2350           0 :         return ret;
    2351             : }
    2352             : 
    2353             : 
    2354           1 : int wpas_stop_pno(struct wpa_supplicant *wpa_s)
    2355             : {
    2356           1 :         int ret = 0;
    2357             : 
    2358           1 :         if (!wpa_s->pno)
    2359           1 :                 return 0;
    2360             : 
    2361           0 :         ret = wpa_supplicant_stop_sched_scan(wpa_s);
    2362             : 
    2363           0 :         wpa_s->pno = 0;
    2364           0 :         wpa_s->pno_sched_pending = 0;
    2365             : 
    2366           0 :         if (wpa_s->wpa_state == WPA_SCANNING)
    2367           0 :                 wpa_supplicant_req_scan(wpa_s, 0, 0);
    2368             : 
    2369           0 :         return ret;
    2370             : }
    2371             : 
    2372             : 
    2373         292 : void wpas_mac_addr_rand_scan_clear(struct wpa_supplicant *wpa_s,
    2374             :                                     unsigned int type)
    2375             : {
    2376         292 :         type &= MAC_ADDR_RAND_ALL;
    2377         292 :         wpa_s->mac_addr_rand_enable &= ~type;
    2378             : 
    2379         292 :         if (type & MAC_ADDR_RAND_SCAN) {
    2380         292 :                 os_free(wpa_s->mac_addr_scan);
    2381         292 :                 wpa_s->mac_addr_scan = NULL;
    2382             :         }
    2383             : 
    2384         292 :         if (type & MAC_ADDR_RAND_SCHED_SCAN) {
    2385         288 :                 os_free(wpa_s->mac_addr_sched_scan);
    2386         288 :                 wpa_s->mac_addr_sched_scan = NULL;
    2387             :         }
    2388             : 
    2389         292 :         if (type & MAC_ADDR_RAND_PNO) {
    2390         288 :                 os_free(wpa_s->mac_addr_pno);
    2391         288 :                 wpa_s->mac_addr_pno = NULL;
    2392             :         }
    2393         292 : }
    2394             : 
    2395             : 
    2396           3 : int wpas_mac_addr_rand_scan_set(struct wpa_supplicant *wpa_s,
    2397             :                                 unsigned int type, const u8 *addr,
    2398             :                                 const u8 *mask)
    2399             : {
    2400           3 :         u8 *tmp = NULL;
    2401             : 
    2402           3 :         wpas_mac_addr_rand_scan_clear(wpa_s, type);
    2403             : 
    2404           3 :         if (addr) {
    2405           2 :                 tmp = os_malloc(2 * ETH_ALEN);
    2406           2 :                 if (!tmp)
    2407           0 :                         return -1;
    2408           2 :                 os_memcpy(tmp, addr, ETH_ALEN);
    2409           2 :                 os_memcpy(tmp + ETH_ALEN, mask, ETH_ALEN);
    2410             :         }
    2411             : 
    2412           3 :         if (type == MAC_ADDR_RAND_SCAN) {
    2413           3 :                 wpa_s->mac_addr_scan = tmp;
    2414           0 :         } else if (type == MAC_ADDR_RAND_SCHED_SCAN) {
    2415           0 :                 wpa_s->mac_addr_sched_scan = tmp;
    2416           0 :         } else if (type == MAC_ADDR_RAND_PNO) {
    2417           0 :                 wpa_s->mac_addr_pno = tmp;
    2418             :         } else {
    2419           0 :                 wpa_printf(MSG_INFO,
    2420             :                            "scan: Invalid MAC randomization type=0x%x",
    2421             :                            type);
    2422           0 :                 os_free(tmp);
    2423           0 :                 return -1;
    2424             :         }
    2425             : 
    2426           3 :         wpa_s->mac_addr_rand_enable |= type;
    2427           3 :         return 0;
    2428             : }

Generated by: LCOV version 1.10