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