1 /*
2 * Driver interaction with Linux nl80211/cfg80211 - Scanning
3 * Copyright(c) 2015 Intel Deutschland GmbH
4 * Copyright (c) 2002-2014, Jouni Malinen <[email protected]>
5 * Copyright (c) 2007, Johannes Berg <[email protected]>
6 * Copyright (c) 2009-2010, Atheros Communications
7 *
8 * This software may be distributed under the terms of the BSD license.
9 * See README for more details.
10 */
11
12 #include "includes.h"
13 #include <time.h>
14 #include <netlink/genl/genl.h>
15
16 #include "utils/common.h"
17 #include "utils/eloop.h"
18 #include "common/ieee802_11_defs.h"
19 #include "common/ieee802_11_common.h"
20 #include "common/qca-vendor.h"
21 #include "driver_nl80211.h"
22
23
24 #define MAX_NL80211_NOISE_FREQS 100
25
26 struct nl80211_noise_info {
27 u32 freq[MAX_NL80211_NOISE_FREQS];
28 s8 noise[MAX_NL80211_NOISE_FREQS];
29 unsigned int count;
30 };
31
get_noise_for_scan_results(struct nl_msg * msg,void * arg)32 static int get_noise_for_scan_results(struct nl_msg *msg, void *arg)
33 {
34 struct nlattr *tb[NL80211_ATTR_MAX + 1];
35 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
36 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
37 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
38 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
39 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
40 };
41 struct nl80211_noise_info *info = arg;
42
43 if (info->count >= MAX_NL80211_NOISE_FREQS)
44 return NL_SKIP;
45
46 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
47 genlmsg_attrlen(gnlh, 0), NULL);
48
49 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
50 wpa_printf(MSG_DEBUG, "nl80211: Survey data missing");
51 return NL_SKIP;
52 }
53
54 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
55 tb[NL80211_ATTR_SURVEY_INFO],
56 survey_policy)) {
57 wpa_printf(MSG_DEBUG, "nl80211: Failed to parse nested "
58 "attributes");
59 return NL_SKIP;
60 }
61
62 if (!sinfo[NL80211_SURVEY_INFO_NOISE])
63 return NL_SKIP;
64
65 if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
66 return NL_SKIP;
67
68 info->freq[info->count] =
69 nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
70 info->noise[info->count] =
71 (s8) nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
72 info->count++;
73
74 return NL_SKIP;
75 }
76
77
nl80211_get_noise_for_scan_results(struct wpa_driver_nl80211_data * drv,struct nl80211_noise_info * info)78 static int nl80211_get_noise_for_scan_results(
79 struct wpa_driver_nl80211_data *drv, struct nl80211_noise_info *info)
80 {
81 struct nl_msg *msg;
82
83 os_memset(info, 0, sizeof(*info));
84 msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
85 return send_and_recv_resp(drv, msg, get_noise_for_scan_results, info);
86 }
87
88
nl80211_abort_scan(struct i802_bss * bss)89 static int nl80211_abort_scan(struct i802_bss *bss)
90 {
91 int ret;
92 struct nl_msg *msg;
93 struct wpa_driver_nl80211_data *drv = bss->drv;
94
95 wpa_printf(MSG_DEBUG, "nl80211: Abort scan");
96 msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_ABORT_SCAN);
97 ret = send_and_recv_cmd(drv, msg);
98 if (ret) {
99 wpa_printf(MSG_DEBUG, "nl80211: Abort scan failed: ret=%d (%s)",
100 ret, strerror(-ret));
101 }
102 return ret;
103 }
104
105
106 #ifdef CONFIG_DRIVER_NL80211_QCA
nl80211_abort_vendor_scan(struct wpa_driver_nl80211_data * drv,u64 scan_cookie)107 static int nl80211_abort_vendor_scan(struct wpa_driver_nl80211_data *drv,
108 u64 scan_cookie)
109 {
110 struct nl_msg *msg;
111 struct nlattr *params;
112 int ret;
113
114 wpa_printf(MSG_DEBUG, "nl80211: Abort vendor scan with cookie 0x%llx",
115 (long long unsigned int) scan_cookie);
116
117 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
118 if (!msg ||
119 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
120 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
121 QCA_NL80211_VENDOR_SUBCMD_ABORT_SCAN) ||
122 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
123 nla_put_u64(msg, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE, scan_cookie))
124 goto fail;
125
126 nla_nest_end(msg, params);
127
128 ret = send_and_recv_cmd(drv, msg);
129 msg = NULL;
130 if (ret) {
131 wpa_printf(MSG_INFO,
132 "nl80211: Aborting vendor scan with cookie 0x%llx failed: ret=%d (%s)",
133 (long long unsigned int) scan_cookie, ret,
134 strerror(-ret));
135 goto fail;
136 }
137 return 0;
138 fail:
139 nlmsg_free(msg);
140 return -1;
141 }
142 #endif /* CONFIG_DRIVER_NL80211_QCA */
143
144
145 /**
146 * wpa_driver_nl80211_scan_timeout - Scan timeout to report scan completion
147 * @eloop_ctx: Driver private data
148 * @timeout_ctx: ctx argument given to wpa_driver_nl80211_init()
149 *
150 * This function can be used as registered timeout when starting a scan to
151 * generate a scan completed event if the driver does not report this.
152 */
wpa_driver_nl80211_scan_timeout(void * eloop_ctx,void * timeout_ctx)153 void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
154 {
155 struct wpa_driver_nl80211_data *drv = eloop_ctx;
156 struct i802_bss *bss;
157
158 wpa_printf(MSG_DEBUG, "nl80211: Scan timeout - try to abort it");
159 #ifdef CONFIG_DRIVER_NL80211_QCA
160 if (drv->vendor_scan_cookie &&
161 nl80211_abort_vendor_scan(drv, drv->vendor_scan_cookie) == 0)
162 return;
163 #endif /* CONFIG_DRIVER_NL80211_QCA */
164
165 for (bss = drv->first_bss; bss; bss = bss->next) {
166 if (bss->scan_link)
167 break;
168 }
169
170 if (!bss) {
171 wpa_printf(MSG_DEBUG, "nl80211: Failed to find scan BSS");
172 return;
173 }
174
175 if (!drv->vendor_scan_cookie &&
176 nl80211_abort_scan(bss) == 0) {
177 bss->scan_link = NULL;
178 return;
179 }
180
181 wpa_printf(MSG_DEBUG, "nl80211: Failed to abort scan");
182
183 if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED)
184 nl80211_restore_ap_mode(bss);
185
186 wpa_printf(MSG_DEBUG, "nl80211: Try to get scan results");
187 wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
188 }
189
190
191 static struct nl_msg *
nl80211_scan_common(struct i802_bss * bss,u8 cmd,struct wpa_driver_scan_params * params)192 nl80211_scan_common(struct i802_bss *bss, u8 cmd,
193 struct wpa_driver_scan_params *params)
194 {
195 struct wpa_driver_nl80211_data *drv = bss->drv;
196 struct nl_msg *msg;
197 size_t i;
198 u32 scan_flags = 0;
199
200 msg = nl80211_cmd_msg(bss, 0, cmd);
201 if (!msg)
202 return NULL;
203
204 if (params->num_ssids) {
205 struct nlattr *ssids;
206
207 ssids = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
208 if (ssids == NULL)
209 goto fail;
210 for (i = 0; i < params->num_ssids; i++) {
211 wpa_printf(MSG_MSGDUMP, "nl80211: Scan SSID %s",
212 wpa_ssid_txt(params->ssids[i].ssid,
213 params->ssids[i].ssid_len));
214 if (nla_put(msg, i + 1, params->ssids[i].ssid_len,
215 params->ssids[i].ssid))
216 goto fail;
217 }
218 nla_nest_end(msg, ssids);
219
220 /*
221 * If allowed, scan for 6 GHz APs that are reported by other
222 * APs. Note that if the flag is not set and 6 GHz channels are
223 * to be scanned, it is highly likely that non-PSC channels
224 * would be scanned passively (due to the Probe Request frame
225 * transmission restrictions mandated in IEEE Std 802.11ax-2021,
226 * 26.17.2.3 (Scanning in the 6 GHz band). Passive scanning of
227 * all non-PSC channels would take a significant amount of time.
228 */
229 if (!params->non_coloc_6ghz) {
230 wpa_printf(MSG_DEBUG,
231 "nl80211: Scan co-located APs on 6 GHz");
232 scan_flags |= NL80211_SCAN_FLAG_COLOCATED_6GHZ;
233 }
234 } else {
235 wpa_printf(MSG_DEBUG, "nl80211: Passive scan requested");
236 }
237
238 if (params->extra_ies) {
239 wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs",
240 params->extra_ies, params->extra_ies_len);
241 if (nla_put(msg, NL80211_ATTR_IE, params->extra_ies_len,
242 params->extra_ies))
243 goto fail;
244 }
245
246 if (params->freqs) {
247 struct nlattr *freqs;
248 freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
249 if (freqs == NULL)
250 goto fail;
251 for (i = 0; params->freqs[i]; i++) {
252 wpa_printf(MSG_MSGDUMP, "nl80211: Scan frequency %u "
253 "MHz", params->freqs[i]);
254 if (nla_put_u32(msg, i + 1, params->freqs[i]))
255 goto fail;
256 }
257 nla_nest_end(msg, freqs);
258 }
259
260 os_free(drv->filter_ssids);
261 drv->filter_ssids = params->filter_ssids;
262 params->filter_ssids = NULL;
263 drv->num_filter_ssids = params->num_filter_ssids;
264
265 if (!drv->hostapd && is_ap_interface(drv->nlmode)) {
266 wpa_printf(MSG_DEBUG, "nl80211: Add NL80211_SCAN_FLAG_AP");
267 scan_flags |= NL80211_SCAN_FLAG_AP;
268 }
269
270 if (params->only_new_results) {
271 wpa_printf(MSG_DEBUG, "nl80211: Add NL80211_SCAN_FLAG_FLUSH");
272 scan_flags |= NL80211_SCAN_FLAG_FLUSH;
273 }
274
275 if (params->low_priority && drv->have_low_prio_scan) {
276 wpa_printf(MSG_DEBUG,
277 "nl80211: Add NL80211_SCAN_FLAG_LOW_PRIORITY");
278 scan_flags |= NL80211_SCAN_FLAG_LOW_PRIORITY;
279 }
280
281 if (params->mac_addr_rand) {
282 wpa_printf(MSG_DEBUG,
283 "nl80211: Add NL80211_SCAN_FLAG_RANDOM_ADDR");
284 scan_flags |= NL80211_SCAN_FLAG_RANDOM_ADDR;
285
286 if (params->mac_addr) {
287 wpa_printf(MSG_DEBUG, "nl80211: MAC address: " MACSTR,
288 MAC2STR(params->mac_addr));
289 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
290 params->mac_addr))
291 goto fail;
292 }
293
294 if (params->mac_addr_mask) {
295 wpa_printf(MSG_DEBUG, "nl80211: MAC address mask: "
296 MACSTR, MAC2STR(params->mac_addr_mask));
297 if (nla_put(msg, NL80211_ATTR_MAC_MASK, ETH_ALEN,
298 params->mac_addr_mask))
299 goto fail;
300 }
301 }
302
303 if (params->duration) {
304 if (!(drv->capa.rrm_flags &
305 WPA_DRIVER_FLAGS_SUPPORT_SET_SCAN_DWELL) ||
306 nla_put_u16(msg, NL80211_ATTR_MEASUREMENT_DURATION,
307 params->duration))
308 goto fail;
309
310 if (params->duration_mandatory &&
311 nla_put_flag(msg,
312 NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY))
313 goto fail;
314 }
315
316 if (params->oce_scan) {
317 wpa_printf(MSG_DEBUG,
318 "nl80211: Add NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME");
319 wpa_printf(MSG_DEBUG,
320 "nl80211: Add NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP");
321 wpa_printf(MSG_DEBUG,
322 "nl80211: Add NL80211_SCAN_FLAG_OCE_PROBE_REQ_MIN_TX_RATE");
323 wpa_printf(MSG_DEBUG,
324 "nl80211: Add NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION");
325 scan_flags |= NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME |
326 NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP |
327 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE |
328 NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION;
329 }
330
331 if (params->min_probe_req_content) {
332 if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_SCAN_MIN_PREQ)
333 scan_flags |= NL80211_SCAN_FLAG_MIN_PREQ_CONTENT;
334 else
335 wpa_printf(MSG_DEBUG,
336 "nl80211: NL80211_SCAN_FLAG_MIN_PREQ_CONTENT not supported");
337 }
338
339 if (scan_flags &&
340 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, scan_flags))
341 goto fail;
342
343 return msg;
344
345 fail:
346 nlmsg_free(msg);
347 return NULL;
348 }
349
350
351 /**
352 * wpa_driver_nl80211_scan - Request the driver to initiate scan
353 * @bss: Pointer to private driver data from wpa_driver_nl80211_init()
354 * @params: Scan parameters
355 * Returns: 0 on success, -1 on failure
356 */
wpa_driver_nl80211_scan(struct i802_bss * bss,struct wpa_driver_scan_params * params)357 int wpa_driver_nl80211_scan(struct i802_bss *bss,
358 struct wpa_driver_scan_params *params)
359 {
360 struct wpa_driver_nl80211_data *drv = bss->drv;
361 int ret = -1, timeout;
362 struct nl_msg *msg = NULL;
363
364 wpa_dbg(bss->ctx, MSG_DEBUG, "nl80211: scan request");
365 drv->scan_for_auth = 0;
366
367 if (TEST_FAIL())
368 return -1;
369
370 msg = nl80211_scan_common(bss, NL80211_CMD_TRIGGER_SCAN, params);
371 if (!msg)
372 return -1;
373
374 if (params->p2p_probe) {
375 struct nlattr *rates;
376
377 wpa_printf(MSG_DEBUG, "nl80211: P2P probe - mask SuppRates");
378
379 rates = nla_nest_start(msg, NL80211_ATTR_SCAN_SUPP_RATES);
380 if (rates == NULL)
381 goto fail;
382
383 /*
384 * Remove 2.4 GHz rates 1, 2, 5.5, 11 Mbps from supported rates
385 * by masking out everything else apart from the OFDM rates 6,
386 * 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS rates. All 5 GHz
387 * rates are left enabled.
388 */
389 if (nla_put(msg, NL80211_BAND_2GHZ, 8,
390 "\x0c\x12\x18\x24\x30\x48\x60\x6c"))
391 goto fail;
392 nla_nest_end(msg, rates);
393
394 if (nla_put_flag(msg, NL80211_ATTR_TX_NO_CCK_RATE))
395 goto fail;
396 }
397
398 if (params->bssid) {
399 wpa_printf(MSG_DEBUG, "nl80211: Scan for a specific BSSID: "
400 MACSTR, MAC2STR(params->bssid));
401 if (nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid))
402 goto fail;
403 /* NL80211_ATTR_MAC was used for this purpose initially and the
404 * NL80211_ATTR_BSSID was added in 2016 when MAC address
405 * randomization was added. For compatibility with older kernel
406 * versions, add the NL80211_ATTR_MAC attribute as well when
407 * the conflicting functionality is not in use. */
408 if (!params->mac_addr_rand &&
409 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid))
410 goto fail;
411 }
412
413 ret = send_and_recv_cmd(drv, msg);
414 msg = NULL;
415 if (ret) {
416 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
417 "(%s)", ret, strerror(-ret));
418 if (drv->hostapd && is_ap_interface(drv->nlmode)) {
419 #ifdef CONFIG_IEEE80211BE
420 /* For multi link BSS, retry scan if any other links
421 * are busy scanning. */
422 if (ret == -EBUSY &&
423 nl80211_link_valid(bss->valid_links,
424 params->link_id)) {
425 struct i802_bss *link_bss;
426 u8 link_id;
427
428 wpa_printf(MSG_DEBUG,
429 "nl80211: Scan trigger on multi link BSS failed (requested link=%d on interface %s)",
430 params->link_id, bss->ifname);
431
432 for (link_bss = drv->first_bss; link_bss;
433 link_bss = link_bss->next) {
434 if (link_bss->scan_link)
435 break;
436 }
437
438 if (!link_bss) {
439 wpa_printf(MSG_DEBUG,
440 "nl80211: BSS information already running scan not available");
441 goto fail;
442 }
443
444 link_id = nl80211_get_link_id_from_link(
445 link_bss, link_bss->scan_link);
446 wpa_printf(MSG_DEBUG,
447 "nl80211: Scan already running on interface %s link %d",
448 link_bss->ifname, link_id);
449 goto fail;
450 }
451 #endif /* CONFIG_IEEE80211BE */
452
453 /*
454 * mac80211 does not allow scan requests in AP mode, so
455 * try to do this in station mode.
456 */
457 drv->ap_scan_as_station = drv->nlmode;
458 if (wpa_driver_nl80211_set_mode(
459 bss, NL80211_IFTYPE_STATION) ||
460 wpa_driver_nl80211_scan(bss, params)) {
461 nl80211_restore_ap_mode(bss);
462 goto fail;
463 }
464
465 ret = 0;
466 } else
467 goto fail;
468 }
469
470 drv->scan_state = SCAN_REQUESTED;
471 /* Not all drivers generate "scan completed" wireless event, so try to
472 * read results after a timeout. */
473 timeout = drv->uses_6ghz ? 20 : 10;
474 if (drv->uses_s1g)
475 timeout += 5;
476 if (drv->scan_complete_events) {
477 /*
478 * The driver seems to deliver events to notify when scan is
479 * complete, so use longer timeout to avoid race conditions
480 * with scanning and following association request.
481 */
482 timeout = 30;
483 }
484 wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
485 "seconds", ret, timeout);
486 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, bss->ctx);
487 eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,
488 drv, bss->ctx);
489 drv->last_scan_cmd = NL80211_CMD_TRIGGER_SCAN;
490
491 bss->scan_link = bss->flink;
492 if (is_ap_interface(drv->nlmode) &&
493 nl80211_link_valid(bss->valid_links, params->link_id)) {
494 wpa_dbg(bss->ctx, MSG_DEBUG,
495 "nl80211: Scan requested for link %d",
496 params->link_id);
497 bss->scan_link = nl80211_get_link(bss, params->link_id);
498 }
499
500 fail:
501 nlmsg_free(msg);
502 return ret;
503 }
504
505
506 static int
nl80211_sched_scan_add_scan_plans(struct wpa_driver_nl80211_data * drv,struct nl_msg * msg,struct wpa_driver_scan_params * params)507 nl80211_sched_scan_add_scan_plans(struct wpa_driver_nl80211_data *drv,
508 struct nl_msg *msg,
509 struct wpa_driver_scan_params *params)
510 {
511 struct nlattr *plans;
512 struct sched_scan_plan *scan_plans = params->sched_scan_plans;
513 unsigned int i;
514
515 plans = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
516 if (!plans)
517 return -1;
518
519 for (i = 0; i < params->sched_scan_plans_num; i++) {
520 struct nlattr *plan = nla_nest_start(msg, i + 1);
521
522 if (!plan)
523 return -1;
524
525 if (!scan_plans[i].interval ||
526 scan_plans[i].interval >
527 drv->capa.max_sched_scan_plan_interval) {
528 wpa_printf(MSG_DEBUG,
529 "nl80211: sched scan plan no. %u: Invalid interval: %u",
530 i, scan_plans[i].interval);
531 return -1;
532 }
533
534 if (nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL,
535 scan_plans[i].interval))
536 return -1;
537
538 if (scan_plans[i].iterations >
539 drv->capa.max_sched_scan_plan_iterations) {
540 wpa_printf(MSG_DEBUG,
541 "nl80211: sched scan plan no. %u: Invalid number of iterations: %u",
542 i, scan_plans[i].iterations);
543 return -1;
544 }
545
546 if (scan_plans[i].iterations &&
547 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS,
548 scan_plans[i].iterations))
549 return -1;
550
551 nla_nest_end(msg, plan);
552
553 /*
554 * All the scan plans must specify the number of iterations
555 * except the last plan, which will run infinitely. So if the
556 * number of iterations is not specified, this ought to be the
557 * last scan plan.
558 */
559 if (!scan_plans[i].iterations)
560 break;
561 }
562
563 if (i != params->sched_scan_plans_num - 1) {
564 wpa_printf(MSG_DEBUG,
565 "nl80211: All sched scan plans but the last must specify number of iterations");
566 return -1;
567 }
568
569 nla_nest_end(msg, plans);
570 return 0;
571 }
572
573
574 /**
575 * wpa_driver_nl80211_sched_scan - Initiate a scheduled scan
576 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
577 * @params: Scan parameters
578 * Returns: 0 on success, -1 on failure or if not supported
579 */
wpa_driver_nl80211_sched_scan(void * priv,struct wpa_driver_scan_params * params)580 int wpa_driver_nl80211_sched_scan(void *priv,
581 struct wpa_driver_scan_params *params)
582 {
583 struct i802_bss *bss = priv;
584 struct wpa_driver_nl80211_data *drv = bss->drv;
585 int ret = -1;
586 struct nl_msg *msg;
587 size_t i;
588
589 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: sched_scan request");
590
591 #ifdef ANDROID
592 if (!drv->capa.sched_scan_supported)
593 return android_pno_start(bss, params);
594 #endif /* ANDROID */
595
596 if (!params->sched_scan_plans_num ||
597 params->sched_scan_plans_num > drv->capa.max_sched_scan_plans) {
598 wpa_printf(MSG_ERROR,
599 "nl80211: Invalid number of sched scan plans: %u",
600 params->sched_scan_plans_num);
601 return -1;
602 }
603
604 msg = nl80211_scan_common(bss, NL80211_CMD_START_SCHED_SCAN, params);
605 if (!msg)
606 goto fail;
607
608 if (drv->capa.max_sched_scan_plan_iterations) {
609 if (nl80211_sched_scan_add_scan_plans(drv, msg, params))
610 goto fail;
611 } else {
612 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL,
613 params->sched_scan_plans[0].interval * 1000))
614 goto fail;
615 }
616
617 if ((drv->num_filter_ssids &&
618 (int) drv->num_filter_ssids <= drv->capa.max_match_sets) ||
619 params->filter_rssi) {
620 struct nlattr *match_sets;
621 match_sets = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
622 if (match_sets == NULL)
623 goto fail;
624
625 for (i = 0; i < drv->num_filter_ssids; i++) {
626 struct nlattr *match_set_ssid;
627 wpa_printf(MSG_MSGDUMP,
628 "nl80211: Sched scan filter SSID %s",
629 wpa_ssid_txt(drv->filter_ssids[i].ssid,
630 drv->filter_ssids[i].ssid_len));
631
632 match_set_ssid = nla_nest_start(msg, i + 1);
633 if (match_set_ssid == NULL ||
634 nla_put(msg, NL80211_ATTR_SCHED_SCAN_MATCH_SSID,
635 drv->filter_ssids[i].ssid_len,
636 drv->filter_ssids[i].ssid) ||
637 (params->filter_rssi &&
638 nla_put_u32(msg,
639 NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
640 params->filter_rssi)))
641 goto fail;
642
643 nla_nest_end(msg, match_set_ssid);
644 }
645
646 /*
647 * Due to backward compatibility code, newer kernels treat this
648 * matchset (with only an RSSI filter) as the default for all
649 * other matchsets, unless it's the only one, in which case the
650 * matchset will actually allow all SSIDs above the RSSI.
651 */
652 if (params->filter_rssi) {
653 struct nlattr *match_set_rssi;
654 match_set_rssi = nla_nest_start(msg, 0);
655 if (match_set_rssi == NULL ||
656 nla_put_u32(msg, NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
657 params->filter_rssi))
658 goto fail;
659 wpa_printf(MSG_MSGDUMP,
660 "nl80211: Sched scan RSSI filter %d dBm",
661 params->filter_rssi);
662 nla_nest_end(msg, match_set_rssi);
663 }
664
665 nla_nest_end(msg, match_sets);
666 }
667
668 if (params->relative_rssi_set) {
669 struct nl80211_bss_select_rssi_adjust rssi_adjust;
670
671 os_memset(&rssi_adjust, 0, sizeof(rssi_adjust));
672 wpa_printf(MSG_DEBUG, "nl80211: Relative RSSI: %d",
673 params->relative_rssi);
674 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
675 params->relative_rssi))
676 goto fail;
677
678 if (params->relative_adjust_rssi) {
679 int pref_band_set = 1;
680
681 switch (params->relative_adjust_band) {
682 case WPA_SETBAND_5G:
683 rssi_adjust.band = NL80211_BAND_5GHZ;
684 break;
685 case WPA_SETBAND_2G:
686 rssi_adjust.band = NL80211_BAND_2GHZ;
687 break;
688 default:
689 pref_band_set = 0;
690 break;
691 }
692 rssi_adjust.delta = params->relative_adjust_rssi;
693
694 if (pref_band_set &&
695 nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
696 sizeof(rssi_adjust), &rssi_adjust))
697 goto fail;
698 }
699 }
700
701 if (params->sched_scan_start_delay &&
702 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY,
703 params->sched_scan_start_delay))
704 goto fail;
705
706 ret = send_and_recv_cmd(drv, msg);
707
708 /* TODO: if we get an error here, we should fall back to normal scan */
709
710 msg = NULL;
711 if (ret) {
712 wpa_printf(MSG_DEBUG, "nl80211: Sched scan start failed: "
713 "ret=%d (%s)", ret, strerror(-ret));
714 goto fail;
715 }
716
717 wpa_printf(MSG_DEBUG, "nl80211: Sched scan requested (ret=%d)", ret);
718
719 fail:
720 nlmsg_free(msg);
721 return ret;
722 }
723
724
725 /**
726 * wpa_driver_nl80211_stop_sched_scan - Stop a scheduled scan
727 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
728 * Returns: 0 on success, -1 on failure or if not supported
729 */
wpa_driver_nl80211_stop_sched_scan(void * priv)730 int wpa_driver_nl80211_stop_sched_scan(void *priv)
731 {
732 struct i802_bss *bss = priv;
733 struct wpa_driver_nl80211_data *drv = bss->drv;
734 int ret;
735 struct nl_msg *msg;
736
737 #ifdef ANDROID
738 if (!drv->capa.sched_scan_supported)
739 return android_pno_stop(bss);
740 #endif /* ANDROID */
741
742 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_STOP_SCHED_SCAN);
743 ret = send_and_recv_cmd(drv, msg);
744 if (ret) {
745 wpa_printf(MSG_DEBUG,
746 "nl80211: Sched scan stop failed: ret=%d (%s)",
747 ret, strerror(-ret));
748 } else {
749 wpa_printf(MSG_DEBUG,
750 "nl80211: Sched scan stop sent");
751 }
752
753 return ret;
754 }
755
756
nl80211_scan_filtered(struct wpa_driver_nl80211_data * drv,const u8 * ie,size_t ie_len)757 static int nl80211_scan_filtered(struct wpa_driver_nl80211_data *drv,
758 const u8 *ie, size_t ie_len)
759 {
760 const u8 *ssid;
761 size_t i;
762
763 if (drv->filter_ssids == NULL)
764 return 0;
765
766 ssid = get_ie(ie, ie_len, WLAN_EID_SSID);
767 if (ssid == NULL)
768 return 1;
769
770 for (i = 0; i < drv->num_filter_ssids; i++) {
771 if (ssid[1] == drv->filter_ssids[i].ssid_len &&
772 os_memcmp(ssid + 2, drv->filter_ssids[i].ssid, ssid[1]) ==
773 0)
774 return 0;
775 }
776
777 return 1;
778 }
779
780
781 static struct wpa_scan_res *
nl80211_parse_bss_info(struct wpa_driver_nl80211_data * drv,struct nl_msg * msg,const u8 * bssid)782 nl80211_parse_bss_info(struct wpa_driver_nl80211_data *drv,
783 struct nl_msg *msg, const u8 *bssid)
784 {
785 struct nlattr *tb[NL80211_ATTR_MAX + 1];
786 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
787 struct nlattr *bss[NL80211_BSS_MAX + 1];
788 static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
789 [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
790 [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
791 [NL80211_BSS_TSF] = { .type = NLA_U64 },
792 [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
793 [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
794 [NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
795 [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
796 [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
797 [NL80211_BSS_STATUS] = { .type = NLA_U32 },
798 [NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
799 [NL80211_BSS_BEACON_IES] = { .type = NLA_UNSPEC },
800 [NL80211_BSS_BEACON_TSF] = { .type = NLA_U64 },
801 [NL80211_BSS_PARENT_TSF] = { .type = NLA_U64 },
802 [NL80211_BSS_PARENT_BSSID] = { .type = NLA_UNSPEC },
803 [NL80211_BSS_LAST_SEEN_BOOTTIME] = { .type = NLA_U64 },
804 };
805 struct wpa_scan_res *r;
806 const u8 *ie, *beacon_ie;
807 size_t ie_len, beacon_ie_len;
808 u8 *pos;
809
810 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
811 genlmsg_attrlen(gnlh, 0), NULL);
812 if (!tb[NL80211_ATTR_BSS])
813 return NULL;
814 if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
815 bss_policy))
816 return NULL;
817 if (bssid && bss[NL80211_BSS_BSSID] &&
818 !ether_addr_equal(bssid, nla_data(bss[NL80211_BSS_BSSID])))
819 return NULL;
820 if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
821 ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
822 ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
823 } else {
824 ie = NULL;
825 ie_len = 0;
826 }
827 if (bss[NL80211_BSS_BEACON_IES]) {
828 beacon_ie = nla_data(bss[NL80211_BSS_BEACON_IES]);
829 beacon_ie_len = nla_len(bss[NL80211_BSS_BEACON_IES]);
830 } else {
831 beacon_ie = NULL;
832 beacon_ie_len = 0;
833 }
834
835 if (nl80211_scan_filtered(drv, ie ? ie : beacon_ie,
836 ie ? ie_len : beacon_ie_len))
837 return NULL;
838
839 r = os_zalloc(sizeof(*r) + ie_len + beacon_ie_len);
840 if (r == NULL)
841 return NULL;
842 if (bss[NL80211_BSS_BSSID])
843 os_memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),
844 ETH_ALEN);
845 if (bss[NL80211_BSS_FREQUENCY])
846 r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
847 if (bss[NL80211_BSS_BEACON_INTERVAL])
848 r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]);
849 if (bss[NL80211_BSS_CAPABILITY])
850 r->caps = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
851 r->flags |= WPA_SCAN_NOISE_INVALID;
852 if (bss[NL80211_BSS_SIGNAL_MBM]) {
853 r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
854 r->level /= 100; /* mBm to dBm */
855 r->flags |= WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID;
856 } else if (bss[NL80211_BSS_SIGNAL_UNSPEC]) {
857 r->level = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);
858 r->flags |= WPA_SCAN_QUAL_INVALID;
859 } else
860 r->flags |= WPA_SCAN_LEVEL_INVALID | WPA_SCAN_QUAL_INVALID;
861 if (bss[NL80211_BSS_TSF])
862 r->tsf = nla_get_u64(bss[NL80211_BSS_TSF]);
863 if (bss[NL80211_BSS_BEACON_TSF]) {
864 u64 tsf = nla_get_u64(bss[NL80211_BSS_BEACON_TSF]);
865 if (tsf > r->tsf) {
866 r->tsf = tsf;
867 r->beacon_newer = true;
868 }
869 }
870 if (bss[NL80211_BSS_SEEN_MS_AGO])
871 r->age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]);
872 if (bss[NL80211_BSS_LAST_SEEN_BOOTTIME]) {
873 u64 boottime;
874 struct timespec ts;
875
876 #ifndef CLOCK_BOOTTIME
877 #define CLOCK_BOOTTIME 7
878 #endif
879 if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0) {
880 /* Use more accurate boottime information to update the
881 * scan result age since the driver reports this and
882 * CLOCK_BOOTTIME is available. */
883 boottime = nla_get_u64(
884 bss[NL80211_BSS_LAST_SEEN_BOOTTIME]);
885 r->age = ((u64) ts.tv_sec * 1000000000 +
886 ts.tv_nsec - boottime) / 1000000;
887 }
888 }
889 r->ie_len = ie_len;
890 pos = (u8 *) (r + 1);
891 if (ie) {
892 os_memcpy(pos, ie, ie_len);
893 pos += ie_len;
894 }
895 r->beacon_ie_len = beacon_ie_len;
896 if (beacon_ie)
897 os_memcpy(pos, beacon_ie, beacon_ie_len);
898
899 if (bss[NL80211_BSS_STATUS]) {
900 enum nl80211_bss_status status;
901 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
902 switch (status) {
903 case NL80211_BSS_STATUS_ASSOCIATED:
904 r->flags |= WPA_SCAN_ASSOCIATED;
905 break;
906 default:
907 break;
908 }
909 }
910
911 if (bss[NL80211_BSS_PARENT_TSF] && bss[NL80211_BSS_PARENT_BSSID]) {
912 r->parent_tsf = nla_get_u64(bss[NL80211_BSS_PARENT_TSF]);
913 os_memcpy(r->tsf_bssid, nla_data(bss[NL80211_BSS_PARENT_BSSID]),
914 ETH_ALEN);
915 }
916
917 return r;
918 }
919
920
921 struct nl80211_bss_info_arg {
922 struct wpa_driver_nl80211_data *drv;
923 struct wpa_scan_results *res;
924 const u8 *bssid;
925 };
926
bss_info_handler(struct nl_msg * msg,void * arg)927 static int bss_info_handler(struct nl_msg *msg, void *arg)
928 {
929 struct nl80211_bss_info_arg *_arg = arg;
930 struct wpa_scan_results *res = _arg->res;
931 struct wpa_scan_res **tmp;
932 struct wpa_scan_res *r;
933
934 r = nl80211_parse_bss_info(_arg->drv, msg, _arg->bssid);
935 if (!r)
936 return NL_SKIP;
937
938 if (!res) {
939 os_free(r);
940 return NL_SKIP;
941 }
942 tmp = os_realloc_array(res->res, res->num + 1,
943 sizeof(struct wpa_scan_res *));
944 if (tmp == NULL) {
945 os_free(r);
946 return NL_SKIP;
947 }
948 tmp[res->num++] = r;
949 res->res = tmp;
950
951 return NL_SKIP;
952 }
953
954
clear_state_mismatch(struct wpa_driver_nl80211_data * drv,const u8 * addr)955 static void clear_state_mismatch(struct wpa_driver_nl80211_data *drv,
956 const u8 *addr)
957 {
958 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
959 wpa_printf(MSG_DEBUG, "nl80211: Clear possible state "
960 "mismatch (" MACSTR ")", MAC2STR(addr));
961 wpa_driver_nl80211_mlme(drv, addr,
962 NL80211_CMD_DEAUTHENTICATE,
963 WLAN_REASON_PREV_AUTH_NOT_VALID, 1,
964 drv->first_bss);
965 }
966 }
967
968
nl80211_check_bss_status(struct wpa_driver_nl80211_data * drv,struct wpa_scan_res * r)969 static void nl80211_check_bss_status(struct wpa_driver_nl80211_data *drv,
970 struct wpa_scan_res *r)
971 {
972 if (!(r->flags & WPA_SCAN_ASSOCIATED))
973 return;
974
975 wpa_printf(MSG_DEBUG, "nl80211: Scan results indicate BSS status with "
976 MACSTR " as associated", MAC2STR(r->bssid));
977 if (is_sta_interface(drv->nlmode) && !drv->associated) {
978 wpa_printf(MSG_DEBUG,
979 "nl80211: Local state (not associated) does not match with BSS state");
980 clear_state_mismatch(drv, r->bssid);
981 } else if (is_sta_interface(drv->nlmode) &&
982 !ether_addr_equal(drv->bssid, r->bssid)) {
983 wpa_printf(MSG_DEBUG,
984 "nl80211: Local state (associated with " MACSTR
985 ") does not match with BSS state",
986 MAC2STR(drv->bssid));
987
988 if (!ether_addr_equal(drv->sta_mlo_info.ap_mld_addr,
989 drv->bssid)) {
990 clear_state_mismatch(drv, r->bssid);
991
992 if (!is_zero_ether_addr(drv->sta_mlo_info.ap_mld_addr))
993 clear_state_mismatch(
994 drv, drv->sta_mlo_info.ap_mld_addr);
995 else
996 clear_state_mismatch(drv, drv->bssid);
997
998 } else {
999 wpa_printf(MSG_DEBUG,
1000 "nl80211: BSSID is the MLD address");
1001 }
1002 }
1003 }
1004
1005
wpa_driver_nl80211_check_bss_status(struct wpa_driver_nl80211_data * drv,struct wpa_scan_results * res)1006 static void wpa_driver_nl80211_check_bss_status(
1007 struct wpa_driver_nl80211_data *drv, struct wpa_scan_results *res)
1008 {
1009 size_t i;
1010
1011 for (i = 0; i < res->num; i++)
1012 nl80211_check_bss_status(drv, res->res[i]);
1013 }
1014
1015
nl80211_update_scan_res_noise(struct wpa_scan_res * res,struct nl80211_noise_info * info)1016 static void nl80211_update_scan_res_noise(struct wpa_scan_res *res,
1017 struct nl80211_noise_info *info)
1018 {
1019 unsigned int i;
1020
1021 for (i = 0; res && i < info->count; i++) {
1022 if ((int) info->freq[i] != res->freq ||
1023 !(res->flags & WPA_SCAN_NOISE_INVALID))
1024 continue;
1025 res->noise = info->noise[i];
1026 res->flags &= ~WPA_SCAN_NOISE_INVALID;
1027 }
1028 }
1029
1030
1031 static struct wpa_scan_results *
nl80211_get_scan_results(struct wpa_driver_nl80211_data * drv,const u8 * bssid)1032 nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv, const u8 *bssid)
1033 {
1034 struct nl_msg *msg;
1035 struct wpa_scan_results *res;
1036 int ret;
1037 struct nl80211_bss_info_arg arg;
1038 int count = 0;
1039
1040 try_again:
1041 res = os_zalloc(sizeof(*res));
1042 if (res == NULL)
1043 return NULL;
1044 if (!(msg = nl80211_cmd_msg(drv->first_bss, NLM_F_DUMP,
1045 NL80211_CMD_GET_SCAN))) {
1046 wpa_scan_results_free(res);
1047 return NULL;
1048 }
1049
1050 arg.drv = drv;
1051 arg.res = res;
1052 arg.bssid = bssid;
1053 ret = send_and_recv_resp(drv, msg, bss_info_handler, &arg);
1054 if (ret == -EAGAIN) {
1055 count++;
1056 if (count >= 10) {
1057 wpa_printf(MSG_INFO,
1058 "nl80211: Failed to receive consistent scan result dump");
1059 } else {
1060 wpa_printf(MSG_DEBUG,
1061 "nl80211: Failed to receive consistent scan result dump - try again");
1062 wpa_scan_results_free(res);
1063 goto try_again;
1064 }
1065 }
1066 if (ret == 0) {
1067 struct nl80211_noise_info info;
1068
1069 wpa_printf(MSG_DEBUG, "nl80211: Received scan results (%lu "
1070 "BSSes)", (unsigned long) res->num);
1071 if (nl80211_get_noise_for_scan_results(drv, &info) == 0) {
1072 size_t i;
1073
1074 for (i = 0; i < res->num; ++i)
1075 nl80211_update_scan_res_noise(res->res[i],
1076 &info);
1077 }
1078 return res;
1079 }
1080 wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
1081 "(%s)", ret, strerror(-ret));
1082 wpa_scan_results_free(res);
1083 return NULL;
1084 }
1085
1086
1087 /**
1088 * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results
1089 * @priv: Pointer to private nl80211 data from wpa_driver_nl80211_init()
1090 * @bssid: Return results only for the specified BSSID, %NULL for all
1091 * Returns: Scan results on success, -1 on failure
1092 */
wpa_driver_nl80211_get_scan_results(void * priv,const u8 * bssid)1093 struct wpa_scan_results * wpa_driver_nl80211_get_scan_results(void *priv,
1094 const u8 *bssid)
1095 {
1096 struct i802_bss *bss = priv;
1097 struct wpa_driver_nl80211_data *drv = bss->drv;
1098 struct wpa_scan_results *res;
1099
1100 res = nl80211_get_scan_results(drv, bssid);
1101 if (res)
1102 wpa_driver_nl80211_check_bss_status(drv, res);
1103 return res;
1104 }
1105
1106
1107 struct nl80211_dump_scan_ctx {
1108 struct wpa_driver_nl80211_data *drv;
1109 int idx;
1110 };
1111
nl80211_dump_scan_handler(struct nl_msg * msg,void * arg)1112 static int nl80211_dump_scan_handler(struct nl_msg *msg, void *arg)
1113 {
1114 struct nl80211_dump_scan_ctx *ctx = arg;
1115 struct wpa_scan_res *r;
1116
1117 r = nl80211_parse_bss_info(ctx->drv, msg, NULL);
1118 if (!r)
1119 return NL_SKIP;
1120 wpa_printf(MSG_DEBUG, "nl80211: %d " MACSTR " %d%s",
1121 ctx->idx, MAC2STR(r->bssid), r->freq,
1122 r->flags & WPA_SCAN_ASSOCIATED ? " [assoc]" : "");
1123 ctx->idx++;
1124 os_free(r);
1125 return NL_SKIP;
1126 }
1127
1128
nl80211_dump_scan(struct wpa_driver_nl80211_data * drv)1129 void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv)
1130 {
1131 struct nl_msg *msg;
1132 struct nl80211_dump_scan_ctx ctx;
1133
1134 wpa_printf(MSG_DEBUG, "nl80211: Scan result dump");
1135 ctx.drv = drv;
1136 ctx.idx = 0;
1137 msg = nl80211_cmd_msg(drv->first_bss, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
1138 if (msg)
1139 send_and_recv_resp(drv, msg, nl80211_dump_scan_handler, &ctx);
1140 }
1141
1142
wpa_driver_nl80211_abort_scan(void * priv,u64 scan_cookie)1143 int wpa_driver_nl80211_abort_scan(void *priv, u64 scan_cookie)
1144 {
1145 struct i802_bss *bss = priv;
1146 #ifdef CONFIG_DRIVER_NL80211_QCA
1147 struct wpa_driver_nl80211_data *drv = bss->drv;
1148
1149 /*
1150 * If scan_cookie is zero, a normal scan through kernel (cfg80211)
1151 * was triggered, hence abort the cfg80211 scan instead of the vendor
1152 * scan.
1153 */
1154 if (drv->scan_vendor_cmd_avail && scan_cookie)
1155 return nl80211_abort_vendor_scan(drv, scan_cookie);
1156 #endif /* CONFIG_DRIVER_NL80211_QCA */
1157 return nl80211_abort_scan(bss);
1158 }
1159
1160
1161 #ifdef CONFIG_DRIVER_NL80211_QCA
1162
scan_cookie_handler(struct nl_msg * msg,void * arg)1163 static int scan_cookie_handler(struct nl_msg *msg, void *arg)
1164 {
1165 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1166 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1167 u64 *cookie = arg;
1168
1169 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1170 genlmsg_attrlen(gnlh, 0), NULL);
1171
1172 if (tb[NL80211_ATTR_VENDOR_DATA]) {
1173 struct nlattr *nl_vendor = tb[NL80211_ATTR_VENDOR_DATA];
1174 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
1175
1176 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
1177 nla_data(nl_vendor), nla_len(nl_vendor), NULL);
1178
1179 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE])
1180 *cookie = nla_get_u64(
1181 tb_vendor[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
1182 }
1183
1184 return NL_SKIP;
1185 }
1186
1187
1188 /**
1189 * wpa_driver_nl80211_vendor_scan - Request the driver to initiate a vendor scan
1190 * @bss: Pointer to private driver data from wpa_driver_nl80211_init()
1191 * @params: Scan parameters
1192 * Returns: 0 on success, -1 on failure
1193 */
wpa_driver_nl80211_vendor_scan(struct i802_bss * bss,struct wpa_driver_scan_params * params)1194 int wpa_driver_nl80211_vendor_scan(struct i802_bss *bss,
1195 struct wpa_driver_scan_params *params)
1196 {
1197 struct wpa_driver_nl80211_data *drv = bss->drv;
1198 struct nl_msg *msg = NULL;
1199 struct nlattr *attr;
1200 size_t i;
1201 u32 scan_flags = 0;
1202 int ret = -1;
1203 u64 cookie = 0;
1204
1205 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: vendor scan request");
1206 drv->scan_for_auth = 0;
1207
1208 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
1209 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
1210 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
1211 QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN) )
1212 goto fail;
1213
1214 attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
1215 if (attr == NULL)
1216 goto fail;
1217
1218 if (params->num_ssids) {
1219 struct nlattr *ssids;
1220
1221 ssids = nla_nest_start(msg, QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS);
1222 if (ssids == NULL)
1223 goto fail;
1224 for (i = 0; i < params->num_ssids; i++) {
1225 wpa_printf(MSG_MSGDUMP, "nl80211: Scan SSID %s",
1226 wpa_ssid_txt(params->ssids[i].ssid,
1227 params->ssids[i].ssid_len));
1228 if (nla_put(msg, i + 1, params->ssids[i].ssid_len,
1229 params->ssids[i].ssid))
1230 goto fail;
1231 }
1232 nla_nest_end(msg, ssids);
1233 }
1234
1235 if (params->extra_ies) {
1236 wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs",
1237 params->extra_ies, params->extra_ies_len);
1238 if (nla_put(msg, QCA_WLAN_VENDOR_ATTR_SCAN_IE,
1239 params->extra_ies_len, params->extra_ies))
1240 goto fail;
1241 }
1242
1243 if (params->freqs) {
1244 struct nlattr *freqs;
1245
1246 freqs = nla_nest_start(msg,
1247 QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES);
1248 if (freqs == NULL)
1249 goto fail;
1250 for (i = 0; params->freqs[i]; i++) {
1251 wpa_printf(MSG_MSGDUMP,
1252 "nl80211: Scan frequency %u MHz",
1253 params->freqs[i]);
1254 if (nla_put_u32(msg, i + 1, params->freqs[i]))
1255 goto fail;
1256 }
1257 nla_nest_end(msg, freqs);
1258 }
1259
1260 os_free(drv->filter_ssids);
1261 drv->filter_ssids = params->filter_ssids;
1262 params->filter_ssids = NULL;
1263 drv->num_filter_ssids = params->num_filter_ssids;
1264
1265 if (params->low_priority && drv->have_low_prio_scan) {
1266 wpa_printf(MSG_DEBUG,
1267 "nl80211: Add NL80211_SCAN_FLAG_LOW_PRIORITY");
1268 scan_flags |= NL80211_SCAN_FLAG_LOW_PRIORITY;
1269 }
1270
1271 if (params->mac_addr_rand) {
1272 wpa_printf(MSG_DEBUG,
1273 "nl80211: Add NL80211_SCAN_FLAG_RANDOM_ADDR");
1274 scan_flags |= NL80211_SCAN_FLAG_RANDOM_ADDR;
1275
1276 if (params->mac_addr) {
1277 wpa_printf(MSG_DEBUG, "nl80211: MAC address: " MACSTR,
1278 MAC2STR(params->mac_addr));
1279 if (nla_put(msg, QCA_WLAN_VENDOR_ATTR_SCAN_MAC,
1280 ETH_ALEN, params->mac_addr))
1281 goto fail;
1282 }
1283
1284 if (params->mac_addr_mask) {
1285 wpa_printf(MSG_DEBUG, "nl80211: MAC address mask: "
1286 MACSTR, MAC2STR(params->mac_addr_mask));
1287 if (nla_put(msg, QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK,
1288 ETH_ALEN, params->mac_addr_mask))
1289 goto fail;
1290 }
1291 }
1292
1293 if (scan_flags &&
1294 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS, scan_flags))
1295 goto fail;
1296
1297 if (params->p2p_probe) {
1298 struct nlattr *rates;
1299
1300 wpa_printf(MSG_DEBUG, "nl80211: P2P probe - mask SuppRates");
1301
1302 rates = nla_nest_start(msg,
1303 QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES);
1304 if (rates == NULL)
1305 goto fail;
1306
1307 /*
1308 * Remove 2.4 GHz rates 1, 2, 5.5, 11 Mbps from supported rates
1309 * by masking out everything else apart from the OFDM rates 6,
1310 * 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS rates. All 5 GHz
1311 * rates are left enabled.
1312 */
1313 if (nla_put(msg, NL80211_BAND_2GHZ, 8,
1314 "\x0c\x12\x18\x24\x30\x48\x60\x6c"))
1315 goto fail;
1316 nla_nest_end(msg, rates);
1317
1318 if (nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE))
1319 goto fail;
1320 }
1321
1322 if (params->bssid) {
1323 wpa_printf(MSG_DEBUG, "nl80211: Scan for a specific BSSID: "
1324 MACSTR, MAC2STR(params->bssid));
1325 if (nla_put(msg, QCA_WLAN_VENDOR_ATTR_SCAN_BSSID, ETH_ALEN,
1326 params->bssid))
1327 goto fail;
1328 }
1329
1330 if (is_ap_interface(drv->nlmode) &&
1331 params->link_id != NL80211_DRV_LINK_ID_NA &&
1332 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_SCAN_LINK_ID, params->link_id))
1333 goto fail;
1334
1335 nla_nest_end(msg, attr);
1336
1337 ret = send_and_recv_resp(drv, msg, scan_cookie_handler, &cookie);
1338 msg = NULL;
1339 if (ret) {
1340 wpa_printf(MSG_DEBUG,
1341 "nl80211: Vendor scan trigger failed: ret=%d (%s)",
1342 ret, strerror(-ret));
1343 goto fail;
1344 }
1345
1346 drv->vendor_scan_cookie = cookie;
1347 drv->scan_state = SCAN_REQUESTED;
1348 /* Pass the cookie to the caller to help distinguish the scans. */
1349 params->scan_cookie = cookie;
1350
1351 wpa_printf(MSG_DEBUG,
1352 "nl80211: Vendor scan requested (ret=%d) - scan timeout 30 seconds, scan cookie:0x%llx",
1353 ret, (long long unsigned int) cookie);
1354 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, bss->ctx);
1355 eloop_register_timeout(30, 0, wpa_driver_nl80211_scan_timeout,
1356 drv, bss->ctx);
1357 drv->last_scan_cmd = NL80211_CMD_VENDOR;
1358
1359 fail:
1360 nlmsg_free(msg);
1361 return ret;
1362 }
1363
1364
1365 /**
1366 * nl80211_set_default_scan_ies - Set the scan default IEs to the driver
1367 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
1368 * @ies: Pointer to IEs buffer
1369 * @ies_len: Length of IEs in bytes
1370 * Returns: 0 on success, -1 on failure
1371 */
nl80211_set_default_scan_ies(void * priv,const u8 * ies,size_t ies_len)1372 int nl80211_set_default_scan_ies(void *priv, const u8 *ies, size_t ies_len)
1373 {
1374 struct i802_bss *bss = priv;
1375 struct wpa_driver_nl80211_data *drv = bss->drv;
1376 struct nl_msg *msg = NULL;
1377 struct nlattr *attr;
1378 int ret = -1;
1379
1380 if (!drv->set_wifi_conf_vendor_cmd_avail)
1381 return -1;
1382
1383 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
1384 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
1385 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
1386 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION))
1387 goto fail;
1388
1389 attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
1390 if (attr == NULL)
1391 goto fail;
1392
1393 wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan default IEs", ies, ies_len);
1394 if (nla_put(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES,
1395 ies_len, ies))
1396 goto fail;
1397
1398 nla_nest_end(msg, attr);
1399
1400 ret = send_and_recv_cmd(drv, msg);
1401 msg = NULL;
1402 if (ret) {
1403 wpa_printf(MSG_ERROR,
1404 "nl80211: Set scan default IEs failed: ret=%d (%s)",
1405 ret, strerror(-ret));
1406 goto fail;
1407 }
1408
1409 fail:
1410 nlmsg_free(msg);
1411 return ret;
1412 }
1413
1414 #endif /* CONFIG_DRIVER_NL80211_QCA */
1415