nl80211: Add support for aborting an ongoing scan
[mech_eap.git] / src / drivers / driver_nl80211_scan.c
1 /*
2  * Driver interaction with Linux nl80211/cfg80211 - Scanning
3  * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
4  * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
5  * Copyright (c) 2009-2010, Atheros Communications
6  *
7  * This software may be distributed under the terms of the BSD license.
8  * See README for more details.
9  */
10
11 #include "includes.h"
12 #include <netlink/genl/genl.h>
13
14 #include "utils/common.h"
15 #include "utils/eloop.h"
16 #include "common/ieee802_11_defs.h"
17 #include "common/qca-vendor.h"
18 #include "driver_nl80211.h"
19
20
21 static int get_noise_for_scan_results(struct nl_msg *msg, void *arg)
22 {
23         struct nlattr *tb[NL80211_ATTR_MAX + 1];
24         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
25         struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
26         static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
27                 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
28                 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
29         };
30         struct wpa_scan_results *scan_results = arg;
31         struct wpa_scan_res *scan_res;
32         size_t i;
33
34         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
35                   genlmsg_attrlen(gnlh, 0), NULL);
36
37         if (!tb[NL80211_ATTR_SURVEY_INFO]) {
38                 wpa_printf(MSG_DEBUG, "nl80211: Survey data missing");
39                 return NL_SKIP;
40         }
41
42         if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
43                              tb[NL80211_ATTR_SURVEY_INFO],
44                              survey_policy)) {
45                 wpa_printf(MSG_DEBUG, "nl80211: Failed to parse nested "
46                            "attributes");
47                 return NL_SKIP;
48         }
49
50         if (!sinfo[NL80211_SURVEY_INFO_NOISE])
51                 return NL_SKIP;
52
53         if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
54                 return NL_SKIP;
55
56         for (i = 0; i < scan_results->num; ++i) {
57                 scan_res = scan_results->res[i];
58                 if (!scan_res)
59                         continue;
60                 if ((int) nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
61                     scan_res->freq)
62                         continue;
63                 if (!(scan_res->flags & WPA_SCAN_NOISE_INVALID))
64                         continue;
65                 scan_res->noise = (s8)
66                         nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
67                 scan_res->flags &= ~WPA_SCAN_NOISE_INVALID;
68         }
69
70         return NL_SKIP;
71 }
72
73
74 static int nl80211_get_noise_for_scan_results(
75         struct wpa_driver_nl80211_data *drv,
76         struct wpa_scan_results *scan_res)
77 {
78         struct nl_msg *msg;
79
80         msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
81         return send_and_recv_msgs(drv, msg, get_noise_for_scan_results,
82                                   scan_res);
83 }
84
85
86 /**
87  * wpa_driver_nl80211_scan_timeout - Scan timeout to report scan completion
88  * @eloop_ctx: Driver private data
89  * @timeout_ctx: ctx argument given to wpa_driver_nl80211_init()
90  *
91  * This function can be used as registered timeout when starting a scan to
92  * generate a scan completed event if the driver does not report this.
93  */
94 void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
95 {
96         struct wpa_driver_nl80211_data *drv = eloop_ctx;
97         if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED) {
98                 wpa_driver_nl80211_set_mode(drv->first_bss,
99                                             drv->ap_scan_as_station);
100                 drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
101         }
102         wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
103         wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
104 }
105
106
107 static struct nl_msg *
108 nl80211_scan_common(struct i802_bss *bss, u8 cmd,
109                     struct wpa_driver_scan_params *params)
110 {
111         struct wpa_driver_nl80211_data *drv = bss->drv;
112         struct nl_msg *msg;
113         size_t i;
114         u32 scan_flags = 0;
115
116         msg = nl80211_cmd_msg(bss, 0, cmd);
117         if (!msg)
118                 return NULL;
119
120         if (params->num_ssids) {
121                 struct nlattr *ssids;
122
123                 ssids = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
124                 if (ssids == NULL)
125                         goto fail;
126                 for (i = 0; i < params->num_ssids; i++) {
127                         wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan SSID",
128                                           params->ssids[i].ssid,
129                                           params->ssids[i].ssid_len);
130                         if (nla_put(msg, i + 1, params->ssids[i].ssid_len,
131                                     params->ssids[i].ssid))
132                                 goto fail;
133                 }
134                 nla_nest_end(msg, ssids);
135         } else {
136                 wpa_printf(MSG_DEBUG, "nl80211: Passive scan requested");
137         }
138
139         if (params->extra_ies) {
140                 wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs",
141                             params->extra_ies, params->extra_ies_len);
142                 if (nla_put(msg, NL80211_ATTR_IE, params->extra_ies_len,
143                             params->extra_ies))
144                         goto fail;
145         }
146
147         if (params->freqs) {
148                 struct nlattr *freqs;
149                 freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
150                 if (freqs == NULL)
151                         goto fail;
152                 for (i = 0; params->freqs[i]; i++) {
153                         wpa_printf(MSG_MSGDUMP, "nl80211: Scan frequency %u "
154                                    "MHz", params->freqs[i]);
155                         if (nla_put_u32(msg, i + 1, params->freqs[i]))
156                                 goto fail;
157                 }
158                 nla_nest_end(msg, freqs);
159         }
160
161         os_free(drv->filter_ssids);
162         drv->filter_ssids = params->filter_ssids;
163         params->filter_ssids = NULL;
164         drv->num_filter_ssids = params->num_filter_ssids;
165
166         if (params->only_new_results) {
167                 wpa_printf(MSG_DEBUG, "nl80211: Add NL80211_SCAN_FLAG_FLUSH");
168                 scan_flags |= NL80211_SCAN_FLAG_FLUSH;
169         }
170
171         if (params->low_priority && drv->have_low_prio_scan) {
172                 wpa_printf(MSG_DEBUG,
173                            "nl80211: Add NL80211_SCAN_FLAG_LOW_PRIORITY");
174                 scan_flags |= NL80211_SCAN_FLAG_LOW_PRIORITY;
175         }
176
177         if (params->mac_addr_rand) {
178                 wpa_printf(MSG_DEBUG,
179                            "nl80211: Add NL80211_SCAN_FLAG_RANDOM_ADDR");
180                 scan_flags |= NL80211_SCAN_FLAG_RANDOM_ADDR;
181
182                 if (params->mac_addr) {
183                         wpa_printf(MSG_DEBUG, "nl80211: MAC address: " MACSTR,
184                                    MAC2STR(params->mac_addr));
185                         if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
186                                     params->mac_addr))
187                                 goto fail;
188                 }
189
190                 if (params->mac_addr_mask) {
191                         wpa_printf(MSG_DEBUG, "nl80211: MAC address mask: "
192                                    MACSTR, MAC2STR(params->mac_addr_mask));
193                         if (nla_put(msg, NL80211_ATTR_MAC_MASK, ETH_ALEN,
194                                     params->mac_addr_mask))
195                                 goto fail;
196                 }
197         }
198
199         if (scan_flags &&
200             nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, scan_flags))
201                 goto fail;
202
203         return msg;
204
205 fail:
206         nlmsg_free(msg);
207         return NULL;
208 }
209
210
211 /**
212  * wpa_driver_nl80211_scan - Request the driver to initiate scan
213  * @bss: Pointer to private driver data from wpa_driver_nl80211_init()
214  * @params: Scan parameters
215  * Returns: 0 on success, -1 on failure
216  */
217 int wpa_driver_nl80211_scan(struct i802_bss *bss,
218                             struct wpa_driver_scan_params *params)
219 {
220         struct wpa_driver_nl80211_data *drv = bss->drv;
221         int ret = -1, timeout;
222         struct nl_msg *msg = NULL;
223
224         wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");
225         drv->scan_for_auth = 0;
226
227         if (TEST_FAIL())
228                 return -1;
229
230         msg = nl80211_scan_common(bss, NL80211_CMD_TRIGGER_SCAN, params);
231         if (!msg)
232                 return -1;
233
234         if (params->p2p_probe) {
235                 struct nlattr *rates;
236
237                 wpa_printf(MSG_DEBUG, "nl80211: P2P probe - mask SuppRates");
238
239                 rates = nla_nest_start(msg, NL80211_ATTR_SCAN_SUPP_RATES);
240                 if (rates == NULL)
241                         goto fail;
242
243                 /*
244                  * Remove 2.4 GHz rates 1, 2, 5.5, 11 Mbps from supported rates
245                  * by masking out everything else apart from the OFDM rates 6,
246                  * 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS rates. All 5 GHz
247                  * rates are left enabled.
248                  */
249                 if (nla_put(msg, NL80211_BAND_2GHZ, 8,
250                             "\x0c\x12\x18\x24\x30\x48\x60\x6c"))
251                         goto fail;
252                 nla_nest_end(msg, rates);
253
254                 if (nla_put_flag(msg, NL80211_ATTR_TX_NO_CCK_RATE))
255                         goto fail;
256         }
257
258         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
259         msg = NULL;
260         if (ret) {
261                 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
262                            "(%s)", ret, strerror(-ret));
263                 if (drv->hostapd && is_ap_interface(drv->nlmode)) {
264                         enum nl80211_iftype old_mode = drv->nlmode;
265
266                         /*
267                          * mac80211 does not allow scan requests in AP mode, so
268                          * try to do this in station mode.
269                          */
270                         if (wpa_driver_nl80211_set_mode(
271                                     bss, NL80211_IFTYPE_STATION))
272                                 goto fail;
273
274                         if (wpa_driver_nl80211_scan(bss, params)) {
275                                 wpa_driver_nl80211_set_mode(bss, old_mode);
276                                 goto fail;
277                         }
278
279                         /* Restore AP mode when processing scan results */
280                         drv->ap_scan_as_station = old_mode;
281                         ret = 0;
282                 } else
283                         goto fail;
284         }
285
286         drv->scan_state = SCAN_REQUESTED;
287         /* Not all drivers generate "scan completed" wireless event, so try to
288          * read results after a timeout. */
289         timeout = 10;
290         if (drv->scan_complete_events) {
291                 /*
292                  * The driver seems to deliver events to notify when scan is
293                  * complete, so use longer timeout to avoid race conditions
294                  * with scanning and following association request.
295                  */
296                 timeout = 30;
297         }
298         wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
299                    "seconds", ret, timeout);
300         eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
301         eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,
302                                drv, drv->ctx);
303         drv->last_scan_cmd = NL80211_CMD_TRIGGER_SCAN;
304
305 fail:
306         nlmsg_free(msg);
307         return ret;
308 }
309
310
311 /**
312  * wpa_driver_nl80211_sched_scan - Initiate a scheduled scan
313  * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
314  * @params: Scan parameters
315  * @interval: Interval between scan cycles in milliseconds
316  * Returns: 0 on success, -1 on failure or if not supported
317  */
318 int wpa_driver_nl80211_sched_scan(void *priv,
319                                   struct wpa_driver_scan_params *params,
320                                   u32 interval)
321 {
322         struct i802_bss *bss = priv;
323         struct wpa_driver_nl80211_data *drv = bss->drv;
324         int ret = -1;
325         struct nl_msg *msg;
326         size_t i;
327
328         wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: sched_scan request");
329
330 #ifdef ANDROID
331         if (!drv->capa.sched_scan_supported)
332                 return android_pno_start(bss, params);
333 #endif /* ANDROID */
334
335         msg = nl80211_scan_common(bss, NL80211_CMD_START_SCHED_SCAN, params);
336         if (!msg ||
337             nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, interval))
338                 goto fail;
339
340         if ((drv->num_filter_ssids &&
341             (int) drv->num_filter_ssids <= drv->capa.max_match_sets) ||
342             params->filter_rssi) {
343                 struct nlattr *match_sets;
344                 match_sets = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
345                 if (match_sets == NULL)
346                         goto fail;
347
348                 for (i = 0; i < drv->num_filter_ssids; i++) {
349                         struct nlattr *match_set_ssid;
350                         wpa_hexdump_ascii(MSG_MSGDUMP,
351                                           "nl80211: Sched scan filter SSID",
352                                           drv->filter_ssids[i].ssid,
353                                           drv->filter_ssids[i].ssid_len);
354
355                         match_set_ssid = nla_nest_start(msg, i + 1);
356                         if (match_set_ssid == NULL ||
357                             nla_put(msg, NL80211_ATTR_SCHED_SCAN_MATCH_SSID,
358                                     drv->filter_ssids[i].ssid_len,
359                                     drv->filter_ssids[i].ssid) ||
360                             (params->filter_rssi &&
361                              nla_put_u32(msg,
362                                          NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
363                                          params->filter_rssi)))
364                                 goto fail;
365
366                         nla_nest_end(msg, match_set_ssid);
367                 }
368
369                 /*
370                  * Due to backward compatibility code, newer kernels treat this
371                  * matchset (with only an RSSI filter) as the default for all
372                  * other matchsets, unless it's the only one, in which case the
373                  * matchset will actually allow all SSIDs above the RSSI.
374                  */
375                 if (params->filter_rssi) {
376                         struct nlattr *match_set_rssi;
377                         match_set_rssi = nla_nest_start(msg, 0);
378                         if (match_set_rssi == NULL ||
379                             nla_put_u32(msg, NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
380                                         params->filter_rssi))
381                                 goto fail;
382                         wpa_printf(MSG_MSGDUMP,
383                                    "nl80211: Sched scan RSSI filter %d dBm",
384                                    params->filter_rssi);
385                         nla_nest_end(msg, match_set_rssi);
386                 }
387
388                 nla_nest_end(msg, match_sets);
389         }
390
391         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
392
393         /* TODO: if we get an error here, we should fall back to normal scan */
394
395         msg = NULL;
396         if (ret) {
397                 wpa_printf(MSG_DEBUG, "nl80211: Sched scan start failed: "
398                            "ret=%d (%s)", ret, strerror(-ret));
399                 goto fail;
400         }
401
402         wpa_printf(MSG_DEBUG, "nl80211: Sched scan requested (ret=%d) - "
403                    "scan interval %d msec", ret, interval);
404
405 fail:
406         nlmsg_free(msg);
407         return ret;
408 }
409
410
411 /**
412  * wpa_driver_nl80211_stop_sched_scan - Stop a scheduled scan
413  * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
414  * Returns: 0 on success, -1 on failure or if not supported
415  */
416 int wpa_driver_nl80211_stop_sched_scan(void *priv)
417 {
418         struct i802_bss *bss = priv;
419         struct wpa_driver_nl80211_data *drv = bss->drv;
420         int ret;
421         struct nl_msg *msg;
422
423 #ifdef ANDROID
424         if (!drv->capa.sched_scan_supported)
425                 return android_pno_stop(bss);
426 #endif /* ANDROID */
427
428         msg = nl80211_drv_msg(drv, 0, NL80211_CMD_STOP_SCHED_SCAN);
429         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
430         if (ret) {
431                 wpa_printf(MSG_DEBUG,
432                            "nl80211: Sched scan stop failed: ret=%d (%s)",
433                            ret, strerror(-ret));
434         } else {
435                 wpa_printf(MSG_DEBUG,
436                            "nl80211: Sched scan stop sent");
437         }
438
439         return ret;
440 }
441
442
443 const u8 * nl80211_get_ie(const u8 *ies, size_t ies_len, u8 ie)
444 {
445         const u8 *end, *pos;
446
447         if (ies == NULL)
448                 return NULL;
449
450         pos = ies;
451         end = ies + ies_len;
452
453         while (end - pos > 1) {
454                 if (2 + pos[1] > end - pos)
455                         break;
456                 if (pos[0] == ie)
457                         return pos;
458                 pos += 2 + pos[1];
459         }
460
461         return NULL;
462 }
463
464
465 static int nl80211_scan_filtered(struct wpa_driver_nl80211_data *drv,
466                                  const u8 *ie, size_t ie_len)
467 {
468         const u8 *ssid;
469         size_t i;
470
471         if (drv->filter_ssids == NULL)
472                 return 0;
473
474         ssid = nl80211_get_ie(ie, ie_len, WLAN_EID_SSID);
475         if (ssid == NULL)
476                 return 1;
477
478         for (i = 0; i < drv->num_filter_ssids; i++) {
479                 if (ssid[1] == drv->filter_ssids[i].ssid_len &&
480                     os_memcmp(ssid + 2, drv->filter_ssids[i].ssid, ssid[1]) ==
481                     0)
482                         return 0;
483         }
484
485         return 1;
486 }
487
488
489 int bss_info_handler(struct nl_msg *msg, void *arg)
490 {
491         struct nlattr *tb[NL80211_ATTR_MAX + 1];
492         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
493         struct nlattr *bss[NL80211_BSS_MAX + 1];
494         static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
495                 [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
496                 [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
497                 [NL80211_BSS_TSF] = { .type = NLA_U64 },
498                 [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
499                 [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
500                 [NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
501                 [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
502                 [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
503                 [NL80211_BSS_STATUS] = { .type = NLA_U32 },
504                 [NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
505                 [NL80211_BSS_BEACON_IES] = { .type = NLA_UNSPEC },
506         };
507         struct nl80211_bss_info_arg *_arg = arg;
508         struct wpa_scan_results *res = _arg->res;
509         struct wpa_scan_res **tmp;
510         struct wpa_scan_res *r;
511         const u8 *ie, *beacon_ie;
512         size_t ie_len, beacon_ie_len;
513         u8 *pos;
514         size_t i;
515
516         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
517                   genlmsg_attrlen(gnlh, 0), NULL);
518         if (!tb[NL80211_ATTR_BSS])
519                 return NL_SKIP;
520         if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
521                              bss_policy))
522                 return NL_SKIP;
523         if (bss[NL80211_BSS_STATUS]) {
524                 enum nl80211_bss_status status;
525                 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
526                 if (status == NL80211_BSS_STATUS_ASSOCIATED &&
527                     bss[NL80211_BSS_FREQUENCY]) {
528                         _arg->assoc_freq =
529                                 nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
530                         wpa_printf(MSG_DEBUG, "nl80211: Associated on %u MHz",
531                                    _arg->assoc_freq);
532                 }
533                 if (status == NL80211_BSS_STATUS_IBSS_JOINED &&
534                     bss[NL80211_BSS_FREQUENCY]) {
535                         _arg->ibss_freq =
536                                 nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
537                         wpa_printf(MSG_DEBUG, "nl80211: IBSS-joined on %u MHz",
538                                    _arg->ibss_freq);
539                 }
540                 if (status == NL80211_BSS_STATUS_ASSOCIATED &&
541                     bss[NL80211_BSS_BSSID]) {
542                         os_memcpy(_arg->assoc_bssid,
543                                   nla_data(bss[NL80211_BSS_BSSID]), ETH_ALEN);
544                         wpa_printf(MSG_DEBUG, "nl80211: Associated with "
545                                    MACSTR, MAC2STR(_arg->assoc_bssid));
546                 }
547         }
548         if (!res)
549                 return NL_SKIP;
550         if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
551                 ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
552                 ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
553         } else {
554                 ie = NULL;
555                 ie_len = 0;
556         }
557         if (bss[NL80211_BSS_BEACON_IES]) {
558                 beacon_ie = nla_data(bss[NL80211_BSS_BEACON_IES]);
559                 beacon_ie_len = nla_len(bss[NL80211_BSS_BEACON_IES]);
560         } else {
561                 beacon_ie = NULL;
562                 beacon_ie_len = 0;
563         }
564
565         if (nl80211_scan_filtered(_arg->drv, ie ? ie : beacon_ie,
566                                   ie ? ie_len : beacon_ie_len))
567                 return NL_SKIP;
568
569         r = os_zalloc(sizeof(*r) + ie_len + beacon_ie_len);
570         if (r == NULL)
571                 return NL_SKIP;
572         if (bss[NL80211_BSS_BSSID])
573                 os_memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),
574                           ETH_ALEN);
575         if (bss[NL80211_BSS_FREQUENCY])
576                 r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
577         if (bss[NL80211_BSS_BEACON_INTERVAL])
578                 r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]);
579         if (bss[NL80211_BSS_CAPABILITY])
580                 r->caps = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
581         r->flags |= WPA_SCAN_NOISE_INVALID;
582         if (bss[NL80211_BSS_SIGNAL_MBM]) {
583                 r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
584                 r->level /= 100; /* mBm to dBm */
585                 r->flags |= WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID;
586         } else if (bss[NL80211_BSS_SIGNAL_UNSPEC]) {
587                 r->level = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);
588                 r->flags |= WPA_SCAN_QUAL_INVALID;
589         } else
590                 r->flags |= WPA_SCAN_LEVEL_INVALID | WPA_SCAN_QUAL_INVALID;
591         if (bss[NL80211_BSS_TSF])
592                 r->tsf = nla_get_u64(bss[NL80211_BSS_TSF]);
593         if (bss[NL80211_BSS_BEACON_TSF]) {
594                 u64 tsf = nla_get_u64(bss[NL80211_BSS_BEACON_TSF]);
595                 if (tsf > r->tsf)
596                         r->tsf = tsf;
597         }
598         if (bss[NL80211_BSS_SEEN_MS_AGO])
599                 r->age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]);
600         r->ie_len = ie_len;
601         pos = (u8 *) (r + 1);
602         if (ie) {
603                 os_memcpy(pos, ie, ie_len);
604                 pos += ie_len;
605         }
606         r->beacon_ie_len = beacon_ie_len;
607         if (beacon_ie)
608                 os_memcpy(pos, beacon_ie, beacon_ie_len);
609
610         if (bss[NL80211_BSS_STATUS]) {
611                 enum nl80211_bss_status status;
612                 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
613                 switch (status) {
614                 case NL80211_BSS_STATUS_ASSOCIATED:
615                         r->flags |= WPA_SCAN_ASSOCIATED;
616                         break;
617                 default:
618                         break;
619                 }
620         }
621
622         /*
623          * cfg80211 maintains separate BSS table entries for APs if the same
624          * BSSID,SSID pair is seen on multiple channels. wpa_supplicant does
625          * not use frequency as a separate key in the BSS table, so filter out
626          * duplicated entries. Prefer associated BSS entry in such a case in
627          * order to get the correct frequency into the BSS table. Similarly,
628          * prefer newer entries over older.
629          */
630         for (i = 0; i < res->num; i++) {
631                 const u8 *s1, *s2;
632                 if (os_memcmp(res->res[i]->bssid, r->bssid, ETH_ALEN) != 0)
633                         continue;
634
635                 s1 = nl80211_get_ie((u8 *) (res->res[i] + 1),
636                                     res->res[i]->ie_len, WLAN_EID_SSID);
637                 s2 = nl80211_get_ie((u8 *) (r + 1), r->ie_len, WLAN_EID_SSID);
638                 if (s1 == NULL || s2 == NULL || s1[1] != s2[1] ||
639                     os_memcmp(s1, s2, 2 + s1[1]) != 0)
640                         continue;
641
642                 /* Same BSSID,SSID was already included in scan results */
643                 wpa_printf(MSG_DEBUG, "nl80211: Remove duplicated scan result "
644                            "for " MACSTR, MAC2STR(r->bssid));
645
646                 if (((r->flags & WPA_SCAN_ASSOCIATED) &&
647                      !(res->res[i]->flags & WPA_SCAN_ASSOCIATED)) ||
648                     r->age < res->res[i]->age) {
649                         os_free(res->res[i]);
650                         res->res[i] = r;
651                 } else
652                         os_free(r);
653                 return NL_SKIP;
654         }
655
656         tmp = os_realloc_array(res->res, res->num + 1,
657                                sizeof(struct wpa_scan_res *));
658         if (tmp == NULL) {
659                 os_free(r);
660                 return NL_SKIP;
661         }
662         tmp[res->num++] = r;
663         res->res = tmp;
664
665         return NL_SKIP;
666 }
667
668
669 static void clear_state_mismatch(struct wpa_driver_nl80211_data *drv,
670                                  const u8 *addr)
671 {
672         if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
673                 wpa_printf(MSG_DEBUG, "nl80211: Clear possible state "
674                            "mismatch (" MACSTR ")", MAC2STR(addr));
675                 wpa_driver_nl80211_mlme(drv, addr,
676                                         NL80211_CMD_DEAUTHENTICATE,
677                                         WLAN_REASON_PREV_AUTH_NOT_VALID, 1);
678         }
679 }
680
681
682 static void wpa_driver_nl80211_check_bss_status(
683         struct wpa_driver_nl80211_data *drv, struct wpa_scan_results *res)
684 {
685         size_t i;
686
687         for (i = 0; i < res->num; i++) {
688                 struct wpa_scan_res *r = res->res[i];
689
690                 if (r->flags & WPA_SCAN_ASSOCIATED) {
691                         wpa_printf(MSG_DEBUG, "nl80211: Scan results "
692                                    "indicate BSS status with " MACSTR
693                                    " as associated",
694                                    MAC2STR(r->bssid));
695                         if (is_sta_interface(drv->nlmode) &&
696                             !drv->associated) {
697                                 wpa_printf(MSG_DEBUG, "nl80211: Local state "
698                                            "(not associated) does not match "
699                                            "with BSS state");
700                                 clear_state_mismatch(drv, r->bssid);
701                         } else if (is_sta_interface(drv->nlmode) &&
702                                    os_memcmp(drv->bssid, r->bssid, ETH_ALEN) !=
703                                    0) {
704                                 wpa_printf(MSG_DEBUG, "nl80211: Local state "
705                                            "(associated with " MACSTR ") does "
706                                            "not match with BSS state",
707                                            MAC2STR(drv->bssid));
708                                 clear_state_mismatch(drv, r->bssid);
709                                 clear_state_mismatch(drv, drv->bssid);
710                         }
711                 }
712         }
713 }
714
715
716 static struct wpa_scan_results *
717 nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv)
718 {
719         struct nl_msg *msg;
720         struct wpa_scan_results *res;
721         int ret;
722         struct nl80211_bss_info_arg arg;
723
724         res = os_zalloc(sizeof(*res));
725         if (res == NULL)
726                 return NULL;
727         if (!(msg = nl80211_cmd_msg(drv->first_bss, NLM_F_DUMP,
728                                     NL80211_CMD_GET_SCAN))) {
729                 wpa_scan_results_free(res);
730                 return NULL;
731         }
732
733         arg.drv = drv;
734         arg.res = res;
735         ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
736         if (ret == 0) {
737                 wpa_printf(MSG_DEBUG, "nl80211: Received scan results (%lu "
738                            "BSSes)", (unsigned long) res->num);
739                 nl80211_get_noise_for_scan_results(drv, res);
740                 return res;
741         }
742         wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
743                    "(%s)", ret, strerror(-ret));
744         wpa_scan_results_free(res);
745         return NULL;
746 }
747
748
749 /**
750  * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results
751  * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
752  * Returns: Scan results on success, -1 on failure
753  */
754 struct wpa_scan_results * wpa_driver_nl80211_get_scan_results(void *priv)
755 {
756         struct i802_bss *bss = priv;
757         struct wpa_driver_nl80211_data *drv = bss->drv;
758         struct wpa_scan_results *res;
759
760         res = nl80211_get_scan_results(drv);
761         if (res)
762                 wpa_driver_nl80211_check_bss_status(drv, res);
763         return res;
764 }
765
766
767 void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv)
768 {
769         struct wpa_scan_results *res;
770         size_t i;
771
772         res = nl80211_get_scan_results(drv);
773         if (res == NULL) {
774                 wpa_printf(MSG_DEBUG, "nl80211: Failed to get scan results");
775                 return;
776         }
777
778         wpa_printf(MSG_DEBUG, "nl80211: Scan result dump");
779         for (i = 0; i < res->num; i++) {
780                 struct wpa_scan_res *r = res->res[i];
781                 wpa_printf(MSG_DEBUG, "nl80211: %d/%d " MACSTR "%s",
782                            (int) i, (int) res->num, MAC2STR(r->bssid),
783                            r->flags & WPA_SCAN_ASSOCIATED ? " [assoc]" : "");
784         }
785
786         wpa_scan_results_free(res);
787 }
788
789
790 int wpa_driver_nl80211_abort_scan(void *priv)
791 {
792         struct i802_bss *bss = priv;
793         struct wpa_driver_nl80211_data *drv = bss->drv;
794         int ret;
795         struct nl_msg *msg;
796
797         wpa_printf(MSG_DEBUG, "nl80211: Abort scan");
798         msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_ABORT_SCAN);
799         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
800         if (ret) {
801                 wpa_printf(MSG_DEBUG, "nl80211: Abort scan failed: ret=%d (%s)",
802                            ret, strerror(-ret));
803         }
804
805         return ret;
806 }
807
808
809 #ifdef CONFIG_DRIVER_NL80211_QCA
810
811 static int scan_cookie_handler(struct nl_msg *msg, void *arg)
812 {
813         struct nlattr *tb[NL80211_ATTR_MAX + 1];
814         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
815         u64 *cookie = arg;
816
817         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
818                   genlmsg_attrlen(gnlh, 0), NULL);
819
820         if (tb[NL80211_ATTR_VENDOR_DATA]) {
821                 struct nlattr *nl_vendor = tb[NL80211_ATTR_VENDOR_DATA];
822                 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
823
824                 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
825                           nla_data(nl_vendor), nla_len(nl_vendor), NULL);
826
827                 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE])
828                         *cookie = nla_get_u64(
829                                 tb_vendor[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
830         }
831
832         return NL_SKIP;
833 }
834
835
836 /**
837  * wpa_driver_nl80211_vendor_scan - Request the driver to initiate a vendor scan
838  * @bss: Pointer to private driver data from wpa_driver_nl80211_init()
839  * @params: Scan parameters
840  * Returns: 0 on success, -1 on failure
841  */
842 int wpa_driver_nl80211_vendor_scan(struct i802_bss *bss,
843                                    struct wpa_driver_scan_params *params)
844 {
845         struct wpa_driver_nl80211_data *drv = bss->drv;
846         struct nl_msg *msg = NULL;
847         struct nlattr *attr;
848         size_t i;
849         u32 scan_flags = 0;
850         int ret = -1;
851         u64 cookie = 0;
852
853         wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: vendor scan request");
854         drv->scan_for_auth = 0;
855
856         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
857             nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
858             nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
859                         QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN) )
860                 goto fail;
861
862         attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
863         if (attr == NULL)
864                 goto fail;
865
866         if (params->num_ssids) {
867                 struct nlattr *ssids;
868
869                 ssids = nla_nest_start(msg, QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS);
870                 if (ssids == NULL)
871                         goto fail;
872                 for (i = 0; i < params->num_ssids; i++) {
873                         wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan SSID",
874                                         params->ssids[i].ssid,
875                                         params->ssids[i].ssid_len);
876                         if (nla_put(msg, i + 1, params->ssids[i].ssid_len,
877                                     params->ssids[i].ssid))
878                                 goto fail;
879                 }
880                 nla_nest_end(msg, ssids);
881         }
882
883         if (params->extra_ies) {
884                 wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs",
885                             params->extra_ies, params->extra_ies_len);
886                 if (nla_put(msg, QCA_WLAN_VENDOR_ATTR_SCAN_IE,
887                             params->extra_ies_len, params->extra_ies))
888                         goto fail;
889         }
890
891         if (params->freqs) {
892                 struct nlattr *freqs;
893
894                 freqs = nla_nest_start(msg,
895                                        QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES);
896                 if (freqs == NULL)
897                         goto fail;
898                 for (i = 0; params->freqs[i]; i++) {
899                         wpa_printf(MSG_MSGDUMP,
900                                    "nl80211: Scan frequency %u MHz",
901                                    params->freqs[i]);
902                         if (nla_put_u32(msg, i + 1, params->freqs[i]))
903                                 goto fail;
904                 }
905                 nla_nest_end(msg, freqs);
906         }
907
908         os_free(drv->filter_ssids);
909         drv->filter_ssids = params->filter_ssids;
910         params->filter_ssids = NULL;
911         drv->num_filter_ssids = params->num_filter_ssids;
912
913         if (params->low_priority && drv->have_low_prio_scan) {
914                 wpa_printf(MSG_DEBUG,
915                            "nl80211: Add NL80211_SCAN_FLAG_LOW_PRIORITY");
916                 scan_flags |= NL80211_SCAN_FLAG_LOW_PRIORITY;
917         }
918
919         if (params->mac_addr_rand) {
920                 wpa_printf(MSG_DEBUG,
921                            "nl80211: Add NL80211_SCAN_FLAG_RANDOM_ADDR");
922                 scan_flags |= NL80211_SCAN_FLAG_RANDOM_ADDR;
923
924                 if (params->mac_addr) {
925                         wpa_printf(MSG_DEBUG, "nl80211: MAC address: " MACSTR,
926                                    MAC2STR(params->mac_addr));
927                         if (nla_put(msg, QCA_WLAN_VENDOR_ATTR_SCAN_MAC,
928                                     ETH_ALEN, params->mac_addr))
929                                 goto fail;
930                 }
931
932                 if (params->mac_addr_mask) {
933                         wpa_printf(MSG_DEBUG, "nl80211: MAC address mask: "
934                                    MACSTR, MAC2STR(params->mac_addr_mask));
935                         if (nla_put(msg, QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK,
936                                     ETH_ALEN, params->mac_addr_mask))
937                                 goto fail;
938                 }
939         }
940
941         if (scan_flags &&
942             nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, scan_flags))
943                 goto fail;
944
945         if (params->p2p_probe) {
946                 struct nlattr *rates;
947
948                 wpa_printf(MSG_DEBUG, "nl80211: P2P probe - mask SuppRates");
949
950                 rates = nla_nest_start(msg,
951                                        QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES);
952                 if (rates == NULL)
953                         goto fail;
954
955                 /*
956                  * Remove 2.4 GHz rates 1, 2, 5.5, 11 Mbps from supported rates
957                  * by masking out everything else apart from the OFDM rates 6,
958                  * 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS rates. All 5 GHz
959                  * rates are left enabled.
960                  */
961                 if (nla_put(msg, NL80211_BAND_2GHZ, 8,
962                             "\x0c\x12\x18\x24\x30\x48\x60\x6c"))
963                         goto fail;
964                 nla_nest_end(msg, rates);
965
966                 if (nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE))
967                         goto fail;
968         }
969
970         nla_nest_end(msg, attr);
971
972         ret = send_and_recv_msgs(drv, msg, scan_cookie_handler, &cookie);
973         msg = NULL;
974         if (ret) {
975                 wpa_printf(MSG_DEBUG,
976                            "nl80211: Vendor scan trigger failed: ret=%d (%s)",
977                            ret, strerror(-ret));
978                 goto fail;
979         }
980
981         drv->vendor_scan_cookie = cookie;
982         drv->scan_state = SCAN_REQUESTED;
983
984         wpa_printf(MSG_DEBUG,
985                    "nl80211: Vendor scan requested (ret=%d) - scan timeout 30 seconds, scan cookie:0x%llx",
986                    ret, (long long unsigned int) cookie);
987         eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
988         eloop_register_timeout(30, 0, wpa_driver_nl80211_scan_timeout,
989                                drv, drv->ctx);
990         drv->last_scan_cmd = NL80211_CMD_VENDOR;
991
992 fail:
993         nlmsg_free(msg);
994         return ret;
995 }
996
997 #endif /* CONFIG_DRIVER_NL80211_QCA */