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