Add scheduled scan driver operations
[mech_eap.git] / wpa_supplicant / scan.c
1 /*
2  * WPA Supplicant - Scanning
3  * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "utils/includes.h"
16
17 #include "utils/common.h"
18 #include "utils/eloop.h"
19 #include "common/ieee802_11_defs.h"
20 #include "config.h"
21 #include "wpa_supplicant_i.h"
22 #include "driver_i.h"
23 #include "mlme.h"
24 #include "wps_supplicant.h"
25 #include "p2p_supplicant.h"
26 #include "p2p/p2p.h"
27 #include "notify.h"
28 #include "bss.h"
29 #include "scan.h"
30
31
32 static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
33 {
34         struct wpa_ssid *ssid;
35         union wpa_event_data data;
36
37         ssid = wpa_supplicant_get_ssid(wpa_s);
38         if (ssid == NULL)
39                 return;
40
41         if (wpa_s->current_ssid == NULL) {
42                 wpa_s->current_ssid = ssid;
43                 if (wpa_s->current_ssid != NULL)
44                         wpas_notify_network_changed(wpa_s);
45         }
46         wpa_supplicant_initiate_eapol(wpa_s);
47         wpa_dbg(wpa_s, MSG_DEBUG, "Already associated with a configured "
48                 "network - generating associated event");
49         os_memset(&data, 0, sizeof(data));
50         wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data);
51 }
52
53
54 #ifdef CONFIG_WPS
55 static int wpas_wps_in_use(struct wpa_supplicant *wpa_s,
56                            enum wps_request_type *req_type)
57 {
58         struct wpa_ssid *ssid;
59         int wps = 0;
60
61         for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
62                 if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
63                         continue;
64
65                 wps = 1;
66                 *req_type = wpas_wps_get_req_type(ssid);
67                 if (!ssid->eap.phase1)
68                         continue;
69
70                 if (os_strstr(ssid->eap.phase1, "pbc=1"))
71                         return 2;
72         }
73
74 #ifdef CONFIG_P2P
75         wpa_s->wps->dev.p2p = 1;
76         if (!wps) {
77                 wps = 1;
78                 *req_type = WPS_REQ_ENROLLEE_INFO;
79         }
80 #endif /* CONFIG_P2P */
81
82         return wps;
83 }
84 #endif /* CONFIG_WPS */
85
86
87 int wpa_supplicant_enabled_networks(struct wpa_config *conf)
88 {
89         struct wpa_ssid *ssid = conf->ssid;
90         int count = 0;
91         while (ssid) {
92                 if (!ssid->disabled)
93                         count++;
94                 ssid = ssid->next;
95         }
96         return count;
97 }
98
99
100 static void wpa_supplicant_assoc_try(struct wpa_supplicant *wpa_s,
101                                      struct wpa_ssid *ssid)
102 {
103         while (ssid) {
104                 if (!ssid->disabled)
105                         break;
106                 ssid = ssid->next;
107         }
108
109         /* ap_scan=2 mode - try to associate with each SSID. */
110         if (ssid == NULL) {
111                 wpa_dbg(wpa_s, MSG_DEBUG, "wpa_supplicant_assoc_try: Reached "
112                         "end of scan list - go back to beginning");
113                 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
114                 wpa_supplicant_req_scan(wpa_s, 0, 0);
115                 return;
116         }
117         if (ssid->next) {
118                 /* Continue from the next SSID on the next attempt. */
119                 wpa_s->prev_scan_ssid = ssid;
120         } else {
121                 /* Start from the beginning of the SSID list. */
122                 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
123         }
124         wpa_supplicant_associate(wpa_s, NULL, ssid);
125 }
126
127
128 static int int_array_len(const int *a)
129 {
130         int i;
131         for (i = 0; a && a[i]; i++)
132                 ;
133         return i;
134 }
135
136
137 static void int_array_concat(int **res, const int *a)
138 {
139         int reslen, alen, i;
140         int *n;
141
142         reslen = int_array_len(*res);
143         alen = int_array_len(a);
144
145         n = os_realloc(*res, (reslen + alen + 1) * sizeof(int));
146         if (n == NULL) {
147                 os_free(*res);
148                 *res = NULL;
149                 return;
150         }
151         for (i = 0; i <= alen; i++)
152                 n[reslen + i] = a[i];
153         *res = n;
154 }
155
156
157 static int freq_cmp(const void *a, const void *b)
158 {
159         int _a = *(int *) a;
160         int _b = *(int *) b;
161
162         if (_a == 0)
163                 return 1;
164         if (_b == 0)
165                 return -1;
166         return _a - _b;
167 }
168
169
170 static void int_array_sort_unique(int *a)
171 {
172         int alen;
173         int i, j;
174
175         if (a == NULL)
176                 return;
177
178         alen = int_array_len(a);
179         qsort(a, alen, sizeof(int), freq_cmp);
180
181         i = 0;
182         j = 1;
183         while (a[i] && a[j]) {
184                 if (a[i] == a[j]) {
185                         j++;
186                         continue;
187                 }
188                 a[++i] = a[j++];
189         }
190         if (a[i])
191                 i++;
192         a[i] = 0;
193 }
194
195
196 int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
197                                 struct wpa_driver_scan_params *params)
198 {
199         int ret;
200
201         wpa_supplicant_notify_scanning(wpa_s, 1);
202
203         if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
204                 ret = ieee80211_sta_req_scan(wpa_s, params);
205         else
206                 ret = wpa_drv_scan(wpa_s, params);
207
208         if (ret) {
209                 wpa_supplicant_notify_scanning(wpa_s, 0);
210                 wpas_notify_scan_done(wpa_s, 0);
211         } else
212                 wpa_s->scan_runs++;
213
214         return ret;
215 }
216
217
218 static void
219 wpa_supplicant_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx)
220 {
221         struct wpa_supplicant *wpa_s = eloop_ctx;
222
223         wpa_dbg(wpa_s, MSG_DEBUG, "Sched scan timeout - stopping it");
224
225         wpa_s->sched_scan_timed_out = 1;
226         wpa_supplicant_cancel_sched_scan(wpa_s);
227 }
228
229
230 static int
231 wpa_supplicant_start_sched_scan(struct wpa_supplicant *wpa_s,
232                                 struct wpa_driver_scan_params *params,
233                                 int interval)
234 {
235         int ret;
236
237         if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
238                 return -1;
239
240         wpa_supplicant_notify_scanning(wpa_s, 1);
241         ret = wpa_drv_sched_scan(wpa_s, params, interval * 1000);
242         if (ret)
243                 wpa_supplicant_notify_scanning(wpa_s, 0);
244         else
245                 wpa_s->sched_scanning = 1;
246
247         return ret;
248 }
249
250
251 static int wpa_supplicant_stop_sched_scan(struct wpa_supplicant *wpa_s)
252 {
253         int ret;
254
255         ret = wpa_drv_stop_sched_scan(wpa_s);
256         if (ret) {
257                 wpa_dbg(wpa_s, MSG_DEBUG, "stopping sched_scan failed!");
258                 /* TODO: what to do if stopping fails? */
259                 return -1;
260         }
261
262         return ret;
263 }
264
265
266 static struct wpa_driver_scan_filter *
267 wpa_supplicant_build_filter_ssids(struct wpa_config *conf, size_t *num_ssids)
268 {
269         struct wpa_driver_scan_filter *ssids;
270         struct wpa_ssid *ssid;
271         size_t count;
272
273         *num_ssids = 0;
274         if (!conf->filter_ssids)
275                 return NULL;
276
277         for (count = 0, ssid = conf->ssid; ssid; ssid = ssid->next) {
278                 if (ssid->ssid && ssid->ssid_len)
279                         count++;
280         }
281         if (count == 0)
282                 return NULL;
283         ssids = os_zalloc(count * sizeof(struct wpa_driver_scan_filter));
284         if (ssids == NULL)
285                 return NULL;
286
287         for (ssid = conf->ssid; ssid; ssid = ssid->next) {
288                 if (!ssid->ssid || !ssid->ssid_len)
289                         continue;
290                 os_memcpy(ssids[*num_ssids].ssid, ssid->ssid, ssid->ssid_len);
291                 ssids[*num_ssids].ssid_len = ssid->ssid_len;
292                 (*num_ssids)++;
293         }
294
295         return ssids;
296 }
297
298
299 static void wpa_supplicant_optimize_freqs(
300         struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params)
301 {
302 #ifdef CONFIG_P2P
303         if (params->freqs == NULL && wpa_s->p2p_in_provisioning &&
304             wpa_s->go_params) {
305                 /* Optimize provisioning state scan based on GO information */
306                 if (wpa_s->p2p_in_provisioning < 5 &&
307                     wpa_s->go_params->freq > 0) {
308                         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO "
309                                 "preferred frequency %d MHz",
310                                 wpa_s->go_params->freq);
311                         params->freqs = os_zalloc(2 * sizeof(int));
312                         if (params->freqs)
313                                 params->freqs[0] = wpa_s->go_params->freq;
314                 } else if (wpa_s->p2p_in_provisioning < 8 &&
315                            wpa_s->go_params->freq_list[0]) {
316                         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only common "
317                                 "channels");
318                         int_array_concat(&params->freqs,
319                                          wpa_s->go_params->freq_list);
320                         if (params->freqs)
321                                 int_array_sort_unique(params->freqs);
322                 }
323                 wpa_s->p2p_in_provisioning++;
324         }
325 #endif /* CONFIG_P2P */
326
327 #ifdef CONFIG_WPS
328         if (params->freqs == NULL && wpa_s->after_wps && wpa_s->wps_freq) {
329                 /*
330                  * Optimize post-provisioning scan based on channel used
331                  * during provisioning.
332                  */
333                 wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz "
334                         "that was used during provisioning", wpa_s->wps_freq);
335                 params->freqs = os_zalloc(2 * sizeof(int));
336                 if (params->freqs)
337                         params->freqs[0] = wpa_s->wps_freq;
338                 wpa_s->after_wps--;
339         }
340
341 #endif /* CONFIG_WPS */
342 }
343
344
345 static struct wpabuf *
346 wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s,
347                          struct wpa_driver_scan_params *params)
348 {
349         struct wpabuf *wps_ie = NULL;
350 #ifdef CONFIG_WPS
351         int wps = 0;
352         enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO;
353
354         wps = wpas_wps_in_use(wpa_s, &req_type);
355
356         if (wps) {
357                 wps_ie = wps_build_probe_req_ie(wps == 2, &wpa_s->wps->dev,
358                                                 wpa_s->wps->uuid, req_type,
359                                                 0, NULL);
360                 if (wps_ie) {
361                         params->extra_ies = wpabuf_head(wps_ie);
362                         params->extra_ies_len = wpabuf_len(wps_ie);
363                 }
364         }
365
366 #ifdef CONFIG_P2P
367         if (wps_ie) {
368                 size_t ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
369                 if (wpabuf_resize(&wps_ie, ielen) == 0) {
370                         wpas_p2p_scan_ie(wpa_s, wps_ie);
371                         params->extra_ies = wpabuf_head(wps_ie);
372                         params->extra_ies_len = wpabuf_len(wps_ie);
373                 }
374         }
375 #endif /* CONFIG_P2P */
376
377 #endif /* CONFIG_WPS */
378
379         return wps_ie;
380 }
381
382
383 static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
384 {
385         struct wpa_supplicant *wpa_s = eloop_ctx;
386         struct wpa_ssid *ssid;
387         int scan_req = 0, ret;
388         struct wpabuf *wps_ie;
389         struct wpa_driver_scan_params params;
390         size_t max_ssids;
391         enum wpa_states prev_state;
392
393         if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
394                 wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - interface disabled");
395                 return;
396         }
397
398         if (wpa_s->disconnected && !wpa_s->scan_req) {
399                 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
400                 return;
401         }
402
403         if (!wpa_supplicant_enabled_networks(wpa_s->conf) &&
404             !wpa_s->scan_req) {
405                 wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan");
406                 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
407                 return;
408         }
409
410         if (wpa_s->conf->ap_scan != 0 &&
411             (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)) {
412                 wpa_dbg(wpa_s, MSG_DEBUG, "Using wired authentication - "
413                         "overriding ap_scan configuration");
414                 wpa_s->conf->ap_scan = 0;
415                 wpas_notify_ap_scan_changed(wpa_s);
416         }
417
418         if (wpa_s->conf->ap_scan == 0) {
419                 wpa_supplicant_gen_assoc_event(wpa_s);
420                 return;
421         }
422
423 #ifdef CONFIG_P2P
424         if (wpas_p2p_in_progress(wpa_s)) {
425                 if (wpa_s->wpa_state == WPA_SCANNING) {
426                         wpa_dbg(wpa_s, MSG_DEBUG, "Delay station mode scan "
427                                 "while P2P operation is in progress");
428                         wpa_supplicant_req_scan(wpa_s, 5, 0);
429                 } else {
430                         wpa_dbg(wpa_s, MSG_DEBUG, "Do not request scan while "
431                                 "P2P operation is in progress");
432                 }
433                 return;
434         }
435 #endif /* CONFIG_P2P */
436
437         if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) ||
438             wpa_s->conf->ap_scan == 2)
439                 max_ssids = 1;
440         else {
441                 max_ssids = wpa_s->max_scan_ssids;
442                 if (max_ssids > WPAS_MAX_SCAN_SSIDS)
443                         max_ssids = WPAS_MAX_SCAN_SSIDS;
444         }
445
446         scan_req = wpa_s->scan_req;
447         wpa_s->scan_req = 0;
448
449         os_memset(&params, 0, sizeof(params));
450
451         prev_state = wpa_s->wpa_state;
452         if (wpa_s->wpa_state == WPA_DISCONNECTED ||
453             wpa_s->wpa_state == WPA_INACTIVE)
454                 wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
455
456         if (scan_req != 2 && wpa_s->connect_without_scan) {
457                 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
458                         if (ssid == wpa_s->connect_without_scan)
459                                 break;
460                 }
461                 wpa_s->connect_without_scan = NULL;
462                 if (ssid) {
463                         wpa_printf(MSG_DEBUG, "Start a pre-selected network "
464                                    "without scan step");
465                         wpa_supplicant_associate(wpa_s, NULL, ssid);
466                         return;
467                 }
468         }
469
470         /* Find the starting point from which to continue scanning */
471         ssid = wpa_s->conf->ssid;
472         if (wpa_s->prev_scan_ssid != WILDCARD_SSID_SCAN) {
473                 while (ssid) {
474                         if (ssid == wpa_s->prev_scan_ssid) {
475                                 ssid = ssid->next;
476                                 break;
477                         }
478                         ssid = ssid->next;
479                 }
480         }
481
482         if (scan_req != 2 && wpa_s->conf->ap_scan == 2) {
483                 wpa_s->connect_without_scan = NULL;
484                 wpa_supplicant_assoc_try(wpa_s, ssid);
485                 return;
486         } else if (wpa_s->conf->ap_scan == 2) {
487                 /*
488                  * User-initiated scan request in ap_scan == 2; scan with
489                  * wildcard SSID.
490                  */
491                 ssid = NULL;
492         } else {
493                 struct wpa_ssid *start = ssid, *tssid;
494                 int freqs_set = 0;
495                 if (ssid == NULL && max_ssids > 1)
496                         ssid = wpa_s->conf->ssid;
497                 while (ssid) {
498                         if (!ssid->disabled && ssid->scan_ssid) {
499                                 wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
500                                                   ssid->ssid, ssid->ssid_len);
501                                 params.ssids[params.num_ssids].ssid =
502                                         ssid->ssid;
503                                 params.ssids[params.num_ssids].ssid_len =
504                                         ssid->ssid_len;
505                                 params.num_ssids++;
506                                 if (params.num_ssids + 1 >= max_ssids)
507                                         break;
508                         }
509                         ssid = ssid->next;
510                         if (ssid == start)
511                                 break;
512                         if (ssid == NULL && max_ssids > 1 &&
513                             start != wpa_s->conf->ssid)
514                                 ssid = wpa_s->conf->ssid;
515                 }
516
517                 for (tssid = wpa_s->conf->ssid; tssid; tssid = tssid->next) {
518                         if (tssid->disabled)
519                                 continue;
520                         if ((params.freqs || !freqs_set) && tssid->scan_freq) {
521                                 int_array_concat(&params.freqs,
522                                                  tssid->scan_freq);
523                         } else {
524                                 os_free(params.freqs);
525                                 params.freqs = NULL;
526                         }
527                         freqs_set = 1;
528                 }
529                 int_array_sort_unique(params.freqs);
530         }
531
532         if (ssid) {
533                 wpa_s->prev_scan_ssid = ssid;
534                 if (max_ssids > 1) {
535                         wpa_dbg(wpa_s, MSG_DEBUG, "Include wildcard SSID in "
536                                 "the scan request");
537                         params.num_ssids++;
538                 }
539                 wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for specific "
540                         "SSID(s)");
541         } else {
542                 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
543                 params.num_ssids++;
544                 wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for wildcard "
545                         "SSID");
546         }
547
548         wpa_supplicant_optimize_freqs(wpa_s, &params);
549         wps_ie = wpa_supplicant_extra_ies(wpa_s, &params);
550
551         if (params.freqs == NULL && wpa_s->next_scan_freqs) {
552                 wpa_dbg(wpa_s, MSG_DEBUG, "Optimize scan based on previously "
553                         "generated frequency list");
554                 params.freqs = wpa_s->next_scan_freqs;
555         } else
556                 os_free(wpa_s->next_scan_freqs);
557         wpa_s->next_scan_freqs = NULL;
558
559         params.filter_ssids = wpa_supplicant_build_filter_ssids(
560                 wpa_s->conf, &params.num_filter_ssids);
561
562         ret = wpa_supplicant_trigger_scan(wpa_s, &params);
563
564         wpabuf_free(wps_ie);
565         os_free(params.freqs);
566         os_free(params.filter_ssids);
567
568         if (ret) {
569                 wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate AP scan");
570                 if (prev_state != wpa_s->wpa_state)
571                         wpa_supplicant_set_state(wpa_s, prev_state);
572                 wpa_supplicant_req_scan(wpa_s, 1, 0);
573         }
574 }
575
576
577 /**
578  * wpa_supplicant_req_scan - Schedule a scan for neighboring access points
579  * @wpa_s: Pointer to wpa_supplicant data
580  * @sec: Number of seconds after which to scan
581  * @usec: Number of microseconds after which to scan
582  *
583  * This function is used to schedule a scan for neighboring access points after
584  * the specified time.
585  */
586 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
587 {
588         /* If there's at least one network that should be specifically scanned
589          * then don't cancel the scan and reschedule.  Some drivers do
590          * background scanning which generates frequent scan results, and that
591          * causes the specific SSID scan to get continually pushed back and
592          * never happen, which causes hidden APs to never get probe-scanned.
593          */
594         if (eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL) &&
595             wpa_s->conf->ap_scan == 1) {
596                 struct wpa_ssid *ssid = wpa_s->conf->ssid;
597
598                 while (ssid) {
599                         if (!ssid->disabled && ssid->scan_ssid)
600                                 break;
601                         ssid = ssid->next;
602                 }
603                 if (ssid) {
604                         wpa_dbg(wpa_s, MSG_DEBUG, "Not rescheduling scan to "
605                                 "ensure that specific SSID scans occur");
606                         return;
607                 }
608         }
609
610         wpa_dbg(wpa_s, MSG_DEBUG, "Setting scan request: %d sec %d usec",
611                 sec, usec);
612         eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
613         eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL);
614 }
615
616
617 /**
618  * wpa_supplicant_req_sched_scan - Start a periodic scheduled scan
619  * @wpa_s: Pointer to wpa_supplicant data
620  *
621  * This function is used to schedule periodic scans for neighboring
622  * access points repeating the scan continuously.
623  */
624 int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s)
625 {
626         struct wpa_driver_scan_params params;
627         enum wpa_states prev_state;
628         struct wpa_ssid *ssid;
629         struct wpabuf *wps_ie = NULL;
630         int ret;
631         int use_wildcard = 0;
632         unsigned int max_sched_scan_ssids;
633
634         if (!wpa_s->sched_scan_supported)
635                 return -1;
636
637         if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS)
638                 max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS;
639         else
640                 max_sched_scan_ssids = wpa_s->max_sched_scan_ssids;
641
642         if (wpa_s->sched_scanning)
643                 return 0;
644
645         os_memset(&params, 0, sizeof(params));
646
647         prev_state = wpa_s->wpa_state;
648         if (wpa_s->wpa_state == WPA_DISCONNECTED ||
649             wpa_s->wpa_state == WPA_INACTIVE)
650                 wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
651
652         /* Find the starting point from which to continue scanning */
653         ssid = wpa_s->conf->ssid;
654         if (wpa_s->prev_sched_ssid) {
655                 while (ssid) {
656                         if (ssid == wpa_s->prev_sched_ssid) {
657                                 ssid = ssid->next;
658                                 break;
659                         }
660                         ssid = ssid->next;
661                 }
662         }
663
664         if (!ssid || !wpa_s->prev_sched_ssid) {
665                 wpa_dbg(wpa_s, MSG_DEBUG, "Beginning of SSID list");
666
667                 wpa_s->sched_scan_interval = 2;
668                 wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2;
669                 wpa_s->first_sched_scan = 1;
670                 ssid = wpa_s->conf->ssid;
671                 wpa_s->prev_sched_ssid = ssid;
672         }
673
674         while (ssid) {
675                 if (ssid->disabled) {
676                         wpa_s->prev_sched_ssid = ssid;
677                         ssid = ssid->next;
678                         continue;
679                 }
680
681                 if (!ssid->scan_ssid)
682                         use_wildcard = 1;
683                 else {
684                         params.ssids[params.num_ssids].ssid =
685                                 ssid->ssid;
686                         params.ssids[params.num_ssids].ssid_len =
687                                 ssid->ssid_len;
688                         params.num_ssids++;
689                         if (params.num_ssids + 1 >= max_sched_scan_ssids) {
690                                 wpa_s->prev_sched_ssid = ssid;
691                                 break;
692                         }
693                 }
694                 wpa_s->prev_sched_ssid = ssid;
695                 ssid = ssid->next;
696         }
697
698         if (ssid || use_wildcard) {
699                 wpa_dbg(wpa_s, MSG_DEBUG, "Include wildcard SSID in "
700                         "the sched scan request");
701                 params.num_ssids++;
702         } else {
703                 wpa_dbg(wpa_s, MSG_DEBUG, "ssid %p - list ended", ssid);
704         }
705
706         if (!params.num_ssids)
707                 return 0;
708
709         if (wpa_s->wps)
710                 wps_ie = wpa_supplicant_extra_ies(wpa_s, &params);
711
712         wpa_dbg(wpa_s, MSG_DEBUG,
713                 "Starting sched scan: interval %d timeout %d",
714                 wpa_s->sched_scan_interval, wpa_s->sched_scan_timeout);
715
716         ret = wpa_supplicant_start_sched_scan(wpa_s, &params,
717                                               wpa_s->sched_scan_interval);
718         wpabuf_free(wps_ie);
719         if (ret) {
720                 wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate sched scan");
721                 if (prev_state != wpa_s->wpa_state)
722                         wpa_supplicant_set_state(wpa_s, prev_state);
723                 return ret;
724         }
725
726         /* If we have more SSIDs to scan, add a timeout so we scan them too */
727         if (ssid || !wpa_s->first_sched_scan) {
728                 wpa_s->sched_scan_timed_out = 0;
729                 eloop_register_timeout(wpa_s->sched_scan_timeout, 0,
730                                        wpa_supplicant_sched_scan_timeout,
731                                        wpa_s, NULL);
732                 wpa_s->first_sched_scan = 0;
733                 wpa_s->sched_scan_timeout /= 2;
734                 wpa_s->sched_scan_interval *= 2;
735         }
736
737         return 0;
738 }
739
740
741 /**
742  * wpa_supplicant_cancel_scan - Cancel a scheduled scan request
743  * @wpa_s: Pointer to wpa_supplicant data
744  *
745  * This function is used to cancel a scan request scheduled with
746  * wpa_supplicant_req_scan().
747  */
748 void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
749 {
750         wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling scan request");
751         eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
752 }
753
754
755 /**
756  * wpa_supplicant_cancel_sched_scan - Stop running scheduled scans
757  * @wpa_s: Pointer to wpa_supplicant data
758  *
759  * This function is used to stop a periodic scheduled scan.
760  */
761 void wpa_supplicant_cancel_sched_scan(struct wpa_supplicant *wpa_s)
762 {
763         if (!wpa_s->sched_scanning)
764                 return;
765
766         wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling sched scan");
767         eloop_cancel_timeout(wpa_supplicant_sched_scan_timeout, wpa_s, NULL);
768         wpa_supplicant_stop_sched_scan(wpa_s);
769 }
770
771
772 void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
773                                     int scanning)
774 {
775         if (wpa_s->scanning != scanning) {
776                 wpa_s->scanning = scanning;
777                 wpas_notify_scanning(wpa_s);
778         }
779 }
780
781
782 static int wpa_scan_get_max_rate(const struct wpa_scan_res *res)
783 {
784         int rate = 0;
785         const u8 *ie;
786         int i;
787
788         ie = wpa_scan_get_ie(res, WLAN_EID_SUPP_RATES);
789         for (i = 0; ie && i < ie[1]; i++) {
790                 if ((ie[i + 2] & 0x7f) > rate)
791                         rate = ie[i + 2] & 0x7f;
792         }
793
794         ie = wpa_scan_get_ie(res, WLAN_EID_EXT_SUPP_RATES);
795         for (i = 0; ie && i < ie[1]; i++) {
796                 if ((ie[i + 2] & 0x7f) > rate)
797                         rate = ie[i + 2] & 0x7f;
798         }
799
800         return rate;
801 }
802
803
804 const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie)
805 {
806         const u8 *end, *pos;
807
808         pos = (const u8 *) (res + 1);
809         end = pos + res->ie_len;
810
811         while (pos + 1 < end) {
812                 if (pos + 2 + pos[1] > end)
813                         break;
814                 if (pos[0] == ie)
815                         return pos;
816                 pos += 2 + pos[1];
817         }
818
819         return NULL;
820 }
821
822
823 const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
824                                   u32 vendor_type)
825 {
826         const u8 *end, *pos;
827
828         pos = (const u8 *) (res + 1);
829         end = pos + res->ie_len;
830
831         while (pos + 1 < end) {
832                 if (pos + 2 + pos[1] > end)
833                         break;
834                 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
835                     vendor_type == WPA_GET_BE32(&pos[2]))
836                         return pos;
837                 pos += 2 + pos[1];
838         }
839
840         return NULL;
841 }
842
843
844 struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
845                                              u32 vendor_type)
846 {
847         struct wpabuf *buf;
848         const u8 *end, *pos;
849
850         buf = wpabuf_alloc(res->ie_len);
851         if (buf == NULL)
852                 return NULL;
853
854         pos = (const u8 *) (res + 1);
855         end = pos + res->ie_len;
856
857         while (pos + 1 < end) {
858                 if (pos + 2 + pos[1] > end)
859                         break;
860                 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
861                     vendor_type == WPA_GET_BE32(&pos[2]))
862                         wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4);
863                 pos += 2 + pos[1];
864         }
865
866         if (wpabuf_len(buf) == 0) {
867                 wpabuf_free(buf);
868                 buf = NULL;
869         }
870
871         return buf;
872 }
873
874
875 struct wpabuf * wpa_scan_get_vendor_ie_multi_beacon(
876         const struct wpa_scan_res *res, u32 vendor_type)
877 {
878         struct wpabuf *buf;
879         const u8 *end, *pos;
880
881         if (res->beacon_ie_len == 0)
882                 return NULL;
883         buf = wpabuf_alloc(res->beacon_ie_len);
884         if (buf == NULL)
885                 return NULL;
886
887         pos = (const u8 *) (res + 1);
888         pos += res->ie_len;
889         end = pos + res->beacon_ie_len;
890
891         while (pos + 1 < end) {
892                 if (pos + 2 + pos[1] > end)
893                         break;
894                 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
895                     vendor_type == WPA_GET_BE32(&pos[2]))
896                         wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4);
897                 pos += 2 + pos[1];
898         }
899
900         if (wpabuf_len(buf) == 0) {
901                 wpabuf_free(buf);
902                 buf = NULL;
903         }
904
905         return buf;
906 }
907
908
909 /* Compare function for sorting scan results. Return >0 if @b is considered
910  * better. */
911 static int wpa_scan_result_compar(const void *a, const void *b)
912 {
913         struct wpa_scan_res **_wa = (void *) a;
914         struct wpa_scan_res **_wb = (void *) b;
915         struct wpa_scan_res *wa = *_wa;
916         struct wpa_scan_res *wb = *_wb;
917         int wpa_a, wpa_b, maxrate_a, maxrate_b;
918
919         /* WPA/WPA2 support preferred */
920         wpa_a = wpa_scan_get_vendor_ie(wa, WPA_IE_VENDOR_TYPE) != NULL ||
921                 wpa_scan_get_ie(wa, WLAN_EID_RSN) != NULL;
922         wpa_b = wpa_scan_get_vendor_ie(wb, WPA_IE_VENDOR_TYPE) != NULL ||
923                 wpa_scan_get_ie(wb, WLAN_EID_RSN) != NULL;
924
925         if (wpa_b && !wpa_a)
926                 return 1;
927         if (!wpa_b && wpa_a)
928                 return -1;
929
930         /* privacy support preferred */
931         if ((wa->caps & IEEE80211_CAP_PRIVACY) == 0 &&
932             (wb->caps & IEEE80211_CAP_PRIVACY))
933                 return 1;
934         if ((wa->caps & IEEE80211_CAP_PRIVACY) &&
935             (wb->caps & IEEE80211_CAP_PRIVACY) == 0)
936                 return -1;
937
938         /* best/max rate preferred if signal level close enough XXX */
939         if ((wa->level && wb->level && abs(wb->level - wa->level) < 5) ||
940             (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) {
941                 maxrate_a = wpa_scan_get_max_rate(wa);
942                 maxrate_b = wpa_scan_get_max_rate(wb);
943                 if (maxrate_a != maxrate_b)
944                         return maxrate_b - maxrate_a;
945         }
946
947         /* use freq for channel preference */
948
949         /* all things being equal, use signal level; if signal levels are
950          * identical, use quality values since some drivers may only report
951          * that value and leave the signal level zero */
952         if (wb->level == wa->level)
953                 return wb->qual - wa->qual;
954         return wb->level - wa->level;
955 }
956
957
958 #ifdef CONFIG_WPS
959 /* Compare function for sorting scan results when searching a WPS AP for
960  * provisioning. Return >0 if @b is considered better. */
961 static int wpa_scan_result_wps_compar(const void *a, const void *b)
962 {
963         struct wpa_scan_res **_wa = (void *) a;
964         struct wpa_scan_res **_wb = (void *) b;
965         struct wpa_scan_res *wa = *_wa;
966         struct wpa_scan_res *wb = *_wb;
967         int uses_wps_a, uses_wps_b;
968         struct wpabuf *wps_a, *wps_b;
969         int res;
970
971         /* Optimization - check WPS IE existence before allocated memory and
972          * doing full reassembly. */
973         uses_wps_a = wpa_scan_get_vendor_ie(wa, WPS_IE_VENDOR_TYPE) != NULL;
974         uses_wps_b = wpa_scan_get_vendor_ie(wb, WPS_IE_VENDOR_TYPE) != NULL;
975         if (uses_wps_a && !uses_wps_b)
976                 return -1;
977         if (!uses_wps_a && uses_wps_b)
978                 return 1;
979
980         if (uses_wps_a && uses_wps_b) {
981                 wps_a = wpa_scan_get_vendor_ie_multi(wa, WPS_IE_VENDOR_TYPE);
982                 wps_b = wpa_scan_get_vendor_ie_multi(wb, WPS_IE_VENDOR_TYPE);
983                 res = wps_ap_priority_compar(wps_a, wps_b);
984                 wpabuf_free(wps_a);
985                 wpabuf_free(wps_b);
986                 if (res)
987                         return res;
988         }
989
990         /*
991          * Do not use current AP security policy as a sorting criteria during
992          * WPS provisioning step since the AP may get reconfigured at the
993          * completion of provisioning.
994          */
995
996         /* all things being equal, use signal level; if signal levels are
997          * identical, use quality values since some drivers may only report
998          * that value and leave the signal level zero */
999         if (wb->level == wa->level)
1000                 return wb->qual - wa->qual;
1001         return wb->level - wa->level;
1002 }
1003 #endif /* CONFIG_WPS */
1004
1005
1006 /**
1007  * wpa_supplicant_get_scan_results - Get scan results
1008  * @wpa_s: Pointer to wpa_supplicant data
1009  * @info: Information about what was scanned or %NULL if not available
1010  * @new_scan: Whether a new scan was performed
1011  * Returns: Scan results, %NULL on failure
1012  *
1013  * This function request the current scan results from the driver and updates
1014  * the local BSS list wpa_s->bss. The caller is responsible for freeing the
1015  * results with wpa_scan_results_free().
1016  */
1017 struct wpa_scan_results *
1018 wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
1019                                 struct scan_info *info, int new_scan)
1020 {
1021         struct wpa_scan_results *scan_res;
1022         size_t i;
1023         int (*compar)(const void *, const void *) = wpa_scan_result_compar;
1024
1025         if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
1026                 scan_res = ieee80211_sta_get_scan_results(wpa_s);
1027         else
1028                 scan_res = wpa_drv_get_scan_results2(wpa_s);
1029         if (scan_res == NULL) {
1030                 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results");
1031                 return NULL;
1032         }
1033
1034 #ifdef CONFIG_WPS
1035         if (wpas_wps_in_progress(wpa_s)) {
1036                 wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Order scan results with WPS "
1037                         "provisioning rules");
1038                 compar = wpa_scan_result_wps_compar;
1039         }
1040 #endif /* CONFIG_WPS */
1041
1042         qsort(scan_res->res, scan_res->num, sizeof(struct wpa_scan_res *),
1043               compar);
1044
1045         wpa_bss_update_start(wpa_s);
1046         for (i = 0; i < scan_res->num; i++)
1047                 wpa_bss_update_scan_res(wpa_s, scan_res->res[i]);
1048         wpa_bss_update_end(wpa_s, info, new_scan);
1049
1050         return scan_res;
1051 }
1052
1053
1054 int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s)
1055 {
1056         struct wpa_scan_results *scan_res;
1057         scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
1058         if (scan_res == NULL)
1059                 return -1;
1060         wpa_scan_results_free(scan_res);
1061
1062         return 0;
1063 }
1064
1065
1066 void wpa_scan_results_free(struct wpa_scan_results *res)
1067 {
1068         size_t i;
1069
1070         if (res == NULL)
1071                 return;
1072
1073         for (i = 0; i < res->num; i++)
1074                 os_free(res->res[i]);
1075         os_free(res->res);
1076         os_free(res);
1077 }