1 /* 2 * wpa_supplicant - Radio Measurements 3 * Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 11 #include "utils/common.h" 12 #include "utils/eloop.h" 13 #include "common/ieee802_11_common.h" 14 #include "wpa_supplicant_i.h" 15 #include "driver_i.h" 16 #include "bss.h" 17 #include "scan.h" 18 #include "p2p_supplicant.h" 19 20 21 static void wpas_rrm_neighbor_rep_timeout_handler(void *data, void *user_ctx) 22 { 23 struct rrm_data *rrm = data; 24 25 if (!rrm->notify_neighbor_rep) { 26 wpa_printf(MSG_ERROR, 27 "RRM: Unexpected neighbor report timeout"); 28 return; 29 } 30 31 wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report - NONE"); 32 rrm->notify_neighbor_rep(rrm->neighbor_rep_cb_ctx, NULL); 33 34 rrm->notify_neighbor_rep = NULL; 35 rrm->neighbor_rep_cb_ctx = NULL; 36 } 37 38 39 /* 40 * wpas_rrm_reset - Clear and reset all RRM data in wpa_supplicant 41 * @wpa_s: Pointer to wpa_supplicant 42 */ 43 void wpas_rrm_reset(struct wpa_supplicant *wpa_s) 44 { 45 wpa_s->rrm.rrm_used = 0; 46 47 eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm, 48 NULL); 49 if (wpa_s->rrm.notify_neighbor_rep) 50 wpas_rrm_neighbor_rep_timeout_handler(&wpa_s->rrm, NULL); 51 wpa_s->rrm.next_neighbor_rep_token = 1; 52 wpas_clear_beacon_rep_data(wpa_s); 53 } 54 55 56 /* 57 * wpas_rrm_process_neighbor_rep - Handle incoming neighbor report 58 * @wpa_s: Pointer to wpa_supplicant 59 * @report: Neighbor report buffer, prefixed by a 1-byte dialog token 60 * @report_len: Length of neighbor report buffer 61 */ 62 void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s, 63 const u8 *report, size_t report_len) 64 { 65 struct wpabuf *neighbor_rep; 66 67 wpa_hexdump(MSG_DEBUG, "RRM: New Neighbor Report", report, report_len); 68 if (report_len < 1) 69 return; 70 71 if (report[0] != wpa_s->rrm.next_neighbor_rep_token - 1) { 72 wpa_printf(MSG_DEBUG, 73 "RRM: Discarding neighbor report with token %d (expected %d)", 74 report[0], wpa_s->rrm.next_neighbor_rep_token - 1); 75 return; 76 } 77 78 eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm, 79 NULL); 80 81 if (!wpa_s->rrm.notify_neighbor_rep) { 82 wpa_msg(wpa_s, MSG_INFO, "RRM: Unexpected neighbor report"); 83 return; 84 } 85 86 /* skipping the first byte, which is only an id (dialog token) */ 87 neighbor_rep = wpabuf_alloc(report_len - 1); 88 if (!neighbor_rep) { 89 wpas_rrm_neighbor_rep_timeout_handler(&wpa_s->rrm, NULL); 90 return; 91 } 92 wpabuf_put_data(neighbor_rep, report + 1, report_len - 1); 93 wpa_dbg(wpa_s, MSG_DEBUG, "RRM: Notifying neighbor report (token = %d)", 94 report[0]); 95 wpa_s->rrm.notify_neighbor_rep(wpa_s->rrm.neighbor_rep_cb_ctx, 96 neighbor_rep); 97 wpa_s->rrm.notify_neighbor_rep = NULL; 98 wpa_s->rrm.neighbor_rep_cb_ctx = NULL; 99 } 100 101 102 #if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS) 103 /* Workaround different, undefined for Windows, error codes used here */ 104 #ifndef ENOTCONN 105 #define ENOTCONN -1 106 #endif 107 #ifndef EOPNOTSUPP 108 #define EOPNOTSUPP -1 109 #endif 110 #ifndef ECANCELED 111 #define ECANCELED -1 112 #endif 113 #endif 114 115 /* Measurement Request element + Location Subject + Maximum Age subelement */ 116 #define MEASURE_REQUEST_LCI_LEN (3 + 1 + 4) 117 /* Measurement Request element + Location Civic Request */ 118 #define MEASURE_REQUEST_CIVIC_LEN (3 + 5) 119 120 121 /** 122 * wpas_rrm_send_neighbor_rep_request - Request a neighbor report from our AP 123 * @wpa_s: Pointer to wpa_supplicant 124 * @ssid: if not null, this is sent in the request. Otherwise, no SSID IE 125 * is sent in the request. 126 * @lci: if set, neighbor request will include LCI request 127 * @civic: if set, neighbor request will include civic location request 128 * @cb: Callback function to be called once the requested report arrives, or 129 * timed out after RRM_NEIGHBOR_REPORT_TIMEOUT seconds. 130 * In the former case, 'neighbor_rep' is a newly allocated wpabuf, and it's 131 * the requester's responsibility to free it. 132 * In the latter case NULL will be sent in 'neighbor_rep'. 133 * @cb_ctx: Context value to send the callback function 134 * Returns: 0 in case of success, negative error code otherwise 135 * 136 * In case there is a previous request which has not been answered yet, the 137 * new request fails. The caller may retry after RRM_NEIGHBOR_REPORT_TIMEOUT. 138 * Request must contain a callback function. 139 */ 140 int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s, 141 const struct wpa_ssid_value *ssid, 142 int lci, int civic, 143 void (*cb)(void *ctx, 144 struct wpabuf *neighbor_rep), 145 void *cb_ctx) 146 { 147 struct wpabuf *buf; 148 const u8 *rrm_ie; 149 150 if (wpa_s->wpa_state != WPA_COMPLETED || wpa_s->current_ssid == NULL) { 151 wpa_dbg(wpa_s, MSG_DEBUG, "RRM: No connection, no RRM."); 152 return -ENOTCONN; 153 } 154 155 if (!wpa_s->rrm.rrm_used) { 156 wpa_dbg(wpa_s, MSG_DEBUG, "RRM: No RRM in current connection."); 157 return -EOPNOTSUPP; 158 } 159 160 rrm_ie = wpa_bss_get_ie(wpa_s->current_bss, 161 WLAN_EID_RRM_ENABLED_CAPABILITIES); 162 if (!rrm_ie || !(wpa_s->current_bss->caps & IEEE80211_CAP_RRM) || 163 !(rrm_ie[2] & WLAN_RRM_CAPS_NEIGHBOR_REPORT)) { 164 wpa_dbg(wpa_s, MSG_DEBUG, 165 "RRM: No network support for Neighbor Report."); 166 return -EOPNOTSUPP; 167 } 168 169 /* Refuse if there's a live request */ 170 if (wpa_s->rrm.notify_neighbor_rep) { 171 wpa_dbg(wpa_s, MSG_DEBUG, 172 "RRM: Currently handling previous Neighbor Report."); 173 return -EBUSY; 174 } 175 176 /* 3 = action category + action code + dialog token */ 177 buf = wpabuf_alloc(3 + (ssid ? 2 + ssid->ssid_len : 0) + 178 (lci ? 2 + MEASURE_REQUEST_LCI_LEN : 0) + 179 (civic ? 2 + MEASURE_REQUEST_CIVIC_LEN : 0)); 180 if (buf == NULL) { 181 wpa_dbg(wpa_s, MSG_DEBUG, 182 "RRM: Failed to allocate Neighbor Report Request"); 183 return -ENOMEM; 184 } 185 186 wpa_dbg(wpa_s, MSG_DEBUG, 187 "RRM: Neighbor report request (for %s), token=%d", 188 (ssid ? wpa_ssid_txt(ssid->ssid, ssid->ssid_len) : ""), 189 wpa_s->rrm.next_neighbor_rep_token); 190 191 wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT); 192 wpabuf_put_u8(buf, WLAN_RRM_NEIGHBOR_REPORT_REQUEST); 193 wpabuf_put_u8(buf, wpa_s->rrm.next_neighbor_rep_token); 194 if (ssid) { 195 wpabuf_put_u8(buf, WLAN_EID_SSID); 196 wpabuf_put_u8(buf, ssid->ssid_len); 197 wpabuf_put_data(buf, ssid->ssid, ssid->ssid_len); 198 } 199 200 if (lci) { 201 /* IEEE P802.11-REVmc/D5.0 9.4.2.21 */ 202 wpabuf_put_u8(buf, WLAN_EID_MEASURE_REQUEST); 203 wpabuf_put_u8(buf, MEASURE_REQUEST_LCI_LEN); 204 205 /* 206 * Measurement token; nonzero number that is unique among the 207 * Measurement Request elements in a particular frame. 208 */ 209 wpabuf_put_u8(buf, 1); /* Measurement Token */ 210 211 /* 212 * Parallel, Enable, Request, and Report bits are 0, Duration is 213 * reserved. 214 */ 215 wpabuf_put_u8(buf, 0); /* Measurement Request Mode */ 216 wpabuf_put_u8(buf, MEASURE_TYPE_LCI); /* Measurement Type */ 217 218 /* IEEE P802.11-REVmc/D5.0 9.4.2.21.10 - LCI request */ 219 /* Location Subject */ 220 wpabuf_put_u8(buf, LOCATION_SUBJECT_REMOTE); 221 222 /* Optional Subelements */ 223 /* 224 * IEEE P802.11-REVmc/D5.0 Figure 9-170 225 * The Maximum Age subelement is required, otherwise the AP can 226 * send only data that was determined after receiving the 227 * request. Setting it here to unlimited age. 228 */ 229 wpabuf_put_u8(buf, LCI_REQ_SUBELEM_MAX_AGE); 230 wpabuf_put_u8(buf, 2); 231 wpabuf_put_le16(buf, 0xffff); 232 } 233 234 if (civic) { 235 /* IEEE P802.11-REVmc/D5.0 9.4.2.21 */ 236 wpabuf_put_u8(buf, WLAN_EID_MEASURE_REQUEST); 237 wpabuf_put_u8(buf, MEASURE_REQUEST_CIVIC_LEN); 238 239 /* 240 * Measurement token; nonzero number that is unique among the 241 * Measurement Request elements in a particular frame. 242 */ 243 wpabuf_put_u8(buf, 2); /* Measurement Token */ 244 245 /* 246 * Parallel, Enable, Request, and Report bits are 0, Duration is 247 * reserved. 248 */ 249 wpabuf_put_u8(buf, 0); /* Measurement Request Mode */ 250 /* Measurement Type */ 251 wpabuf_put_u8(buf, MEASURE_TYPE_LOCATION_CIVIC); 252 253 /* IEEE P802.11-REVmc/D5.0 9.4.2.21.14: 254 * Location Civic request */ 255 /* Location Subject */ 256 wpabuf_put_u8(buf, LOCATION_SUBJECT_REMOTE); 257 wpabuf_put_u8(buf, 0); /* Civic Location Type: IETF RFC 4776 */ 258 /* Location Service Interval Units: Seconds */ 259 wpabuf_put_u8(buf, 0); 260 /* Location Service Interval: 0 - Only one report is requested 261 */ 262 wpabuf_put_le16(buf, 0); 263 /* No optional subelements */ 264 } 265 266 wpa_s->rrm.next_neighbor_rep_token++; 267 268 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, 269 wpa_s->own_addr, wpa_s->bssid, 270 wpabuf_head(buf), wpabuf_len(buf), 0) < 0) { 271 wpa_dbg(wpa_s, MSG_DEBUG, 272 "RRM: Failed to send Neighbor Report Request"); 273 wpabuf_free(buf); 274 return -ECANCELED; 275 } 276 277 wpa_s->rrm.neighbor_rep_cb_ctx = cb_ctx; 278 wpa_s->rrm.notify_neighbor_rep = cb; 279 eloop_register_timeout(RRM_NEIGHBOR_REPORT_TIMEOUT, 0, 280 wpas_rrm_neighbor_rep_timeout_handler, 281 &wpa_s->rrm, NULL); 282 283 wpabuf_free(buf); 284 return 0; 285 } 286 287 288 static int wpas_rrm_report_elem(struct wpabuf **buf, u8 token, u8 mode, u8 type, 289 const u8 *data, size_t data_len) 290 { 291 if (wpabuf_resize(buf, 5 + data_len)) 292 return -1; 293 294 wpabuf_put_u8(*buf, WLAN_EID_MEASURE_REPORT); 295 wpabuf_put_u8(*buf, 3 + data_len); 296 wpabuf_put_u8(*buf, token); 297 wpabuf_put_u8(*buf, mode); 298 wpabuf_put_u8(*buf, type); 299 300 if (data_len) 301 wpabuf_put_data(*buf, data, data_len); 302 303 return 0; 304 } 305 306 307 static int 308 wpas_rrm_build_lci_report(struct wpa_supplicant *wpa_s, 309 const struct rrm_measurement_request_element *req, 310 struct wpabuf **buf) 311 { 312 u8 subject; 313 u16 max_age = 0; 314 struct os_reltime t, diff; 315 unsigned long diff_l; 316 const u8 *subelem; 317 const u8 *request = req->variable; 318 size_t len = req->len - 3; 319 320 if (len < 1) 321 return -1; 322 323 if (!wpa_s->lci) 324 goto reject; 325 326 subject = *request++; 327 len--; 328 329 wpa_printf(MSG_DEBUG, "Measurement request location subject=%u", 330 subject); 331 332 if (subject != LOCATION_SUBJECT_REMOTE) { 333 wpa_printf(MSG_INFO, 334 "Not building LCI report - bad location subject"); 335 return 0; 336 } 337 338 /* Subelements are formatted exactly like elements */ 339 wpa_hexdump(MSG_DEBUG, "LCI request subelements", request, len); 340 subelem = get_ie(request, len, LCI_REQ_SUBELEM_MAX_AGE); 341 if (subelem && subelem[1] == 2) 342 max_age = WPA_GET_LE16(subelem + 2); 343 344 if (os_get_reltime(&t)) 345 goto reject; 346 347 os_reltime_sub(&t, &wpa_s->lci_time, &diff); 348 /* LCI age is calculated in 10th of a second units. */ 349 diff_l = diff.sec * 10 + diff.usec / 100000; 350 351 if (max_age != 0xffff && max_age < diff_l) 352 goto reject; 353 354 if (wpas_rrm_report_elem(buf, req->token, 355 MEASUREMENT_REPORT_MODE_ACCEPT, req->type, 356 wpabuf_head_u8(wpa_s->lci), 357 wpabuf_len(wpa_s->lci)) < 0) { 358 wpa_printf(MSG_DEBUG, "Failed to add LCI report element"); 359 return -1; 360 } 361 362 return 0; 363 364 reject: 365 if (!is_multicast_ether_addr(wpa_s->rrm.dst_addr) && 366 wpas_rrm_report_elem(buf, req->token, 367 MEASUREMENT_REPORT_MODE_REJECT_INCAPABLE, 368 req->type, NULL, 0) < 0) { 369 wpa_printf(MSG_DEBUG, "RRM: Failed to add report element"); 370 return -1; 371 } 372 373 return 0; 374 } 375 376 377 static void wpas_rrm_send_msr_report_mpdu(struct wpa_supplicant *wpa_s, 378 const u8 *data, size_t len) 379 { 380 struct wpabuf *report = wpabuf_alloc(len + 3); 381 382 if (!report) 383 return; 384 385 wpabuf_put_u8(report, WLAN_ACTION_RADIO_MEASUREMENT); 386 wpabuf_put_u8(report, WLAN_RRM_RADIO_MEASUREMENT_REPORT); 387 wpabuf_put_u8(report, wpa_s->rrm.token); 388 389 wpabuf_put_data(report, data, len); 390 391 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, 392 wpa_s->own_addr, wpa_s->bssid, 393 wpabuf_head(report), wpabuf_len(report), 0)) { 394 wpa_printf(MSG_ERROR, 395 "RRM: Radio measurement report failed: Sending Action frame failed"); 396 } 397 398 wpabuf_free(report); 399 } 400 401 402 static int wpas_rrm_beacon_rep_update_last_frame(u8 *pos, size_t len) 403 { 404 struct rrm_measurement_report_element *msr_rep; 405 u8 *end = pos + len; 406 u8 *msr_rep_end; 407 struct rrm_measurement_beacon_report *rep = NULL; 408 u8 *subelem; 409 410 /* Find the last beacon report element */ 411 while (end - pos >= (int) sizeof(*msr_rep)) { 412 msr_rep = (struct rrm_measurement_report_element *) pos; 413 msr_rep_end = pos + msr_rep->len + 2; 414 415 if (msr_rep->eid != WLAN_EID_MEASURE_REPORT || 416 msr_rep_end > end) { 417 /* Should not happen. This indicates a bug. */ 418 wpa_printf(MSG_ERROR, 419 "RRM: non-measurement report element in measurement report frame"); 420 return -1; 421 } 422 423 if (msr_rep->type == MEASURE_TYPE_BEACON) 424 rep = (struct rrm_measurement_beacon_report *) 425 msr_rep->variable; 426 427 pos += pos[1] + 2; 428 } 429 430 if (!rep) 431 return 0; 432 433 subelem = rep->variable; 434 while (subelem + 2 < msr_rep_end && 435 subelem[0] != WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION) 436 subelem += 2 + subelem[1]; 437 438 if (subelem + 2 < msr_rep_end && 439 subelem[0] == WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION && 440 subelem[1] == 1 && 441 subelem + BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN <= end) 442 subelem[2] = 1; 443 444 return 0; 445 } 446 447 448 static void wpas_rrm_send_msr_report(struct wpa_supplicant *wpa_s, 449 struct wpabuf *buf) 450 { 451 int len = wpabuf_len(buf); 452 u8 *pos = wpabuf_mhead_u8(buf), *next = pos; 453 454 #define MPDU_REPORT_LEN (int) (IEEE80211_MAX_MMPDU_SIZE - IEEE80211_HDRLEN - 3) 455 456 while (len) { 457 int send_len = (len > MPDU_REPORT_LEN) ? next - pos : len; 458 459 if (send_len == len) 460 wpas_rrm_beacon_rep_update_last_frame(pos, len); 461 462 if (send_len == len || 463 (send_len + next[1] + 2) > MPDU_REPORT_LEN) { 464 wpas_rrm_send_msr_report_mpdu(wpa_s, pos, send_len); 465 len -= send_len; 466 pos = next; 467 } 468 469 if (len) 470 next += next[1] + 2; 471 } 472 #undef MPDU_REPORT_LEN 473 } 474 475 476 static int wpas_add_channel(u8 op_class, u8 chan, u8 num_primary_channels, 477 int *freqs) 478 { 479 size_t i; 480 481 for (i = 0; i < num_primary_channels; i++) { 482 u8 primary_chan = chan - (2 * num_primary_channels - 2) + i * 4; 483 484 freqs[i] = ieee80211_chan_to_freq(NULL, op_class, primary_chan); 485 /* ieee80211_chan_to_freq() is not really meant for this 486 * conversion of 20 MHz primary channel numbers for wider VHT 487 * channels, so handle those as special cases here for now. */ 488 if (freqs[i] < 0 && 489 (op_class == 128 || op_class == 129 || op_class == 130)) 490 freqs[i] = 5000 + 5 * primary_chan; 491 if (freqs[i] < 0) { 492 wpa_printf(MSG_DEBUG, 493 "Beacon Report: Invalid channel %u", 494 chan); 495 return -1; 496 } 497 } 498 499 return 0; 500 } 501 502 503 static int * wpas_add_channels(const struct oper_class_map *op, 504 struct hostapd_hw_modes *mode, 505 const u8 *channels, const u8 size) 506 { 507 int *freqs, *next_freq; 508 u8 num_primary_channels, i; 509 u8 num_chans; 510 511 num_chans = channels ? size : 512 (op->max_chan - op->min_chan) / op->inc + 1; 513 514 if (op->bw == BW80 || op->bw == BW80P80) 515 num_primary_channels = 4; 516 else if (op->bw == BW160) 517 num_primary_channels = 8; 518 else if (op->bw == BW320) 519 num_primary_channels = 16; 520 else 521 num_primary_channels = 1; 522 523 /* one extra place for the zero-terminator */ 524 freqs = os_calloc(num_chans * num_primary_channels + 1, sizeof(*freqs)); 525 if (!freqs) { 526 wpa_printf(MSG_ERROR, 527 "Beacon Report: Failed to allocate freqs array"); 528 return NULL; 529 } 530 531 next_freq = freqs; 532 for (i = 0; i < num_chans; i++) { 533 u8 chan = channels ? channels[i] : op->min_chan + i * op->inc; 534 enum chan_allowed res = verify_channel(mode, op->op_class, chan, 535 op->bw); 536 537 if (res == NOT_ALLOWED) 538 continue; 539 540 if (wpas_add_channel(op->op_class, chan, num_primary_channels, 541 next_freq) < 0) { 542 os_free(freqs); 543 return NULL; 544 } 545 546 next_freq += num_primary_channels; 547 } 548 549 if (!freqs[0]) { 550 os_free(freqs); 551 return NULL; 552 } 553 554 return freqs; 555 } 556 557 558 static int * wpas_op_class_freqs(const struct oper_class_map *op, 559 struct hostapd_hw_modes *mode) 560 { 561 u8 channels_80mhz_5ghz[] = { 42, 58, 106, 122, 138, 155, 171 }; 562 u8 channels_160mhz_5ghz[] = { 50, 114, 163 }; 563 u8 channels_80mhz_6ghz[] = { 7, 23, 39, 55, 71, 87, 103, 119, 135, 151, 564 167, 183, 199, 215 }; 565 u8 channels_160mhz_6ghz[] = { 15, 47, 79, 111, 143, 175, 207 }; 566 u8 channels_320mhz_6ghz[] = { 31, 63, 95, 127, 159, 191 }; 567 const u8 *channels = NULL; 568 size_t num_chan = 0; 569 bool is_6ghz = is_6ghz_op_class(op->op_class); 570 571 /* 572 * When adding all channels in the operating class, 80 + 80 MHz 573 * operating classes are like 80 MHz channels because we add all valid 574 * channels anyway. 575 */ 576 if (op->bw == BW80 || op->bw == BW80P80) { 577 channels = is_6ghz ? channels_80mhz_6ghz : channels_80mhz_5ghz; 578 num_chan = is_6ghz ? ARRAY_SIZE(channels_80mhz_6ghz) : 579 ARRAY_SIZE(channels_80mhz_5ghz); 580 } else if (op->bw == BW160) { 581 channels = is_6ghz ? channels_160mhz_6ghz : 582 channels_160mhz_5ghz; 583 num_chan = is_6ghz ? ARRAY_SIZE(channels_160mhz_6ghz) : 584 ARRAY_SIZE(channels_160mhz_5ghz); 585 } else if (op->bw == BW320) { 586 channels = channels_320mhz_6ghz; 587 num_chan = ARRAY_SIZE(channels_320mhz_6ghz); 588 } 589 590 return wpas_add_channels(op, mode, channels, num_chan); 591 } 592 593 594 static int * wpas_channel_report_freqs(struct wpa_supplicant *wpa_s, 595 const char *country, const u8 *subelems, 596 size_t len) 597 { 598 int *freqs = NULL, *new_freqs; 599 const u8 *end = subelems + len; 600 601 while (end - subelems > 2) { 602 const struct oper_class_map *op; 603 const u8 *ap_chan_elem, *pos; 604 u8 left; 605 struct hostapd_hw_modes *mode; 606 607 ap_chan_elem = get_ie(subelems, end - subelems, 608 WLAN_BEACON_REQUEST_SUBELEM_AP_CHANNEL); 609 if (!ap_chan_elem) 610 break; 611 pos = ap_chan_elem + 2; 612 left = ap_chan_elem[1]; 613 if (left < 1) 614 break; 615 subelems = ap_chan_elem + 2 + left; 616 617 op = get_oper_class(country, *pos); 618 if (!op) { 619 wpa_printf(MSG_DEBUG, 620 "Beacon request: unknown operating class in AP Channel Report subelement %u", 621 *pos); 622 goto out; 623 } 624 pos++; 625 left--; 626 627 mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op->mode, 628 is_6ghz_op_class(op->op_class)); 629 if (!mode) 630 continue; 631 632 /* 633 * For 80 + 80 MHz operating classes, this AP Channel Report 634 * element should be followed by another element specifying 635 * the second 80 MHz channel. For now just add this 80 MHz 636 * channel, the second 80 MHz channel will be added when the 637 * next element is parsed. 638 * TODO: Verify that this AP Channel Report element is followed 639 * by a corresponding AP Channel Report element as specified in 640 * IEEE Std 802.11-2016, 11.11.9.1. 641 */ 642 new_freqs = wpas_add_channels(op, mode, pos, left); 643 if (new_freqs) 644 int_array_concat(&freqs, new_freqs); 645 646 os_free(new_freqs); 647 } 648 649 return freqs; 650 out: 651 os_free(freqs); 652 return NULL; 653 } 654 655 656 static int * wpas_beacon_request_freqs(struct wpa_supplicant *wpa_s, 657 u8 op_class, u8 chan, 658 const u8 *subelems, size_t len) 659 { 660 int *freqs = NULL, *ext_freqs = NULL; 661 struct hostapd_hw_modes *mode; 662 const char *country = NULL; 663 const struct oper_class_map *op; 664 const u8 *elem; 665 666 if (!wpa_s->current_bss) 667 return NULL; 668 elem = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_COUNTRY); 669 if (elem && elem[1] >= 2) 670 country = (const char *) (elem + 2); 671 672 op = get_oper_class(country, op_class); 673 if (!op) { 674 wpa_printf(MSG_DEBUG, 675 "Beacon request: invalid operating class %d", 676 op_class); 677 return NULL; 678 } 679 680 mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op->mode, 681 is_6ghz_op_class(op->op_class)); 682 if (!mode) 683 return NULL; 684 685 switch (chan) { 686 case 0: 687 freqs = wpas_op_class_freqs(op, mode); 688 if (!freqs) 689 return NULL; 690 break; 691 case 255: 692 /* freqs will be added from AP channel subelements */ 693 break; 694 default: 695 freqs = wpas_add_channels(op, mode, &chan, 1); 696 if (!freqs) 697 return NULL; 698 break; 699 } 700 701 ext_freqs = wpas_channel_report_freqs(wpa_s, country, subelems, len); 702 if (ext_freqs) { 703 int_array_concat(&freqs, ext_freqs); 704 os_free(ext_freqs); 705 int_array_sort_unique(freqs); 706 } 707 708 return freqs; 709 } 710 711 712 int wpas_get_op_chan_phy(int freq, const u8 *ies, size_t ies_len, 713 u8 *op_class, u8 *chan, u8 *phy_type) 714 { 715 const u8 *ie; 716 int sec_chan = 0, vht = 0; 717 struct ieee80211_ht_operation *ht_oper = NULL; 718 struct ieee80211_vht_operation *vht_oper = NULL; 719 u8 seg0, seg1; 720 721 ie = get_ie(ies, ies_len, WLAN_EID_HT_OPERATION); 722 if (ie && ie[1] >= sizeof(struct ieee80211_ht_operation)) { 723 u8 sec_chan_offset; 724 725 ht_oper = (struct ieee80211_ht_operation *) (ie + 2); 726 sec_chan_offset = ht_oper->ht_param & 727 HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK; 728 if (sec_chan_offset == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE) 729 sec_chan = 1; 730 else if (sec_chan_offset == 731 HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW) 732 sec_chan = -1; 733 } 734 735 ie = get_ie(ies, ies_len, WLAN_EID_VHT_OPERATION); 736 if (ie && ie[1] >= sizeof(struct ieee80211_vht_operation)) { 737 vht_oper = (struct ieee80211_vht_operation *) (ie + 2); 738 739 switch (vht_oper->vht_op_info_chwidth) { 740 case CHANWIDTH_80MHZ: 741 seg0 = vht_oper->vht_op_info_chan_center_freq_seg0_idx; 742 seg1 = vht_oper->vht_op_info_chan_center_freq_seg1_idx; 743 if (seg1 && abs(seg1 - seg0) == 8) 744 vht = CONF_OPER_CHWIDTH_160MHZ; 745 else if (seg1) 746 vht = CONF_OPER_CHWIDTH_80P80MHZ; 747 else 748 vht = CONF_OPER_CHWIDTH_80MHZ; 749 break; 750 case CHANWIDTH_160MHZ: 751 vht = CONF_OPER_CHWIDTH_160MHZ; 752 break; 753 case CHANWIDTH_80P80MHZ: 754 vht = CONF_OPER_CHWIDTH_80P80MHZ; 755 break; 756 default: 757 vht = CONF_OPER_CHWIDTH_USE_HT; 758 break; 759 } 760 } 761 762 if (ieee80211_freq_to_channel_ext(freq, sec_chan, vht, op_class, 763 chan) == NUM_HOSTAPD_MODES) { 764 wpa_printf(MSG_DEBUG, 765 "Cannot determine operating class and channel"); 766 return -1; 767 } 768 769 *phy_type = ieee80211_get_phy_type(freq, ht_oper != NULL, 770 vht_oper != NULL); 771 if (*phy_type == PHY_TYPE_UNSPECIFIED) { 772 wpa_printf(MSG_DEBUG, "Cannot determine phy type"); 773 return -1; 774 } 775 776 return 0; 777 } 778 779 780 static int wpas_beacon_rep_add_frame_body(struct bitfield *eids, 781 struct bitfield *ext_eids, 782 enum beacon_report_detail detail, 783 struct wpa_bss *bss, u8 *buf, 784 size_t buf_len, const u8 **ies_buf, 785 size_t *ie_len, int add_fixed) 786 { 787 const u8 *ies = *ies_buf; 788 size_t ies_len = *ie_len; 789 u8 *pos = buf; 790 int rem_len; 791 792 rem_len = 255 - sizeof(struct rrm_measurement_beacon_report) - 793 sizeof(struct rrm_measurement_report_element) - 2 - 794 REPORTED_FRAME_BODY_SUBELEM_LEN; 795 796 if (detail > BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS) { 797 wpa_printf(MSG_DEBUG, 798 "Beacon Request: Invalid reporting detail: %d", 799 detail); 800 return -1; 801 } 802 803 if (detail == BEACON_REPORT_DETAIL_NONE) 804 return 0; 805 806 /* 807 * Minimal frame body subelement size: EID(1) + length(1) + TSF(8) + 808 * beacon interval(2) + capabilities(2) = 14 bytes 809 */ 810 if (add_fixed && buf_len < 14) 811 return -1; 812 813 *pos++ = WLAN_BEACON_REPORT_SUBELEM_FRAME_BODY; 814 /* The length will be filled later */ 815 pos++; 816 817 if (add_fixed) { 818 WPA_PUT_LE64(pos, bss->tsf); 819 pos += sizeof(bss->tsf); 820 WPA_PUT_LE16(pos, bss->beacon_int); 821 pos += 2; 822 WPA_PUT_LE16(pos, bss->caps); 823 pos += 2; 824 } 825 826 rem_len -= pos - buf; 827 828 /* 829 * According to IEEE Std 802.11-2016, 9.4.2.22.7, if the reported frame 830 * body subelement causes the element to exceed the maximum element 831 * size, the subelement is truncated so that the last IE is a complete 832 * IE. So even when required to report all IEs, add elements one after 833 * the other and stop once there is no more room in the measurement 834 * element. 835 */ 836 while (ies_len > 2 && 2U + ies[1] <= ies_len && rem_len > 0) { 837 if (detail == BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS || 838 (eids && bitfield_is_set(eids, ies[0])) || 839 (ext_eids && ies[0] == WLAN_EID_EXTENSION && ies[1] && 840 bitfield_is_set(ext_eids, ies[2]))) { 841 u8 elen = ies[1]; 842 843 if (2 + elen > buf + buf_len - pos || 844 2 + elen > rem_len) 845 break; 846 847 *pos++ = ies[0]; 848 *pos++ = elen; 849 os_memcpy(pos, ies + 2, elen); 850 pos += elen; 851 rem_len -= 2 + elen; 852 } 853 854 ies_len -= 2 + ies[1]; 855 ies += 2 + ies[1]; 856 } 857 858 *ie_len = ies_len; 859 *ies_buf = ies; 860 861 /* Now the length is known */ 862 buf[1] = pos - buf - 2; 863 return pos - buf; 864 } 865 866 867 static int wpas_add_beacon_rep_elem(struct beacon_rep_data *data, 868 struct wpa_bss *bss, 869 struct wpabuf **wpa_buf, 870 struct rrm_measurement_beacon_report *rep, 871 const u8 **ie, size_t *ie_len, u8 idx) 872 { 873 int ret; 874 u8 *buf, *pos; 875 u32 subelems_len = REPORTED_FRAME_BODY_SUBELEM_LEN + 876 (data->last_indication ? 877 BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN : 0); 878 879 /* Maximum element length: Beacon Report element + Reported Frame Body 880 * subelement + all IEs of the reported Beacon frame + Reported Frame 881 * Body Fragment ID subelement */ 882 buf = os_malloc(sizeof(*rep) + 14 + *ie_len + subelems_len); 883 if (!buf) 884 return -1; 885 886 os_memcpy(buf, rep, sizeof(*rep)); 887 888 ret = wpas_beacon_rep_add_frame_body(data->eids, data->ext_eids, 889 data->report_detail, 890 bss, buf + sizeof(*rep), 891 14 + *ie_len, ie, ie_len, 892 idx == 0); 893 if (ret < 0) 894 goto out; 895 896 pos = buf + ret + sizeof(*rep); 897 pos[0] = WLAN_BEACON_REPORT_SUBELEM_FRAME_BODY_FRAGMENT_ID; 898 pos[1] = 2; 899 900 /* 901 * Only one Beacon Report Measurement is supported at a time, so 902 * the Beacon Report ID can always be set to 1. 903 */ 904 pos[2] = 1; 905 906 /* Fragment ID Number (bits 0..6) and More Frame Body Fragments (bit 7) 907 */ 908 pos[3] = idx; 909 if (data->report_detail != BEACON_REPORT_DETAIL_NONE && *ie_len) 910 pos[3] |= REPORTED_FRAME_BODY_MORE_FRAGMENTS; 911 else 912 pos[3] &= ~REPORTED_FRAME_BODY_MORE_FRAGMENTS; 913 914 pos += REPORTED_FRAME_BODY_SUBELEM_LEN; 915 916 if (data->last_indication) { 917 pos[0] = WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION; 918 pos[1] = 1; 919 920 /* This field will be updated later if this is the last frame */ 921 pos[2] = 0; 922 } 923 924 ret = wpas_rrm_report_elem(wpa_buf, data->token, 925 MEASUREMENT_REPORT_MODE_ACCEPT, 926 MEASURE_TYPE_BEACON, buf, 927 ret + sizeof(*rep) + subelems_len); 928 out: 929 os_free(buf); 930 return ret; 931 } 932 933 934 static int wpas_add_beacon_rep(struct wpa_supplicant *wpa_s, 935 struct wpabuf **wpa_buf, struct wpa_bss *bss, 936 u64 start, u64 parent_tsf) 937 { 938 struct beacon_rep_data *data = &wpa_s->beacon_rep_data; 939 const u8 *ies = wpa_bss_ie_ptr(bss); 940 const u8 *pos = ies; 941 size_t ies_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len; 942 struct rrm_measurement_beacon_report rep; 943 u8 idx = 0; 944 945 if (!ether_addr_equal(data->bssid, broadcast_ether_addr) && 946 !ether_addr_equal(data->bssid, bss->bssid)) 947 return 0; 948 949 if (data->ssid_len && 950 (data->ssid_len != bss->ssid_len || 951 os_memcmp(data->ssid, bss->ssid, bss->ssid_len) != 0)) 952 return 0; 953 954 if (wpas_get_op_chan_phy(bss->freq, ies, ies_len, &rep.op_class, 955 &rep.channel, &rep.report_info) < 0) 956 return 0; 957 958 rep.start_time = host_to_le64(start); 959 rep.duration = host_to_le16(data->scan_params.duration); 960 rep.rcpi = rssi_to_rcpi(bss->level); 961 rep.rsni = 255; /* 255 indicates that RSNI is not available */ 962 os_memcpy(rep.bssid, bss->bssid, ETH_ALEN); 963 rep.antenna_id = 0; /* unknown */ 964 rep.parent_tsf = host_to_le32(parent_tsf); 965 966 do { 967 int ret; 968 969 ret = wpas_add_beacon_rep_elem(data, bss, wpa_buf, &rep, 970 &pos, &ies_len, idx++); 971 if (ret) 972 return ret; 973 } while (data->report_detail != BEACON_REPORT_DETAIL_NONE && 974 ies_len >= 2); 975 976 return 0; 977 } 978 979 980 static int wpas_beacon_rep_no_results(struct wpa_supplicant *wpa_s, 981 struct wpabuf **buf) 982 { 983 return wpas_rrm_report_elem(buf, wpa_s->beacon_rep_data.token, 984 MEASUREMENT_REPORT_MODE_ACCEPT, 985 MEASURE_TYPE_BEACON, NULL, 0); 986 } 987 988 989 static void wpas_beacon_rep_table(struct wpa_supplicant *wpa_s, 990 struct wpabuf **buf) 991 { 992 size_t i; 993 994 for (i = 0; i < wpa_s->last_scan_res_used; i++) { 995 if (wpas_add_beacon_rep(wpa_s, buf, wpa_s->last_scan_res[i], 996 0, 0) < 0) 997 break; 998 } 999 1000 if (!(*buf)) 1001 wpas_beacon_rep_no_results(wpa_s, buf); 1002 1003 wpa_hexdump_buf(MSG_DEBUG, "RRM: Radio Measurement report", *buf); 1004 } 1005 1006 1007 void wpas_rrm_refuse_request(struct wpa_supplicant *wpa_s) 1008 { 1009 if (!is_multicast_ether_addr(wpa_s->rrm.dst_addr)) { 1010 struct wpabuf *buf = NULL; 1011 1012 if (wpas_rrm_report_elem(&buf, wpa_s->beacon_rep_data.token, 1013 MEASUREMENT_REPORT_MODE_REJECT_REFUSED, 1014 MEASURE_TYPE_BEACON, NULL, 0)) { 1015 wpa_printf(MSG_ERROR, "RRM: Memory allocation failed"); 1016 wpabuf_free(buf); 1017 return; 1018 } 1019 1020 wpas_rrm_send_msr_report(wpa_s, buf); 1021 wpabuf_free(buf); 1022 } 1023 1024 wpas_clear_beacon_rep_data(wpa_s); 1025 } 1026 1027 1028 static void wpas_rrm_scan_timeout(void *eloop_ctx, void *timeout_ctx) 1029 { 1030 struct wpa_supplicant *wpa_s = eloop_ctx; 1031 struct wpa_driver_scan_params *params = 1032 &wpa_s->beacon_rep_data.scan_params; 1033 u16 prev_duration = params->duration; 1034 1035 if (!wpa_s->current_bss) 1036 return; 1037 1038 if (!(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_SUPPORT_SET_SCAN_DWELL) && 1039 params->duration) { 1040 wpa_printf(MSG_DEBUG, 1041 "RRM: Cannot set scan duration due to missing driver support"); 1042 params->duration = 0; 1043 } 1044 os_get_reltime(&wpa_s->beacon_rep_scan); 1045 if (wpa_s->scanning || wpas_p2p_in_progress(wpa_s) || 1046 wpa_supplicant_trigger_scan(wpa_s, params, true, false)) 1047 wpas_rrm_refuse_request(wpa_s); 1048 params->duration = prev_duration; 1049 } 1050 1051 1052 static int wpas_rm_handle_beacon_req_subelem(struct wpa_supplicant *wpa_s, 1053 struct beacon_rep_data *data, 1054 u8 sid, u8 slen, const u8 *subelem) 1055 { 1056 struct bitfield *eids; 1057 u8 report_info, i; 1058 1059 switch (sid) { 1060 case WLAN_BEACON_REQUEST_SUBELEM_SSID: 1061 if (!slen) { 1062 wpa_printf(MSG_DEBUG, 1063 "SSID subelement with zero length - wildcard SSID"); 1064 break; 1065 } 1066 1067 if (slen > SSID_MAX_LEN) { 1068 wpa_printf(MSG_DEBUG, 1069 "Invalid SSID subelement length: %u", slen); 1070 return -1; 1071 } 1072 1073 data->ssid_len = slen; 1074 os_memcpy(data->ssid, subelem, data->ssid_len); 1075 break; 1076 case WLAN_BEACON_REQUEST_SUBELEM_INFO: 1077 if (slen != 2) { 1078 wpa_printf(MSG_DEBUG, 1079 "Invalid reporting information subelement length: %u", 1080 slen); 1081 return -1; 1082 } 1083 1084 report_info = subelem[0]; 1085 if (report_info != 0) { 1086 wpa_printf(MSG_DEBUG, 1087 "reporting information=%u is not supported", 1088 report_info); 1089 return 0; 1090 } 1091 break; 1092 case WLAN_BEACON_REQUEST_SUBELEM_DETAIL: 1093 if (slen != 1) { 1094 wpa_printf(MSG_DEBUG, 1095 "Invalid reporting detail subelement length: %u", 1096 slen); 1097 return -1; 1098 } 1099 1100 data->report_detail = subelem[0]; 1101 if (data->report_detail > 1102 BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS) { 1103 wpa_printf(MSG_DEBUG, "Invalid reporting detail: %u", 1104 subelem[0]); 1105 return -1; 1106 } 1107 1108 break; 1109 case WLAN_BEACON_REQUEST_SUBELEM_REQUEST: 1110 case WLAN_BEACON_REQUEST_SUBELEM_EXT_REQUEST: 1111 if (data->report_detail != 1112 BEACON_REPORT_DETAIL_REQUESTED_ONLY) { 1113 wpa_printf(MSG_DEBUG, 1114 "Beacon request: request subelement is present but report detail is %u", 1115 data->report_detail); 1116 return -1; 1117 } 1118 1119 if (!slen) { 1120 wpa_printf(MSG_DEBUG, 1121 "Invalid request subelement length: %u", 1122 slen); 1123 return -1; 1124 } 1125 1126 if (sid == WLAN_BEACON_REQUEST_SUBELEM_EXT_REQUEST) { 1127 if (slen < 2) { 1128 wpa_printf(MSG_DEBUG, 1129 "Invalid extended request"); 1130 return -1; 1131 } 1132 if (subelem[0] != WLAN_EID_EXTENSION) { 1133 wpa_printf(MSG_DEBUG, 1134 "Skip unknown Requested Element ID %u in Extended Request subelement", 1135 subelem[0]); 1136 break; 1137 } 1138 1139 /* Skip the Requested Element ID field */ 1140 subelem++; 1141 slen--; 1142 } 1143 1144 if ((sid == WLAN_BEACON_REQUEST_SUBELEM_REQUEST && 1145 data->eids) || 1146 (sid == WLAN_BEACON_REQUEST_SUBELEM_EXT_REQUEST && 1147 data->ext_eids)) { 1148 wpa_printf(MSG_DEBUG, 1149 "Beacon Request: Request sub elements appear more than once"); 1150 return -1; 1151 } 1152 1153 eids = bitfield_alloc(255); 1154 if (!eids) { 1155 wpa_printf(MSG_DEBUG, "Failed to allocate EIDs bitmap"); 1156 return -1; 1157 } 1158 1159 if (sid == WLAN_BEACON_REQUEST_SUBELEM_REQUEST) 1160 data->eids = eids; 1161 else 1162 data->ext_eids = eids; 1163 1164 for (i = 0; i < slen; i++) 1165 bitfield_set(eids, subelem[i]); 1166 break; 1167 case WLAN_BEACON_REQUEST_SUBELEM_AP_CHANNEL: 1168 /* Skip - it will be processed when freqs are added */ 1169 break; 1170 case WLAN_BEACON_REQUEST_SUBELEM_LAST_INDICATION: 1171 if (slen != 1) { 1172 wpa_printf(MSG_DEBUG, 1173 "Beacon request: Invalid last indication request subelement length: %u", 1174 slen); 1175 return -1; 1176 } 1177 1178 data->last_indication = subelem[0]; 1179 break; 1180 default: 1181 wpa_printf(MSG_DEBUG, 1182 "Beacon request: Unknown subelement id %u", sid); 1183 break; 1184 } 1185 1186 return 1; 1187 } 1188 1189 1190 /** 1191 * Returns 0 if the next element can be processed, 1 if some operation was 1192 * triggered, and -1 if processing failed (i.e., the element is in invalid 1193 * format or an internal error occurred). 1194 */ 1195 static int 1196 wpas_rm_handle_beacon_req(struct wpa_supplicant *wpa_s, 1197 u8 elem_token, int duration_mandatory, 1198 const struct rrm_measurement_beacon_request *req, 1199 size_t len, struct wpabuf **buf) 1200 { 1201 struct beacon_rep_data *data = &wpa_s->beacon_rep_data; 1202 struct wpa_driver_scan_params *params = &data->scan_params; 1203 const u8 *subelems; 1204 size_t elems_len; 1205 u16 rand_interval; 1206 u32 interval_usec; 1207 u32 _rand; 1208 int ret = 0, res; 1209 u8 reject_mode; 1210 1211 if (len < sizeof(*req)) 1212 return -1; 1213 1214 if (req->mode != BEACON_REPORT_MODE_PASSIVE && 1215 req->mode != BEACON_REPORT_MODE_ACTIVE && 1216 req->mode != BEACON_REPORT_MODE_TABLE) 1217 return 0; 1218 1219 subelems = req->variable; 1220 elems_len = len - sizeof(*req); 1221 rand_interval = le_to_host16(req->rand_interval); 1222 1223 os_free(params->freqs); 1224 os_memset(params, 0, sizeof(*params)); 1225 1226 data->token = elem_token; 1227 1228 /* default reporting detail is all fixed length fields and all 1229 * elements */ 1230 data->report_detail = BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS; 1231 os_memcpy(data->bssid, req->bssid, ETH_ALEN); 1232 1233 while (elems_len >= 2) { 1234 if (subelems[1] > elems_len - 2) { 1235 wpa_printf(MSG_DEBUG, 1236 "Beacon Request: Truncated subelement"); 1237 ret = -1; 1238 goto out; 1239 } 1240 1241 res = wpas_rm_handle_beacon_req_subelem( 1242 wpa_s, data, subelems[0], subelems[1], &subelems[2]); 1243 if (res < 0) { 1244 ret = res; 1245 goto out; 1246 } else if (!res) { 1247 reject_mode = MEASUREMENT_REPORT_MODE_REJECT_INCAPABLE; 1248 goto out_reject; 1249 } 1250 1251 elems_len -= 2 + subelems[1]; 1252 subelems += 2 + subelems[1]; 1253 } 1254 1255 if (req->mode == BEACON_REPORT_MODE_TABLE) { 1256 wpas_beacon_rep_table(wpa_s, buf); 1257 goto out; 1258 } 1259 1260 params->freqs = wpas_beacon_request_freqs(wpa_s, req->oper_class, 1261 req->channel, req->variable, 1262 len - sizeof(*req)); 1263 if (!params->freqs) { 1264 wpa_printf(MSG_DEBUG, "Beacon request: No valid channels"); 1265 reject_mode = MEASUREMENT_REPORT_MODE_REJECT_REFUSED; 1266 goto out_reject; 1267 } 1268 1269 params->duration = le_to_host16(req->duration); 1270 params->duration_mandatory = duration_mandatory; 1271 if (!params->duration) { 1272 wpa_printf(MSG_DEBUG, "Beacon request: Duration is 0"); 1273 ret = -1; 1274 goto out; 1275 } 1276 1277 params->only_new_results = 1; 1278 1279 if (req->mode == BEACON_REPORT_MODE_ACTIVE) { 1280 params->ssids[params->num_ssids].ssid = data->ssid; 1281 params->ssids[params->num_ssids++].ssid_len = data->ssid_len; 1282 } 1283 1284 if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0) 1285 _rand = os_random(); 1286 interval_usec = (_rand % (rand_interval + 1)) * 1024; 1287 eloop_register_timeout(0, interval_usec, wpas_rrm_scan_timeout, wpa_s, 1288 NULL); 1289 return 1; 1290 out_reject: 1291 if (!is_multicast_ether_addr(wpa_s->rrm.dst_addr) && 1292 wpas_rrm_report_elem(buf, elem_token, reject_mode, 1293 MEASURE_TYPE_BEACON, NULL, 0) < 0) { 1294 wpa_printf(MSG_DEBUG, "RRM: Failed to add report element"); 1295 ret = -1; 1296 } 1297 out: 1298 wpas_clear_beacon_rep_data(wpa_s); 1299 return ret; 1300 } 1301 1302 1303 static int 1304 wpas_rrm_handle_msr_req_element( 1305 struct wpa_supplicant *wpa_s, 1306 const struct rrm_measurement_request_element *req, 1307 struct wpabuf **buf) 1308 { 1309 int duration_mandatory; 1310 1311 wpa_printf(MSG_DEBUG, "Measurement request type %d token %d", 1312 req->type, req->token); 1313 1314 if (req->mode & MEASUREMENT_REQUEST_MODE_ENABLE) { 1315 /* Enable bit is not supported for now */ 1316 wpa_printf(MSG_DEBUG, "RRM: Enable bit not supported, ignore"); 1317 return 0; 1318 } 1319 1320 if ((req->mode & MEASUREMENT_REQUEST_MODE_PARALLEL) && 1321 req->type > MEASURE_TYPE_RPI_HIST) { 1322 /* Parallel measurements are not supported for now */ 1323 wpa_printf(MSG_DEBUG, 1324 "RRM: Parallel measurements are not supported, reject"); 1325 goto reject; 1326 } 1327 1328 duration_mandatory = 1329 !!(req->mode & MEASUREMENT_REQUEST_MODE_DURATION_MANDATORY); 1330 1331 switch (req->type) { 1332 case MEASURE_TYPE_LCI: 1333 return wpas_rrm_build_lci_report(wpa_s, req, buf); 1334 case MEASURE_TYPE_BEACON: 1335 if (duration_mandatory && 1336 !(wpa_s->drv_rrm_flags & 1337 WPA_DRIVER_FLAGS_SUPPORT_SET_SCAN_DWELL)) { 1338 wpa_printf(MSG_DEBUG, 1339 "RRM: Driver does not support dwell time configuration - reject beacon report with mandatory duration"); 1340 goto reject; 1341 } 1342 return wpas_rm_handle_beacon_req(wpa_s, req->token, 1343 duration_mandatory, 1344 (const void *) req->variable, 1345 req->len - 3, buf); 1346 default: 1347 wpa_printf(MSG_INFO, 1348 "RRM: Unsupported radio measurement type %u", 1349 req->type); 1350 break; 1351 } 1352 1353 reject: 1354 if (!is_multicast_ether_addr(wpa_s->rrm.dst_addr) && 1355 wpas_rrm_report_elem(buf, req->token, 1356 MEASUREMENT_REPORT_MODE_REJECT_INCAPABLE, 1357 req->type, NULL, 0) < 0) { 1358 wpa_printf(MSG_DEBUG, "RRM: Failed to add report element"); 1359 return -1; 1360 } 1361 1362 return 0; 1363 } 1364 1365 1366 static struct wpabuf * 1367 wpas_rrm_process_msr_req_elems(struct wpa_supplicant *wpa_s, const u8 *pos, 1368 size_t len) 1369 { 1370 struct wpabuf *buf = NULL; 1371 1372 while (len) { 1373 const struct rrm_measurement_request_element *req; 1374 int res; 1375 1376 if (len < 2) { 1377 wpa_printf(MSG_DEBUG, "RRM: Truncated element"); 1378 goto out; 1379 } 1380 1381 req = (const struct rrm_measurement_request_element *) pos; 1382 if (req->eid != WLAN_EID_MEASURE_REQUEST) { 1383 wpa_printf(MSG_DEBUG, 1384 "RRM: Expected Measurement Request element, but EID is %u", 1385 req->eid); 1386 goto out; 1387 } 1388 1389 if (req->len < 3) { 1390 wpa_printf(MSG_DEBUG, "RRM: Element length too short"); 1391 goto out; 1392 } 1393 1394 if (req->len > len - 2) { 1395 wpa_printf(MSG_DEBUG, "RRM: Element length too long"); 1396 goto out; 1397 } 1398 1399 res = wpas_rrm_handle_msr_req_element(wpa_s, req, &buf); 1400 if (res < 0) 1401 goto out; 1402 1403 pos += req->len + 2; 1404 len -= req->len + 2; 1405 } 1406 1407 return buf; 1408 1409 out: 1410 wpabuf_free(buf); 1411 return NULL; 1412 } 1413 1414 1415 void wpas_rrm_handle_radio_measurement_request(struct wpa_supplicant *wpa_s, 1416 const u8 *src, const u8 *dst, 1417 const u8 *frame, size_t len) 1418 { 1419 struct wpabuf *report; 1420 1421 if (wpa_s->wpa_state != WPA_COMPLETED) { 1422 wpa_printf(MSG_INFO, 1423 "RRM: Ignoring radio measurement request: Not associated"); 1424 return; 1425 } 1426 1427 if (!wpa_s->rrm.rrm_used) { 1428 wpa_printf(MSG_INFO, 1429 "RRM: Ignoring radio measurement request: Not RRM network"); 1430 return; 1431 } 1432 1433 if (len < 3) { 1434 wpa_printf(MSG_INFO, 1435 "RRM: Ignoring too short radio measurement request"); 1436 return; 1437 } 1438 1439 wpa_s->rrm.token = *frame; 1440 os_memcpy(wpa_s->rrm.dst_addr, dst, ETH_ALEN); 1441 1442 /* Number of repetitions is not supported */ 1443 1444 report = wpas_rrm_process_msr_req_elems(wpa_s, frame + 3, len - 3); 1445 if (!report) 1446 return; 1447 1448 wpas_rrm_send_msr_report(wpa_s, report); 1449 wpabuf_free(report); 1450 } 1451 1452 1453 void wpas_rrm_handle_link_measurement_request(struct wpa_supplicant *wpa_s, 1454 const u8 *src, 1455 const u8 *frame, size_t len, 1456 int rssi) 1457 { 1458 struct wpabuf *buf; 1459 const struct rrm_link_measurement_request *req; 1460 struct rrm_link_measurement_report report; 1461 1462 if (wpa_s->wpa_state != WPA_COMPLETED) { 1463 wpa_printf(MSG_INFO, 1464 "RRM: Ignoring link measurement request. Not associated"); 1465 return; 1466 } 1467 1468 if (!wpa_s->rrm.rrm_used) { 1469 wpa_printf(MSG_INFO, 1470 "RRM: Ignoring link measurement request. Not RRM network"); 1471 return; 1472 } 1473 1474 if (!(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION)) { 1475 wpa_printf(MSG_INFO, 1476 "RRM: Measurement report failed. TX power insertion not supported"); 1477 return; 1478 } 1479 1480 req = (const struct rrm_link_measurement_request *) frame; 1481 if (len < sizeof(*req)) { 1482 wpa_printf(MSG_INFO, 1483 "RRM: Link measurement report failed. Request too short"); 1484 return; 1485 } 1486 1487 os_memset(&report, 0, sizeof(report)); 1488 report.dialog_token = req->dialog_token; 1489 report.tpc.eid = WLAN_EID_TPC_REPORT; 1490 report.tpc.len = 2; 1491 /* Note: The driver is expected to update report.tpc.tx_power and 1492 * report.tpc.link_margin subfields when sending out this frame. 1493 * Similarly, the driver would need to update report.rx_ant_id and 1494 * report.tx_ant_id subfields. */ 1495 report.rsni = 255; /* 255 indicates that RSNI is not available */ 1496 report.rcpi = rssi_to_rcpi(rssi); 1497 1498 /* action_category + action_code */ 1499 buf = wpabuf_alloc(2 + sizeof(report)); 1500 if (buf == NULL) { 1501 wpa_printf(MSG_ERROR, 1502 "RRM: Link measurement report failed. Buffer allocation failed"); 1503 return; 1504 } 1505 1506 wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT); 1507 wpabuf_put_u8(buf, WLAN_RRM_LINK_MEASUREMENT_REPORT); 1508 wpabuf_put_data(buf, &report, sizeof(report)); 1509 wpa_hexdump_buf(MSG_DEBUG, "RRM: Link measurement report", buf); 1510 1511 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, src, 1512 wpa_s->own_addr, wpa_s->bssid, 1513 wpabuf_head(buf), wpabuf_len(buf), 0)) { 1514 wpa_printf(MSG_ERROR, 1515 "RRM: Link measurement report failed. Send action failed"); 1516 } 1517 wpabuf_free(buf); 1518 } 1519 1520 1521 static bool wpas_beacon_rep_scan_match(struct wpa_supplicant *wpa_s, 1522 const u8 *bssid) 1523 { 1524 u8 i; 1525 1526 if (!wpa_s->valid_links) 1527 return ether_addr_equal(wpa_s->current_bss->bssid, bssid); 1528 1529 for_each_link(wpa_s->valid_links, i) { 1530 if (ether_addr_equal(wpa_s->links[i].bssid, bssid)) 1531 return true; 1532 } 1533 1534 wpa_printf(MSG_DEBUG, "RRM: MLD: no match for TSF BSSID=" MACSTR, 1535 MAC2STR(bssid)); 1536 1537 return false; 1538 } 1539 1540 1541 int wpas_beacon_rep_scan_process(struct wpa_supplicant *wpa_s, 1542 struct wpa_scan_results *scan_res, 1543 struct scan_info *info) 1544 { 1545 size_t i = 0; 1546 struct wpabuf *buf = NULL; 1547 1548 if (!wpa_s->beacon_rep_data.token) 1549 return 0; 1550 1551 if (!wpa_s->current_bss) 1552 goto out; 1553 1554 /* If the measurement was aborted, don't report partial results */ 1555 if (info->aborted) 1556 goto out; 1557 1558 wpa_printf(MSG_DEBUG, "RRM: TSF BSSID: " MACSTR " current BSS: " MACSTR, 1559 MAC2STR(info->scan_start_tsf_bssid), 1560 MAC2STR(wpa_s->current_bss->bssid)); 1561 if ((wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT) && 1562 !wpas_beacon_rep_scan_match(wpa_s, info->scan_start_tsf_bssid)) { 1563 wpa_printf(MSG_DEBUG, 1564 "RRM: Ignore scan results due to mismatching TSF BSSID"); 1565 goto out; 1566 } 1567 1568 for (i = 0; i < scan_res->num; i++) { 1569 struct wpa_bss *bss = 1570 wpa_bss_get_bssid(wpa_s, scan_res->res[i]->bssid); 1571 1572 if (!bss) 1573 continue; 1574 1575 if ((wpa_s->drv_rrm_flags & 1576 WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT) && 1577 !wpas_beacon_rep_scan_match(wpa_s, 1578 scan_res->res[i]->tsf_bssid)) { 1579 wpa_printf(MSG_DEBUG, 1580 "RRM: Ignore scan result for " MACSTR 1581 " due to mismatching TSF BSSID" MACSTR, 1582 MAC2STR(scan_res->res[i]->bssid), 1583 MAC2STR(scan_res->res[i]->tsf_bssid)); 1584 continue; 1585 } 1586 1587 /* 1588 * Don't report results that were not received during the 1589 * current measurement. 1590 */ 1591 if (!(wpa_s->drv_rrm_flags & 1592 WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT)) { 1593 struct os_reltime update_time, diff; 1594 1595 /* For now, allow 8 ms older results due to some 1596 * unknown issue with cfg80211 BSS table updates during 1597 * a scan with the current BSS. 1598 * TODO: Fix this more properly to avoid having to have 1599 * this type of hacks in place. */ 1600 calculate_update_time(&scan_res->fetch_time, 1601 scan_res->res[i]->age, 1602 &update_time); 1603 os_reltime_sub(&wpa_s->beacon_rep_scan, 1604 &update_time, &diff); 1605 if (os_reltime_before(&update_time, 1606 &wpa_s->beacon_rep_scan) && 1607 (diff.sec || diff.usec >= 8000)) { 1608 wpa_printf(MSG_DEBUG, 1609 "RRM: Ignore scan result for " MACSTR 1610 " due to old update (age(ms) %u, calculated age %u.%06u seconds)", 1611 MAC2STR(scan_res->res[i]->bssid), 1612 scan_res->res[i]->age, 1613 (unsigned int) diff.sec, 1614 (unsigned int) diff.usec); 1615 continue; 1616 } 1617 } else if (info->scan_start_tsf > 1618 scan_res->res[i]->parent_tsf) { 1619 continue; 1620 } 1621 1622 if (wpas_add_beacon_rep(wpa_s, &buf, bss, info->scan_start_tsf, 1623 scan_res->res[i]->parent_tsf) < 0) 1624 break; 1625 } 1626 1627 if (!buf && wpas_beacon_rep_no_results(wpa_s, &buf)) 1628 goto out; 1629 1630 wpa_hexdump_buf(MSG_DEBUG, "RRM: Radio Measurement report", buf); 1631 1632 wpas_rrm_send_msr_report(wpa_s, buf); 1633 wpabuf_free(buf); 1634 1635 out: 1636 wpas_clear_beacon_rep_data(wpa_s); 1637 return 1; 1638 } 1639 1640 1641 void wpas_clear_beacon_rep_data(struct wpa_supplicant *wpa_s) 1642 { 1643 struct beacon_rep_data *data = &wpa_s->beacon_rep_data; 1644 1645 eloop_cancel_timeout(wpas_rrm_scan_timeout, wpa_s, NULL); 1646 bitfield_free(data->eids); 1647 bitfield_free(data->ext_eids); 1648 os_free(data->scan_params.freqs); 1649 os_memset(data, 0, sizeof(*data)); 1650 } 1651