1 /*
2 * Proxmity Ranging
3 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
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_defs.h"
14 #include "common/ieee802_11_common.h"
15 #include "common/proximity_ranging.h"
16 #include "p2p/p2p.h"
17 #include "wpa_supplicant_i.h"
18 #include "config.h"
19 #include "notify.h"
20 #include "driver_i.h"
21 #include "pr_supplicant.h"
22
23 #ifdef CONFIG_PASN
24 static void wpas_pr_pasn_timeout(void *eloop_ctx, void *timeout_ctx);
25 static void wpas_pr_pasn_roc_total_timeout(void *eloop_ctx, void *timeout_ctx);
26 static void wpas_pr_pasn_auth_work_done(struct wpa_supplicant *wpa_s);
27 static void wpas_pr_pasn_auth_retry_timeout(void *eloop_ctx, void *timeout_ctx);
28
29 /* Total listen window (ms) for the PASN responder ROC */
30 #define PR_PASN_RESPONDER_ROC_DURATION 10000
31 /* Initiator PASN authentication timeout (s) */
32 #define PR_PASN_AUTH_TIMEOUT 10
33 /* Retry interval (ms) for unacked PASN Authentication frame 1 */
34 #define PR_PASN_AUTH1_RETRY_INTERVAL_MS 100
35 #endif /* CONFIG_PASN */
36
37
wpas_pr_best_edca_format_bw(u32 bw_bitmap,u32 preamble_bitmap)38 static u8 wpas_pr_best_edca_format_bw(u32 bw_bitmap, u32 preamble_bitmap)
39 {
40 /* Prefer highest bandwidth first */
41 if ((bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_160)) &&
42 (preamble_bitmap & BIT(WPA_PR_PREAMBLE_VHT)))
43 return EDCA_FORMAT_AND_BW_VHT160_DUAL_LO;
44 if ((bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_80P80)) &&
45 (preamble_bitmap & BIT(WPA_PR_PREAMBLE_VHT)))
46 return EDCA_FORMAT_AND_BW_VHT80P80;
47 if ((bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_80)) &&
48 (preamble_bitmap & BIT(WPA_PR_PREAMBLE_VHT)))
49 return EDCA_FORMAT_AND_BW_VHT80;
50 if ((bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_40)) &&
51 (preamble_bitmap & BIT(WPA_PR_PREAMBLE_VHT)))
52 return EDCA_FORMAT_AND_BW_VHT40;
53 if ((bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_40)) &&
54 (preamble_bitmap & BIT(WPA_PR_PREAMBLE_HT)))
55 return EDCA_FORMAT_AND_BW_HT40;
56 if ((bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_20)) &&
57 (preamble_bitmap & BIT(WPA_PR_PREAMBLE_VHT)))
58 return EDCA_FORMAT_AND_BW_VHT20;
59 return EDCA_FORMAT_AND_BW_INVALID;
60 }
61
62
wpas_pr_best_ntb_format_bw(u32 bw_bitmap,u32 preamble_bitmap)63 static u8 wpas_pr_best_ntb_format_bw(u32 bw_bitmap, u32 preamble_bitmap)
64 {
65 if (!(preamble_bitmap & BIT(WPA_PR_PREAMBLE_HE)))
66 return NTB_FORMAT_AND_BW_INVALID;
67
68 if (bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_160))
69 return NTB_FORMAT_AND_BW_HE160_SINGLE_LO;
70 if (bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_80P80))
71 return NTB_FORMAT_AND_BW_HE80P80;
72 if (bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_80))
73 return NTB_FORMAT_AND_BW_HE80;
74 if (bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_40))
75 return NTB_FORMAT_AND_BW_HE40;
76 if (bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_20))
77 return NTB_FORMAT_AND_BW_HE20;
78 return NTB_FORMAT_AND_BW_INVALID;
79 }
80
81
82 static bool
wpas_pr_edca_is_valid_op_class(u32 bw_bitmap,u32 preamble_bitmap,const struct oper_class_map * op_class_map)83 wpas_pr_edca_is_valid_op_class(u32 bw_bitmap, u32 preamble_bitmap,
84 const struct oper_class_map *op_class_map)
85 {
86 if (!op_class_map)
87 return false;
88
89 switch (op_class_map->bw) {
90 case BW20:
91 return !!(bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_20)) &&
92 !!(preamble_bitmap & BIT(WPA_PR_PREAMBLE_VHT));
93 case BW40PLUS:
94 case BW40MINUS:
95 case BW40:
96 return !!(bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_40)) &&
97 !!(preamble_bitmap & (BIT(WPA_PR_PREAMBLE_VHT) |
98 BIT(WPA_PR_PREAMBLE_HT)));
99 case BW80:
100 return !!(bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_80)) &&
101 !!(preamble_bitmap & BIT(WPA_PR_PREAMBLE_VHT));
102 case BW80P80:
103 return !!(bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_80P80)) &&
104 !!(preamble_bitmap & BIT(WPA_PR_PREAMBLE_VHT));
105 case BW160:
106 return !!(bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_160)) &&
107 !!(preamble_bitmap & BIT(WPA_PR_PREAMBLE_VHT));
108 default:
109 return false;
110 }
111 }
112
113
114 static bool
wpas_pr_ntb_is_valid_op_class(u32 bw_bitmap,u32 preamble_bitmap,const struct oper_class_map * op_class_map)115 wpas_pr_ntb_is_valid_op_class(u32 bw_bitmap, u32 preamble_bitmap,
116 const struct oper_class_map *op_class_map)
117 {
118 if (!op_class_map)
119 return false;
120
121 /* NTB ranging requires HE preamble */
122 if (!(preamble_bitmap & BIT(WPA_PR_PREAMBLE_HE)))
123 return false;
124
125 switch (op_class_map->bw) {
126 case BW20:
127 return !!(bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_20));
128 case BW40PLUS:
129 case BW40MINUS:
130 case BW40:
131 return !!(bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_40));
132 case BW80:
133 return !!(bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_80));
134 case BW80P80:
135 return !!(bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_80P80));
136 case BW160:
137 return !!(bw_bitmap & BIT(WPA_PR_CHAN_WIDTH_160));
138 default:
139 return false;
140 }
141 }
142
143
144 /**
145 * wpas_pr_op_class_to_chan_params - Derive center freq and width from op_class
146 */
wpas_pr_op_class_to_chan_params(u8 op_class,u8 op_channel,u32 * center_freq1,u32 * center_freq2,u16 * channel_width)147 static int wpas_pr_op_class_to_chan_params(u8 op_class, u8 op_channel,
148 u32 *center_freq1,
149 u32 *center_freq2,
150 u16 *channel_width)
151 {
152 int control_freq, bw, offset = 0;
153 int half_bw, block_pos;
154
155 if (!center_freq1 || !center_freq2 || !channel_width)
156 return -1;
157
158 *center_freq1 = 0;
159 *center_freq2 = 0;
160 *channel_width = 0;
161
162 /* 80+80 MHz: center_freq2 is unknown from primary channel alone */
163 if (op_class == 130 || op_class == 135) {
164 wpa_printf(MSG_DEBUG,
165 "PR: op_class %u (80+80 MHz) not supported, center_freq2 cannot be determined",
166 op_class);
167 return -1;
168 }
169
170 control_freq = ieee80211_chan_to_freq(NULL, op_class, op_channel);
171 if (control_freq < 0) {
172 wpa_printf(MSG_DEBUG, "PR: Invalid op_class=%u channel=%u",
173 op_class, op_channel);
174 return -1;
175 }
176
177 bw = op_class_to_bandwidth(op_class);
178
179 /*
180 * 2.4 GHz 40 MHz: channels are 5 MHz apart so the generic offset
181 * formula does not apply. Handle upper (op_class 83) and lower
182 * (op_class 84) secondary channel directions explicitly.
183 */
184 if (op_class == 83) {
185 *center_freq1 = control_freq + 10;
186 *channel_width = 40;
187 return 0;
188 }
189 if (op_class == 84) {
190 *center_freq1 = control_freq - 10;
191 *channel_width = 40;
192 return 0;
193 }
194
195 if (bw == 20) {
196 *center_freq1 = control_freq;
197 *channel_width = 20;
198 return 0;
199 }
200
201 /*
202 * For 5 GHz and 6 GHz wider bandwidths, compute the primary channel's
203 * position (in 20 MHz steps) within its band segment, then derive
204 * center_freq1 using the formula:
205 * center_freq1 = control_freq + (bw/2 - 10) -
206 * (offset & (bw/20 - 1)) * 20
207 */
208 if (control_freq >= 5955)
209 offset = (control_freq - 5955) / 20;
210 else if (control_freq >= 5745)
211 offset = (control_freq - 5745) / 20;
212 else if (control_freq >= 5180)
213 offset = (control_freq - 5180) / 20;
214
215 /* Distance from the primary channel to the center of the BW block */
216 half_bw = bw / 2 - 10;
217
218 /* Position of the primary channel within its BW block (in 20 MHz steps)
219 */
220 block_pos = offset & (bw / 20 - 1);
221
222 /* Center = primary channel + half-BW offset - position within block */
223 *center_freq1 = control_freq + half_bw - block_pos * 20;
224 *channel_width = bw;
225
226 wpa_printf(MSG_DEBUG, "PR: op_class=%u ch=%u -> freq=%d cf1=%u bw=%d",
227 op_class, op_channel, control_freq, *center_freq1, bw);
228
229 return 0;
230 }
231
232
233 static void
wpas_pr_setup_edca_channels(struct wpa_supplicant * wpa_s,struct pr_channels * chan,u32 bw_bitmap,u32 preamble_bitmap,bool allow_6ghz)234 wpas_pr_setup_edca_channels(struct wpa_supplicant *wpa_s,
235 struct pr_channels *chan,
236 u32 bw_bitmap, u32 preamble_bitmap,
237 bool allow_6ghz)
238 {
239 struct hostapd_hw_modes *mode;
240 int cla = 0, i;
241
242 for (i = 0; global_op_class[i].op_class; i++) {
243 unsigned int ch;
244 struct pr_op_class *op = NULL;
245 const struct oper_class_map *o = &global_op_class[i];
246
247 mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode,
248 is_6ghz_op_class(o->op_class));
249 if (!mode || (!allow_6ghz && is_6ghz_op_class(o->op_class)) ||
250 !wpas_pr_edca_is_valid_op_class(bw_bitmap, preamble_bitmap,
251 o))
252 continue;
253
254 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
255 enum chan_allowed res;
256
257 /* Check for non-continuous jump in channel index
258 * increment.
259 */
260 if (o->op_class >= 128 && o->op_class <= 130 &&
261 ch < 149 && ch + o->inc > 149)
262 ch = 149;
263
264 res = verify_channel(mode, o->op_class, ch, o->bw);
265
266 if (res == ALLOWED) {
267 if (!op) {
268 if (cla == PR_MAX_OP_CLASSES)
269 continue;
270
271 wpa_printf(MSG_DEBUG,
272 "PR: Add operating class: %u (EDCA)",
273 o->op_class);
274 op = &chan->op_class[cla];
275 cla++;
276 op->op_class = o->op_class;
277 }
278 if (op->channels == PR_MAX_OP_CLASS_CHANNELS)
279 continue;
280 op->channel[op->channels] = ch;
281 op->channels++;
282 }
283 }
284
285 if (op)
286 wpa_hexdump(MSG_DEBUG, "PR: Channels (EDCA)",
287 op->channel, op->channels);
288 }
289
290 chan->op_classes = cla;
291 }
292
293
294 static void
wpas_pr_setup_ntb_channels(struct wpa_supplicant * wpa_s,struct pr_channels * chan,u32 bw_bitmap,u32 preamble_bitmap,bool allow_6ghz)295 wpas_pr_setup_ntb_channels(struct wpa_supplicant *wpa_s,
296 struct pr_channels *chan,
297 u32 bw_bitmap, u32 preamble_bitmap,
298 bool allow_6ghz)
299 {
300 int cla = 0, i;
301 struct hostapd_hw_modes *mode;
302
303 for (i = 0; global_op_class[i].op_class; i++) {
304 unsigned int ch;
305 struct pr_op_class *op = NULL;
306 const struct oper_class_map *o = &global_op_class[i];
307
308 mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode,
309 is_6ghz_op_class(o->op_class));
310 if (!mode || (!allow_6ghz && is_6ghz_op_class(o->op_class)) ||
311 !wpas_pr_ntb_is_valid_op_class(bw_bitmap, preamble_bitmap,
312 o))
313 continue;
314
315 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
316 enum chan_allowed res;
317
318 /* Check for non-continuous jump in channel index
319 * increment.
320 */
321 if (o->op_class >= 128 && o->op_class <= 130 &&
322 ch < 149 && ch + o->inc > 149)
323 ch = 149;
324
325 res = verify_channel(mode, o->op_class, ch, o->bw);
326
327 if (res == ALLOWED) {
328 if (!op) {
329 if (cla == PR_MAX_OP_CLASSES)
330 continue;
331 wpa_printf(MSG_DEBUG,
332 "PR: Add operating class: %u (NTB)",
333 o->op_class);
334 op = &chan->op_class[cla];
335 cla++;
336 op->op_class = o->op_class;
337 }
338 if (op->channels == PR_MAX_OP_CLASS_CHANNELS)
339 continue;
340 op->channel[op->channels] = ch;
341 op->channels++;
342 }
343 }
344 if (op) {
345 wpa_hexdump(MSG_DEBUG, "PR: Channels (NTB)",
346 op->channel, op->channels);
347 }
348 }
349
350 chan->op_classes = cla;
351 }
352
353
wpas_pr_pasn_send_mgmt(void * ctx,const u8 * data,size_t data_len,int noack,unsigned int freq,unsigned int wait)354 static int wpas_pr_pasn_send_mgmt(void *ctx, const u8 *data, size_t data_len,
355 int noack, unsigned int freq,
356 unsigned int wait)
357 {
358 struct wpa_supplicant *wpa_s = ctx;
359
360 return wpa_drv_send_mlme(wpa_s, data, data_len, noack, freq, wait);
361 }
362
363
wpas_pr_device_found(void * ctx,const struct pr_device * dev)364 static void wpas_pr_device_found(void *ctx, const struct pr_device *dev)
365 {
366 struct wpa_supplicant *wpa_s = ctx;
367
368 wpas_notify_pr_device_found(wpa_s, dev);
369 }
370
371
wpas_pr_pasn_negotiation_started(void * ctx,const u8 * peer_addr,u8 role,u8 protocol_type)372 static void wpas_pr_pasn_negotiation_started(void *ctx, const u8 *peer_addr,
373 u8 role, u8 protocol_type)
374 {
375 struct wpa_supplicant *wpa_s = ctx;
376
377 wpas_notify_pr_negotiation_started(wpa_s, peer_addr, role,
378 protocol_type);
379 }
380
381
wpas_pr_pasn_result(void * ctx,u8 role,u8 protocol_type,u8 op_class,u8 op_channel,const char * country)382 static void wpas_pr_pasn_result(void *ctx, u8 role, u8 protocol_type,
383 u8 op_class, u8 op_channel, const char *country)
384 {
385 struct wpa_supplicant *wpa_s = ctx;
386
387 wpas_notify_pr_pasn_result(wpa_s, role, protocol_type, op_class,
388 op_channel, country);
389 }
390
391
wpas_pr_clear_ranging_params(struct pr_data * pr)392 static void wpas_pr_clear_ranging_params(struct pr_data *pr)
393 {
394 if (pr) {
395 os_free(pr->pr_pasn_params);
396 pr->pr_pasn_params = NULL;
397 pr->ranging_final_received = false;
398 }
399 }
400
401
wpas_pr_ranging_session_timeout(void * eloop_ctx,void * timeout_ctx)402 static void wpas_pr_ranging_session_timeout(void *eloop_ctx, void *timeout_ctx)
403 {
404 struct wpa_supplicant *wpa_s = eloop_ctx;
405 struct pr_data *pr = wpa_s->global->pr;
406
407 wpa_printf(MSG_DEBUG, "PR: Ranging session timeout - cleaning up");
408
409 /* Stop peer measurement and cleanup ranging socket */
410 wpa_drv_stop_peer_measurement(wpa_s);
411
412 /* Free ranging params */
413 wpas_pr_clear_ranging_params(pr);
414
415 wpas_pr_pd_stop(wpa_s);
416 wpas_notify_pr_ranging_terminated(wpa_s, PR_SESSION_END_TIMEOUT);
417 }
418
419
420 /**
421 * wpas_pr_trigger_ranging - Trigger FTM ranging after successful PASN auth
422 */
wpas_pr_trigger_ranging(struct wpa_supplicant * wpa_s,const u8 * peer_addr,int freq,u8 op_class,u8 op_channel,u8 format_bw,u8 protocol_type)423 static int wpas_pr_trigger_ranging(struct wpa_supplicant *wpa_s,
424 const u8 *peer_addr, int freq, u8 op_class,
425 u8 op_channel, u8 format_bw,
426 u8 protocol_type)
427 {
428 struct pr_data *pr = wpa_s->global->pr;
429 struct pr_pasn_ranging_params *params;
430 u16 channel_width = 0;
431 u32 center_freq1 = 0, center_freq2 = 0;
432 int ret;
433
434 if (!pr || !pr->pr_pasn_params) {
435 wpa_printf(MSG_DEBUG,
436 "PR: No ranging params available for " MACSTR,
437 MAC2STR(peer_addr));
438 return -1;
439 }
440
441 params = pr->pr_pasn_params;
442
443 wpa_printf(MSG_DEBUG,
444 "PR: Triggering ranging for " MACSTR " freq=%d ch=%u",
445 MAC2STR(peer_addr), freq, op_channel);
446
447 /* Derive center frequencies and channel width (MHz) from op_class */
448 ret = wpas_pr_op_class_to_chan_params(op_class, op_channel,
449 ¢er_freq1, ¢er_freq2,
450 &channel_width);
451 if (ret < 0) {
452 wpa_printf(MSG_INFO,
453 "PR: Failed to derive channel params for op_class=%u ch=%u",
454 op_class, op_channel);
455 goto fail;
456 }
457
458 /* Populate ranging params */
459 params->ranging_op_class = op_class;
460 params->channel_width = channel_width;
461 params->format_bw = format_bw;
462 params->center_freq1 = center_freq1;
463 params->center_freq2 = center_freq2;
464
465 /* Validate format_bw is within enum limits before setting preamble */
466 if (protocol_type & PR_EDCA_BASED_RANGING) {
467 if (format_bw < EDCA_FORMAT_AND_BW_VHT20 ||
468 format_bw > EDCA_FORMAT_AND_BW_VHT160_SINGLE_LO) {
469 wpa_printf(MSG_INFO,
470 "PR: Invalid EDCA format_bw %u (valid range: %u-%u)",
471 format_bw, EDCA_FORMAT_AND_BW_VHT20,
472 EDCA_FORMAT_AND_BW_VHT160_SINGLE_LO);
473 goto fail;
474 }
475 } else if (protocol_type & (PR_NTB_SECURE_LTF_BASED_RANGING |
476 PR_NTB_OPEN_BASED_RANGING)) {
477 if (format_bw > NTB_FORMAT_AND_BW_HE160_SINGLE_LO) {
478 wpa_printf(MSG_INFO,
479 "PR: Invalid NTB format_bw %u (valid range: 0-%u)",
480 format_bw,
481 NTB_FORMAT_AND_BW_HE160_SINGLE_LO);
482 goto fail;
483 }
484 } else {
485 wpa_printf(MSG_INFO, "PR: Unknown protocol_type %u",
486 protocol_type);
487 goto fail;
488 }
489
490 wpa_printf(MSG_DEBUG,
491 "PR: Ranging params - op_class=%u, ch_width=%u, format_bw=%u, cf1=%u, cf2=%u",
492 params->ranging_op_class, params->channel_width,
493 params->format_bw, params->center_freq1,
494 params->center_freq2);
495
496 /* Call driver operation to start peer measurement */
497 if (wpa_drv_start_peer_measurement(wpa_s, peer_addr, freq, op_channel,
498 channel_width, params) < 0) {
499 wpa_printf(MSG_INFO, "PR: Failed to start peer measurement");
500 goto fail;
501 }
502
503 wpa_printf(MSG_DEBUG, "PR: Successfully triggered ranging measurement");
504
505 /* Start session timeout timer if continuous ranging session time is set
506 */
507 if (params->continuous_ranging_session_time > 0) {
508 unsigned int timeout_sec, timeout_usec;
509
510 wpa_printf(MSG_DEBUG,
511 "PR: Starting ranging session timeout timer for %u ms",
512 params->continuous_ranging_session_time);
513
514 timeout_sec = params->continuous_ranging_session_time / 1000;
515 timeout_usec = (params->continuous_ranging_session_time %
516 1000) * 1000;
517 eloop_cancel_timeout(wpas_pr_ranging_session_timeout,
518 wpa_s, NULL);
519 eloop_register_timeout(timeout_sec, timeout_usec,
520 wpas_pr_ranging_session_timeout,
521 wpa_s, NULL);
522 }
523
524 return 0;
525
526 fail:
527 wpas_pr_clear_ranging_params(pr);
528 return -1;
529 }
530
531
wpas_pr_ranging_params(void * ctx,const u8 * dev_addr,const u8 * peer_addr,u8 ranging_role,u8 protocol_type,u8 op_class,u8 op_channel,u8 self_format_bw,u8 peer_format_bw)532 static void wpas_pr_ranging_params(void *ctx, const u8 *dev_addr,
533 const u8 *peer_addr, u8 ranging_role,
534 u8 protocol_type, u8 op_class, u8 op_channel,
535 u8 self_format_bw, u8 peer_format_bw)
536 {
537 struct wpa_supplicant *wpa_s = ctx;
538 int bw, format_bw, freq;
539
540 bw = op_class_to_bandwidth(op_class);
541 format_bw = self_format_bw < peer_format_bw ?
542 self_format_bw : peer_format_bw;
543 freq = ieee80211_chan_to_freq(NULL, op_class, op_channel);
544
545 wpas_notify_pr_ranging_params(wpa_s, dev_addr, peer_addr, ranging_role,
546 protocol_type, freq, op_channel, bw,
547 format_bw);
548
549 /*
550 * PASN succeeded - cancel the PASN timeout so it does not fire and
551 * prematurely stop the PD wdev while ranging is in progress.
552 * Cleanup happens on COMPLETE event or session timeout.
553 */
554 eloop_cancel_timeout(wpas_pr_pasn_timeout, wpa_s, NULL);
555 wpas_pr_pasn_auth_work_done(wpa_s);
556
557 /* Trigger ranging measurement after successful PASN authentication */
558 if (wpas_pr_trigger_ranging(wpa_s, peer_addr, freq, op_class,
559 op_channel, format_bw, protocol_type) < 0) {
560 wpa_printf(MSG_INFO,
561 "PR: Failed to trigger ranging, stopping PD wdev");
562 wpas_pr_pd_stop(wpa_s);
563 }
564 }
565
566
wpas_pr_pasn_set_keys(void * ctx,const u8 * own_addr,const u8 * peer_addr,int cipher,int akmp,struct wpa_ptk * ptk)567 static int wpas_pr_pasn_set_keys(void *ctx, const u8 *own_addr,
568 const u8 *peer_addr, int cipher, int akmp,
569 struct wpa_ptk *ptk)
570 {
571 struct wpa_supplicant *wpa_s = ctx;
572 struct wpa_driver_set_key_params params;
573
574 wpa_printf(MSG_DEBUG, "PR PASN: Set secure ranging context for " MACSTR,
575 MAC2STR(peer_addr));
576
577 if (!wpa_s->driver->set_key)
578 return -1;
579
580 os_memset(¶ms, 0, sizeof(params));
581 params.ifname = wpa_s->ifname;
582 params.own_addr = own_addr;
583 params.alg = wpa_cipher_to_alg(cipher);
584 params.addr = peer_addr;
585 params.key_idx = 0;
586 params.set_tx = 1;
587 params.key = ptk->tk;
588 params.key_len = ptk->tk_len;
589 params.key_flag = KEY_FLAG_PAIRWISE_RX_TX;
590 params.link_id = -1;
591 params.ltf_keyseed = ptk->ltf_keyseed;
592 params.ltf_keyseed_len = ptk->ltf_keyseed_len;
593
594 if (wpa_s->driver->set_key(wpa_s->drv_priv, ¶ms) < 0) {
595 wpa_printf(MSG_INFO, "PR PASN: Failed to set TK");
596 return -1;
597 }
598
599 return 0;
600 }
601
602
wpas_pr_pasn_clear_keys(void * ctx,const u8 * own_addr,const u8 * peer_addr)603 static void wpas_pr_pasn_clear_keys(void *ctx, const u8 *own_addr,
604 const u8 *peer_addr)
605 {
606 struct wpa_supplicant *wpa_s = ctx;
607 struct wpa_driver_set_key_params params;
608
609 wpa_printf(MSG_DEBUG, "PR PASN: Clear secure ranging context for "
610 MACSTR, MAC2STR(peer_addr));
611
612 if (!wpa_s->driver->set_key)
613 return;
614
615 os_memset(¶ms, 0, sizeof(params));
616 params.ifname = wpa_s->ifname;
617 params.own_addr = own_addr;
618 params.alg = WPA_ALG_NONE;
619 params.addr = peer_addr;
620 params.key_idx = 0;
621 params.link_id = -1;
622
623 if (wpa_s->driver->set_key(wpa_s->drv_priv, ¶ms) < 0)
624 wpa_printf(MSG_INFO, "PR PASN: Failed to clear TK");
625 }
626
627
wpas_pr_usd_elems(struct wpa_supplicant * wpa_s,const u8 * src_addr)628 struct wpabuf * wpas_pr_usd_elems(struct wpa_supplicant *wpa_s,
629 const u8 *src_addr)
630 {
631 if (!wpa_s->global->pr)
632 return NULL;
633
634 return pr_prepare_usd_elems(wpa_s->global->pr, src_addr);
635 }
636
637
wpas_pr_process_usd_elems(struct wpa_supplicant * wpa_s,const u8 * buf,u16 buf_len,const u8 * peer_addr,unsigned int freq)638 void wpas_pr_process_usd_elems(struct wpa_supplicant *wpa_s, const u8 *buf,
639 u16 buf_len, const u8 *peer_addr,
640 unsigned int freq)
641 {
642 struct pr_data *pr = wpa_s->global->pr;
643
644 if (!pr)
645 return;
646 pr_process_usd_elems(pr, buf, buf_len, peer_addr, freq);
647 }
648
649
wpas_pr_init(struct wpa_global * global,struct wpa_supplicant * wpa_s,const struct wpa_driver_capa * capa)650 int wpas_pr_init(struct wpa_global *global, struct wpa_supplicant *wpa_s,
651 const struct wpa_driver_capa *capa)
652 {
653 struct pr_config pr;
654
655 if (global->pr)
656 return 0;
657
658 os_memset(&pr, 0, sizeof(pr));
659
660 os_memcpy(pr.dev_addr, wpa_s->own_addr, ETH_ALEN);
661 pr.cb_ctx = wpa_s;
662 pr.dev_name = wpa_s->conf->device_name;
663 pr.pasn_type = wpa_s->conf->pr_pasn_type ?
664 wpa_s->conf->pr_pasn_type :
665 (int) (PR_PASN_DH19_UNAUTH | PR_PASN_DH19_AUTH);
666 pr.preferred_ranging_role = wpa_s->conf->pr_preferred_role;
667
668 pr.edca_format_and_bw =
669 wpas_pr_best_edca_format_bw(capa->pd_bandwidths,
670 capa->pd_preambles);
671 pr.edca_ista_support = capa->ista.support_edca &&
672 capa->asap_support &&
673 pr.edca_format_and_bw != EDCA_FORMAT_AND_BW_INVALID;
674 pr.edca_rsta_support = capa->rsta.support_edca &&
675 capa->asap_support &&
676 pr.edca_format_and_bw != EDCA_FORMAT_AND_BW_INVALID;
677 pr.pd_format_bw_bitmap = capa->pd_bandwidths;
678 pr.pd_preamble_bitmap = capa->pd_preambles;
679 pr.max_rx_antenna = capa->max_rx_antenna;
680 pr.max_tx_antenna = capa->max_tx_antenna;
681
682 wpas_pr_setup_edca_channels(wpa_s, &pr.edca_channels,
683 capa->pd_bandwidths,
684 capa->pd_preambles,
685 pr.support_6ghz);
686 pr.ntb_format_and_bw =
687 wpas_pr_best_ntb_format_bw(capa->pd_bandwidths,
688 capa->pd_preambles);
689 pr.ntb_ista_support = capa->ista.support_ntb &&
690 pr.ntb_format_and_bw != NTB_FORMAT_AND_BW_INVALID;
691 pr.ntb_rsta_support = capa->rsta.support_ntb &&
692 pr.ntb_format_and_bw != NTB_FORMAT_AND_BW_INVALID;
693 pr.max_tx_ltf_repetations = capa->max_tx_ltf_repetations;
694 pr.max_rx_ltf_repetations = capa->max_rx_ltf_repetations;
695 pr.max_tx_ltf_total = capa->max_tx_ltf_total;
696 pr.max_rx_ltf_total = capa->max_rx_ltf_total;
697 pr.max_rx_sts_le_80 = capa->max_rx_sts_le_80;
698 pr.max_rx_sts_gt_80 = capa->max_rx_sts_gt_80;
699 pr.max_tx_sts_le_80 = capa->max_tx_sts_le_80;
700 pr.max_tx_sts_gt_80 = capa->max_tx_sts_gt_80;
701
702 pr.edca_min_ranging_interval = capa->edca_min_ranging_interval;
703 pr.ntb_min_ranging_interval = capa->ntb_min_ranging_interval;
704 pr.concurrent_ista_rsta = capa->concurrent_ista_rsta;
705 pr.pmsr_max_peers = capa->pmsr_max_peers;
706 pr.pr_max_peer_ista_role = capa->ista.max_peers;
707 pr.pr_max_peer_rsta_role = capa->rsta.max_peers;
708 pr.max_ftms_per_burst = capa->max_ftms_per_burst;
709
710 pr.support_6ghz = capa->support_6ghz;
711
712 pr.pasn_send_mgmt = wpas_pr_pasn_send_mgmt;
713 pr.negotiation_started = wpas_pr_pasn_negotiation_started;
714 pr.pasn_result = wpas_pr_pasn_result;
715 pr.get_ranging_params = wpas_pr_ranging_params;
716 pr.set_keys = wpas_pr_pasn_set_keys;
717 pr.device_found = wpas_pr_device_found;
718 pr.clear_keys = wpas_pr_pasn_clear_keys;
719
720 pr.secure_he_ltf = wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_STA;
721
722 wpas_pr_setup_ntb_channels(wpa_s, &pr.ntb_channels,
723 capa->pd_bandwidths, capa->pd_preambles,
724 pr.support_6ghz);
725
726 if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
727 os_memcpy(pr.country, wpa_s->conf->country, 2);
728 pr.country[2] = 0x04;
729 } else {
730 os_memcpy(pr.country, "XX\x04", 3);
731 }
732
733 if (wpa_s->conf->dik &&
734 wpabuf_len(wpa_s->conf->dik) <= DEVICE_IDENTITY_KEY_LEN) {
735 pr.dik_cipher = wpa_s->conf->dik_cipher;
736 pr.dik_len = wpabuf_len(wpa_s->conf->dik);
737 os_memcpy(pr.dik_data, wpabuf_head(wpa_s->conf->dik),
738 pr.dik_len);
739 pr.expiration = 24; /* hours */
740 } else {
741 pr.dik_cipher = DIRA_CIPHER_VERSION_128;
742 pr.dik_len = DEVICE_IDENTITY_KEY_LEN;
743 pr.expiration = 24; /* hours */
744 if (os_get_random(pr.dik_data, pr.dik_len) < 0)
745 return -1;
746
747 wpa_s->conf->dik =
748 wpabuf_alloc_copy(pr.dik_data, pr.dik_len);
749 if (!wpa_s->conf->dik)
750 return -1;
751
752 wpa_s->conf->dik_cipher = pr.dik_cipher;
753
754 wpa_printf(MSG_DEBUG, "PR: PR init new DIRA set");
755
756 if (wpa_s->conf->update_config &&
757 wpa_config_write(wpa_s->confname, wpa_s->conf))
758 wpa_printf(MSG_DEBUG,
759 "PR: Failed to update configuration");
760 }
761
762 global->pr = pr_init(&pr);
763 if (!global->pr) {
764 wpa_printf(MSG_DEBUG, "PR: Failed to init PR");
765 return -1;
766 }
767 global->pr_init_wpa_s = wpa_s;
768
769 return 0;
770 }
771
772
wpas_pr_flush(struct wpa_supplicant * wpa_s)773 void wpas_pr_flush(struct wpa_supplicant *wpa_s)
774 {
775 struct pr_data *pr = wpa_s->global->pr;
776
777 if (pr)
778 pr_flush(pr);
779 }
780
wpas_pr_deinit(struct wpa_supplicant * wpa_s)781 void wpas_pr_deinit(struct wpa_supplicant *wpa_s)
782 {
783 if (wpa_s == wpa_s->global->pr_init_wpa_s) {
784 pr_deinit(wpa_s->global->pr);
785 wpa_s->global->pr = NULL;
786 wpa_s->global->pr_init_wpa_s = NULL;
787 }
788
789 #ifdef CONFIG_PASN
790 eloop_cancel_timeout(wpas_pr_pasn_timeout, wpa_s, NULL);
791 eloop_cancel_timeout(wpas_pr_pasn_roc_total_timeout, wpa_s, NULL);
792 eloop_cancel_timeout(wpas_pr_pasn_auth_retry_timeout, wpa_s, NULL);
793 #endif /* CONFIG_PASN */
794 eloop_cancel_timeout(wpas_pr_ranging_session_timeout, wpa_s, NULL);
795 }
796
797
wpas_pr_pd_stop(struct wpa_supplicant * wpa_s)798 void wpas_pr_pd_stop(struct wpa_supplicant *wpa_s)
799 {
800 struct pr_data *pr = wpa_s->global->pr;
801
802 /* Cancel ranging session timeout and stop peer measurement */
803 eloop_cancel_timeout(wpas_pr_ranging_session_timeout, wpa_s, NULL);
804 wpa_drv_stop_peer_measurement(wpa_s);
805
806 if (is_zero_ether_addr(wpa_s->pd_addr)) {
807 wpa_printf(MSG_DEBUG, "PR: pd_stop: no active PD wdev");
808 return;
809 }
810
811 wpa_printf(MSG_DEBUG, "PR: Stopping PD wdev addr=" MACSTR,
812 MAC2STR(wpa_s->pd_addr));
813
814 wpa_drv_pd_stop(wpa_s);
815 os_memset(wpa_s->pd_addr, 0, ETH_ALEN);
816
817 /* Restore dev_addr to station MAC now that PD wdev is gone */
818 if (pr)
819 pr_set_dev_addr(pr, wpa_s->own_addr);
820
821 wpa_printf(MSG_DEBUG, "PR: PD wdev stopped, dev_addr restored to "
822 MACSTR, MAC2STR(wpa_s->own_addr));
823 }
824
825
wpas_pr_update_dev_addr(struct wpa_supplicant * wpa_s)826 void wpas_pr_update_dev_addr(struct wpa_supplicant *wpa_s)
827 {
828 pr_set_dev_addr(wpa_s->global->pr, wpa_s->own_addr);
829 }
830
831
wpas_pr_clear_dev_iks(struct wpa_supplicant * wpa_s)832 void wpas_pr_clear_dev_iks(struct wpa_supplicant *wpa_s)
833 {
834 struct pr_data *pr = wpa_s->global->pr;
835
836 if (!pr)
837 return;
838
839 pr_clear_dev_iks(pr);
840 }
841
842
wpas_pr_set_dev_ik(struct wpa_supplicant * wpa_s,const u8 * dik,const char * password,const u8 * pmk,size_t pmk_len,bool own)843 void wpas_pr_set_dev_ik(struct wpa_supplicant *wpa_s, const u8 *dik,
844 const char *password, const u8 *pmk, size_t pmk_len,
845 bool own)
846 {
847 struct pr_data *pr = wpa_s->global->pr;
848
849 if (!pr || !dik)
850 return;
851
852 pr_add_dev_ik(pr, dik, password, pmk, pmk_len, own);
853 }
854
855
wpas_pr_measurement_complete(struct wpa_supplicant * wpa_s,struct peer_measurement_complete * complete)856 void wpas_pr_measurement_complete(struct wpa_supplicant *wpa_s,
857 struct peer_measurement_complete *complete)
858 {
859 struct pr_data *pr = wpa_s->global->pr;
860
861 if (!complete) {
862 wpa_printf(MSG_INFO,
863 "PR: Invalid measurement complete event");
864 return;
865 }
866
867 wpa_printf(MSG_DEBUG,
868 "PR: Peer measurement complete cookie=%llu",
869 (unsigned long long) complete->cookie);
870
871 /* Validate cookie if we have a pending ranging request */
872 if (pr && pr->pr_pasn_params && complete->cookie != 0 &&
873 pr->pr_pasn_params->cookie != complete->cookie) {
874 wpa_printf(MSG_INFO,
875 "PR: Complete cookie mismatch - expected %llu, got %llu. Ignoring.",
876 (unsigned long long) pr->pr_pasn_params->cookie,
877 (unsigned long long) complete->cookie);
878 return;
879 }
880
881 wpas_notify_pr_ranging_complete(wpa_s, complete->cookie);
882 wpas_pr_clear_ranging_params(pr);
883 wpas_pr_pd_stop(wpa_s);
884 wpas_notify_pr_ranging_terminated(wpa_s,
885 PR_SESSION_END_PEER_COMPLETE);
886 }
887
888
wpas_pr_measurement_result(struct wpa_supplicant * wpa_s,struct peer_measurement_result * result)889 void wpas_pr_measurement_result(struct wpa_supplicant *wpa_s,
890 struct peer_measurement_result *result)
891 {
892 struct pr_data *pr = wpa_s->global->pr;
893
894 if (!result) {
895 wpa_printf(MSG_INFO, "PR: Invalid measurement result");
896 return;
897 }
898
899 /* Drop results after final has been received */
900 if (pr && pr->ranging_final_received) {
901 wpa_printf(MSG_DEBUG,
902 "PR: Ignoring result after final for " MACSTR,
903 MAC2STR(result->addr));
904 return;
905 }
906
907 /* Validate cookie if we have a pending ranging request */
908 if (pr && pr->pr_pasn_params && result->cookie != 0 &&
909 pr->pr_pasn_params->cookie != result->cookie) {
910 wpa_printf(MSG_INFO,
911 "PR: Cookie mismatch - expected %llu, got %llu. Ignoring result.",
912 (unsigned long long) pr->pr_pasn_params->cookie,
913 (unsigned long long) result->cookie);
914 return;
915 }
916
917 /* Forward result to upper layer - includes failures and final */
918 if (result->ftm.has_data || result->ftm.fail)
919 wpas_notify_pr_measurement_result(wpa_s, result);
920
921 /* After final result, mark session done - no more results accepted */
922 if (result->final) {
923 wpa_printf(MSG_DEBUG,
924 "PR: Final result received for " MACSTR
925 " - no further results will be processed",
926 MAC2STR(result->addr));
927 if (pr)
928 pr->ranging_final_received = true;
929 }
930 }
931
932
933 #ifdef CONFIG_PASN
934
wpas_pr_start_pd(struct wpa_supplicant * wpa_s,const u8 * src_addr)935 static int wpas_pr_start_pd(struct wpa_supplicant *wpa_s, const u8 *src_addr)
936 {
937 u8 pd_addr[ETH_ALEN];
938
939 if (!src_addr || is_zero_ether_addr(src_addr)) {
940 wpa_printf(MSG_INFO, "PR: Invalid MAC address for PD wdev");
941 return -1;
942 }
943
944 if (!is_zero_ether_addr(wpa_s->pd_addr)) {
945 wpa_printf(MSG_INFO, "PR: PD wdev already active addr=" MACSTR,
946 MAC2STR(wpa_s->pd_addr));
947 return -1;
948 }
949
950 wpa_printf(MSG_DEBUG, "PR: Creating PD wdev with MAC address " MACSTR,
951 MAC2STR(src_addr));
952
953 os_memset(pd_addr, 0, ETH_ALEN);
954 if (wpa_drv_pd_start(wpa_s, src_addr, pd_addr) < 0) {
955 wpa_printf(MSG_ERROR, "PR: Failed to create PD wdev");
956 return -1;
957 }
958
959 os_memcpy(wpa_s->pd_addr, pd_addr, ETH_ALEN);
960 pr_set_dev_addr(wpa_s->global->pr, pd_addr);
961
962 wpa_printf(MSG_DEBUG, "PR: PD wdev created addr=" MACSTR,
963 MAC2STR(pd_addr));
964 return 0;
965 }
966
967
968 struct wpa_pr_pasn_auth_work {
969 u8 peer_addr[ETH_ALEN];
970 u8 auth_mode;
971 int freq;
972 enum pr_pasn_role role;
973 u8 ranging_role;
974 u8 ranging_type;
975 u8 *ssid;
976 size_t ssid_len;
977 u8 bssid[ETH_ALEN];
978 int forced_pr_freq;
979 };
980
981
982 struct wpa_pr_pasn_roc_work {
983 unsigned int freq;
984 u8 src_addr[ETH_ALEN];
985 };
986
987
wpas_pr_pasn_free_auth_work(struct wpa_pr_pasn_auth_work * awork)988 static void wpas_pr_pasn_free_auth_work(struct wpa_pr_pasn_auth_work *awork)
989 {
990 if (!awork)
991 return;
992 os_free(awork->ssid);
993 os_free(awork);
994 }
995
996
wpas_pr_pasn_cancel_auth_work(struct wpa_supplicant * wpa_s)997 static void wpas_pr_pasn_cancel_auth_work(struct wpa_supplicant *wpa_s)
998 {
999 wpa_printf(MSG_DEBUG, "PR PASN: Cancel pr-pasn-start-auth work");
1000
1001 /* Remove pending/started work */
1002 radio_remove_works(wpa_s, "pr-pasn-start-auth", 0);
1003 }
1004
1005
1006 /**
1007 * wpas_pr_pasn_auth_work_done - Release PASN auth radio work
1008 */
wpas_pr_pasn_auth_work_done(struct wpa_supplicant * wpa_s)1009 static void wpas_pr_pasn_auth_work_done(struct wpa_supplicant *wpa_s)
1010 {
1011 struct wpa_pr_pasn_auth_work *awork;
1012
1013 if (!wpa_s->pr_pasn_auth_work)
1014 return;
1015
1016 awork = wpa_s->pr_pasn_auth_work->ctx;
1017 wpas_pr_pasn_free_auth_work(awork);
1018 wpa_s->pr_pasn_auth_work->ctx = NULL;
1019 radio_work_done(wpa_s->pr_pasn_auth_work);
1020 wpa_s->pr_pasn_auth_work = NULL;
1021 eloop_cancel_timeout(wpas_pr_pasn_auth_retry_timeout, wpa_s, NULL);
1022 }
1023
1024
1025 /**
1026 * wpas_pr_pasn_roc_work_done - Idempotent helper to complete ROC radio work
1027 */
wpas_pr_pasn_roc_work_done(struct wpa_supplicant * wpa_s)1028 static void wpas_pr_pasn_roc_work_done(struct wpa_supplicant *wpa_s)
1029 {
1030 struct wpa_pr_pasn_roc_work *rwork;
1031
1032 if (!wpa_s->pr_roc_work)
1033 return;
1034
1035 rwork = wpa_s->pr_roc_work->ctx;
1036 os_free(rwork);
1037 wpa_s->pr_roc_work->ctx = NULL;
1038 radio_work_done(wpa_s->pr_roc_work);
1039 wpa_s->pr_roc_work = NULL;
1040 }
1041
1042
1043 /**
1044 * wpas_pr_cancel_roc - Stop all responder ROC activity, both active and queued
1045 *
1046 * Cancels any in-progress driver ROC, releases the active radio work item,
1047 * and removes any pending pr-pasn-roc work items that have not yet started.
1048 * Safe to call when no ROC is active; all sub-operations are idempotent.
1049 * Must NOT be called from within a pr-pasn-roc radio work callback (deinit
1050 * path) as that would cause re-entrant radio_remove_works() ->
1051 * radio_work_free().
1052 */
wpas_pr_cancel_roc(struct wpa_supplicant * wpa_s)1053 static void wpas_pr_cancel_roc(struct wpa_supplicant *wpa_s)
1054 {
1055 wpa_drv_cancel_remain_on_channel(wpa_s);
1056 wpa_s->off_channel_freq = 0;
1057 wpa_s->roc_waiting_drv_freq = 0;
1058 wpas_pr_pasn_roc_work_done(wpa_s);
1059 radio_remove_works(wpa_s, "pr-pasn-roc", 0);
1060 }
1061
1062
1063 /**
1064 * wpas_pr_pasn_abort_responder - Cancel the responder PASN session and clean
1065 * up all associated state. Safe to call from any responder error path; calling
1066 * eloop_cancel_timeout() on an already-expired timer is a no-op.
1067 */
wpas_pr_pasn_abort_responder(struct wpa_supplicant * wpa_s)1068 static void wpas_pr_pasn_abort_responder(struct wpa_supplicant *wpa_s)
1069 {
1070 eloop_cancel_timeout(wpas_pr_pasn_roc_total_timeout, wpa_s, NULL);
1071 wpa_s->pr_responder_mode = false;
1072 os_memset(wpa_s->pr_responder_src_addr, 0, ETH_ALEN);
1073 wpas_pr_clear_ranging_params(wpa_s->global->pr);
1074 }
1075
1076
1077 /**
1078 * wpas_pr_pasn_roc_total_timeout - Total ROC budget expiry; stop responder
1079 */
wpas_pr_pasn_roc_total_timeout(void * eloop_ctx,void * timeout_ctx)1080 static void wpas_pr_pasn_roc_total_timeout(void *eloop_ctx, void *timeout_ctx)
1081 {
1082 struct wpa_supplicant *wpa_s = eloop_ctx;
1083
1084 wpa_printf(MSG_DEBUG,
1085 "PR PASN: Total ROC budget expired, stopping responder listen");
1086
1087 wpas_pr_cancel_roc(wpa_s);
1088 wpas_pr_pasn_abort_responder(wpa_s);
1089 wpas_notify_pr_ranging_terminated(wpa_s, PR_SESSION_END_NEG_FAILED);
1090 }
1091
1092
1093 /**
1094 * wpas_pr_pasn_roc_start_cb - Radio work callback to start the responder ROC
1095 */
wpas_pr_pasn_roc_start_cb(struct wpa_radio_work * work,int deinit)1096 static void wpas_pr_pasn_roc_start_cb(struct wpa_radio_work *work, int deinit)
1097 {
1098 struct wpa_supplicant *wpa_s = work->wpa_s;
1099 struct wpa_pr_pasn_roc_work *rwork = work->ctx;
1100 unsigned int chunk_ms;
1101
1102 if (deinit) {
1103 if (work->started) {
1104 /*
1105 * ROC was already started but the work is being
1106 * cancelled (e.g., interface removal). Cancel the
1107 * driver ROC and clear the channel state.
1108 */
1109 wpa_s->pr_roc_work = NULL;
1110 wpa_drv_cancel_remain_on_channel(wpa_s);
1111 wpa_s->off_channel_freq = 0;
1112 wpa_s->roc_waiting_drv_freq = 0;
1113 }
1114 /*
1115 * Clear responder state and cancel the total-budget timer
1116 * regardless of whether the work was started or not - the
1117 * ROC will never fire now.
1118 */
1119 wpas_pr_pasn_abort_responder(wpa_s);
1120 os_free(rwork);
1121 work->ctx = NULL;
1122 return;
1123 }
1124
1125 wpa_s->pr_roc_work = work;
1126
1127 /* Use max_remain_on_chan as per-chunk duration, matching DPP/P2P */
1128 chunk_ms = wpa_s->max_remain_on_chan;
1129
1130 wpa_printf(MSG_DEBUG,
1131 "PR PASN: Starting ROC chunk at freq %u MHz duration %u ms%s",
1132 rwork->freq, chunk_ms,
1133 is_zero_ether_addr(rwork->src_addr) ? "" :
1134 " with MAC filter");
1135
1136 if (wpa_drv_remain_on_channel(wpa_s, rwork->freq, chunk_ms,
1137 is_zero_ether_addr(rwork->src_addr) ?
1138 NULL : rwork->src_addr) < 0) {
1139 wpa_printf(MSG_ERROR,
1140 "PR PASN: Failed to start ROC for responder");
1141 wpas_pr_pasn_roc_work_done(wpa_s);
1142 wpas_pr_pasn_abort_responder(wpa_s);
1143 wpas_notify_pr_ranging_terminated(wpa_s,
1144 PR_SESSION_END_NEG_FAILED);
1145 return;
1146 }
1147
1148 wpa_s->off_channel_freq = 0;
1149 wpa_s->roc_waiting_drv_freq = rwork->freq;
1150 }
1151
1152
1153 /**
1154 * wpas_pr_schedule_responder_roc - Queue next ROC chunk for the responder
1155 */
wpas_pr_schedule_responder_roc(struct wpa_supplicant * wpa_s,unsigned int freq)1156 static void wpas_pr_schedule_responder_roc(struct wpa_supplicant *wpa_s,
1157 unsigned int freq)
1158 {
1159 struct wpa_pr_pasn_roc_work *rwork;
1160
1161 rwork = os_zalloc(sizeof(*rwork));
1162 if (!rwork) {
1163 wpa_printf(MSG_INFO, "PR PASN: OOM restarting ROC");
1164 goto fail;
1165 }
1166 rwork->freq = freq;
1167
1168 if (wpa_s->pr_responder_mode &&
1169 !is_zero_ether_addr(wpa_s->pr_responder_src_addr))
1170 os_memcpy(rwork->src_addr, wpa_s->pr_responder_src_addr,
1171 ETH_ALEN);
1172
1173 if (!radio_add_work(wpa_s, freq, "pr-pasn-roc", 0,
1174 wpas_pr_pasn_roc_start_cb, rwork)) {
1175 wpa_printf(MSG_INFO, "PR PASN: Failed to reschedule ROC");
1176 os_free(rwork);
1177 goto fail;
1178 }
1179 return;
1180
1181 fail:
1182 wpas_pr_pasn_abort_responder(wpa_s);
1183 }
1184
1185
1186 /**
1187 * wpas_pr_cancel_remain_on_channel_cb - ROC cancel/expiry callback for PR
1188 */
wpas_pr_cancel_remain_on_channel_cb(struct wpa_supplicant * wpa_s,unsigned int freq)1189 void wpas_pr_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
1190 unsigned int freq)
1191 {
1192 wpa_printf(MSG_DEBUG, "PR PASN: Remain on channel cancel for %u MHz",
1193 freq);
1194
1195 if (!wpa_s->pr_roc_work)
1196 return;
1197
1198 wpas_pr_pasn_roc_work_done(wpa_s);
1199
1200 if (wpa_s->pr_responder_mode) {
1201 /* Total-budget timer still live — restart another chunk */
1202 wpa_printf(MSG_DEBUG,
1203 "PR PASN: ROC chunk expired, restarting for next chunk");
1204 wpas_pr_schedule_responder_roc(wpa_s, freq);
1205 return;
1206 }
1207
1208 wpa_printf(MSG_DEBUG,
1209 "PR PASN: ROC total timeout reached, responder done");
1210 }
1211
1212
wpas_pr_pasn_timeout(void * eloop_ctx,void * timeout_ctx)1213 static void wpas_pr_pasn_timeout(void *eloop_ctx, void *timeout_ctx)
1214 {
1215 struct wpa_supplicant *wpa_s = eloop_ctx;
1216
1217 eloop_cancel_timeout(wpas_pr_pasn_auth_retry_timeout, wpa_s, NULL);
1218
1219 if (wpa_s->pr_pasn_auth_work) {
1220 wpas_pr_pasn_cancel_auth_work(wpa_s);
1221 wpa_s->pr_pasn_auth_work = NULL;
1222 }
1223
1224 /*
1225 * Stop the PD wdev only after radio_work_done() has fully returned.
1226 * Calling wpas_pr_pd_stop() from inside the radio-work deinit callback
1227 * would trigger a re-entrant radio_remove_works() -> radio_work_free()
1228 * on the same work item, causing a use-after-free / SIGSEGV.
1229 */
1230 wpas_pr_pd_stop(wpa_s);
1231
1232 wpas_pr_clear_ranging_params(wpa_s->global->pr);
1233
1234 wpa_printf(MSG_DEBUG, "PR: PASN timed out");
1235 wpas_notify_pr_ranging_terminated(wpa_s, PR_SESSION_END_NEG_FAILED);
1236 }
1237
1238
wpas_pr_pasn_auth_start_cb(struct wpa_radio_work * work,int deinit)1239 static void wpas_pr_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit)
1240 {
1241 int ret;
1242 struct wpa_supplicant *wpa_s = work->wpa_s;
1243 struct wpa_pr_pasn_auth_work *awork = work->ctx;
1244 struct pr_data *pr = wpa_s->global->pr;
1245 const u8 *peer_addr = NULL;
1246
1247 if (deinit) {
1248 if (!work->started)
1249 eloop_cancel_timeout(wpas_pr_pasn_timeout, wpa_s, NULL);
1250
1251 wpas_pr_pasn_free_auth_work(awork);
1252 work->ctx = NULL;
1253 return;
1254 }
1255
1256 if (!is_zero_ether_addr(awork->peer_addr))
1257 peer_addr = awork->peer_addr;
1258
1259 ret = pr_initiate_pasn_auth(pr, peer_addr, awork->freq,
1260 awork->auth_mode, awork->ranging_role,
1261 awork->ranging_type, awork->forced_pr_freq);
1262 if (ret) {
1263 wpa_printf(MSG_DEBUG,
1264 "PR PASN: Failed to start PASN authentication");
1265 goto fail;
1266 }
1267
1268 eloop_cancel_timeout(wpas_pr_pasn_timeout, wpa_s, NULL);
1269 eloop_register_timeout(PR_PASN_AUTH_TIMEOUT, 0, wpas_pr_pasn_timeout,
1270 wpa_s, NULL);
1271 wpa_s->pr_pasn_auth_work = work;
1272 return;
1273
1274 fail:
1275 wpas_pr_pasn_free_auth_work(awork);
1276 work->ctx = NULL;
1277 radio_work_done(work);
1278 /* Stop PD wdev after radio_work_done() to avoid use-after-free */
1279 wpas_pr_pd_stop(wpa_s);
1280 wpas_pr_clear_ranging_params(wpa_s->global->pr);
1281 }
1282
1283
wpas_pr_initiate_pasn_auth(struct wpa_supplicant * wpa_s,const u8 * peer_addr,int freq,u8 auth_mode,u8 ranging_role,u8 ranging_type,int forced_pr_freq,const u8 * src_addr,enum pr_pasn_role pasn_role)1284 int wpas_pr_initiate_pasn_auth(struct wpa_supplicant *wpa_s,
1285 const u8 *peer_addr, int freq, u8 auth_mode,
1286 u8 ranging_role, u8 ranging_type,
1287 int forced_pr_freq, const u8 *src_addr,
1288 enum pr_pasn_role pasn_role)
1289 {
1290 struct wpa_pr_pasn_auth_work *awork;
1291 struct pr_data *pr = wpa_s->global->pr;
1292
1293 /* Add OOB peer if not already in the discovery list */
1294 if (pr && pr_ensure_oob_peer(pr, peer_addr, freq) < 0)
1295 return -1;
1296
1297 if (pasn_role == PR_ROLE_PASN_RESPONDER) {
1298 struct wpa_pr_pasn_roc_work *rwork;
1299 unsigned int roc_time_ms = PR_PASN_RESPONDER_ROC_DURATION;
1300 bool has_src_addr = src_addr && !is_zero_ether_addr(src_addr);
1301
1302 wpa_printf(MSG_DEBUG,
1303 "PR PASN: Scheduling ROC at freq %d for responder role%s",
1304 freq, has_src_addr ? " with custom MAC" : "");
1305
1306 rwork = os_zalloc(sizeof(*rwork));
1307 if (!rwork)
1308 return -1;
1309
1310 rwork->freq = freq;
1311 if (has_src_addr)
1312 os_memcpy(rwork->src_addr, src_addr, ETH_ALEN);
1313 /* else rwork->src_addr stays all-zeros (no MAC filter on ROC)
1314 */
1315
1316 /*
1317 * Store state so wpas_pr_pasn_auth_rx() can create the PD
1318 * interface when M1 arrives. When no custom MAC address is
1319 * given the PD wdev is skipped and the existing interface is
1320 * used.
1321 */
1322 wpa_s->pr_responder_mode = true;
1323 if (has_src_addr)
1324 os_memcpy(wpa_s->pr_responder_src_addr, src_addr,
1325 ETH_ALEN);
1326 /* else pr_responder_src_addr stays all-zeros */
1327
1328 if (!radio_add_work(wpa_s, freq, "pr-pasn-roc", 0,
1329 wpas_pr_pasn_roc_start_cb, rwork)) {
1330 wpa_printf(MSG_INFO,
1331 "PR PASN: Failed to schedule ROC for responder");
1332 os_free(rwork);
1333 wpa_s->pr_responder_mode = false;
1334 os_memset(wpa_s->pr_responder_src_addr, 0, ETH_ALEN);
1335 return -1;
1336 }
1337
1338 /*
1339 * Register the total-budget timer. When it fires it clears
1340 * pr_responder_mode so the cancel callback stops restarting
1341 * chunks. Defaults to PR_PASN_RESPONDER_ROC_DURATION;
1342 * overridden by continuous_ranging_session_time when non-zero.
1343 */
1344 if (pr && pr->pr_pasn_params &&
1345 pr->pr_pasn_params->continuous_ranging_session_time > 0)
1346 roc_time_ms = pr->pr_pasn_params->continuous_ranging_session_time;
1347
1348 eloop_register_timeout(roc_time_ms / 1000,
1349 (roc_time_ms % 1000) * 1000,
1350 wpas_pr_pasn_roc_total_timeout,
1351 wpa_s, NULL);
1352 return 0;
1353 }
1354
1355 /*
1356 * PASN initiator role: create the PD wdev if src_addr is provided,
1357 * then queue the radio work to send M1.
1358 */
1359 if (src_addr && !is_zero_ether_addr(src_addr)) {
1360 if (wpas_pr_start_pd(wpa_s, src_addr) < 0) {
1361 wpa_printf(MSG_INFO,
1362 "PR PASN: Failed to create PD wdev");
1363 return -1;
1364 }
1365 }
1366
1367 wpas_pr_pasn_cancel_auth_work(wpa_s);
1368 wpa_s->pr_pasn_auth_work = NULL;
1369
1370 awork = os_zalloc(sizeof(*awork));
1371 if (!awork) {
1372 wpas_pr_pd_stop(wpa_s);
1373 return -1;
1374 }
1375
1376 awork->freq = freq;
1377 os_memcpy(awork->peer_addr, peer_addr, ETH_ALEN);
1378 awork->ranging_role = ranging_role;
1379 awork->ranging_type = ranging_type;
1380 awork->auth_mode = auth_mode;
1381 awork->forced_pr_freq = forced_pr_freq;
1382
1383 if (!radio_add_work(wpa_s, freq, "pr-pasn-start-auth", 1,
1384 wpas_pr_pasn_auth_start_cb, awork)) {
1385 wpas_pr_pasn_free_auth_work(awork);
1386 wpas_pr_pd_stop(wpa_s);
1387 return -1;
1388 }
1389
1390 wpa_printf(MSG_DEBUG,
1391 "PR PASN: Authentication work successfully added");
1392 return 0;
1393 }
1394
1395
1396 /**
1397 * wpas_pr_validate_ranging_request - Validate PR ranging request parameters
1398 */
1399 static int
wpas_pr_validate_ranging_request(struct wpa_supplicant * wpa_s,struct pr_pasn_ranging_params * pr_pasn_params)1400 wpas_pr_validate_ranging_request(struct wpa_supplicant *wpa_s,
1401 struct pr_pasn_ranging_params *pr_pasn_params)
1402 {
1403 struct pr_data *pr = wpa_s->global->pr;
1404 struct pr_config *cfg;
1405 bool is_edca, is_ntb, is_ista;
1406
1407 if (!pr || !pr->cfg) {
1408 wpa_printf(MSG_INFO, "PR: PR not initialized");
1409 return -1;
1410 }
1411
1412 cfg = pr->cfg;
1413
1414 /* Peer address must not be all-zeros */
1415 if (is_zero_ether_addr(pr_pasn_params->peer_addr)) {
1416 wpa_printf(MSG_INFO, "PR: Invalid peer address (all zeros)");
1417 return -1;
1418 }
1419
1420 /* Frequency must be set */
1421 if (!pr_pasn_params->freq) {
1422 wpa_printf(MSG_INFO, "PR: Invalid frequency (zero)");
1423 return -1;
1424 }
1425
1426 /* ranging_type must have at least one valid bit and no unknown bits */
1427 if (!pr_pasn_params->ranging_type ||
1428 (pr_pasn_params->ranging_type &
1429 ~(PR_EDCA_BASED_RANGING | PR_NTB_SECURE_LTF_BASED_RANGING |
1430 PR_NTB_OPEN_BASED_RANGING))) {
1431 wpa_printf(MSG_INFO, "PR: Invalid ranging_type=0x%x",
1432 pr_pasn_params->ranging_type);
1433 return -1;
1434 }
1435
1436 /* ranging_role must have at least one valid bit and no unknown bits */
1437 if (!pr_pasn_params->ranging_role ||
1438 (pr_pasn_params->ranging_role &
1439 ~(PR_ISTA_SUPPORT | PR_RSTA_SUPPORT))) {
1440 wpa_printf(MSG_INFO, "PR: Invalid ranging_role=0x%x",
1441 pr_pasn_params->ranging_role);
1442 return -1;
1443 }
1444
1445 is_edca = pr_pasn_params->ranging_type & PR_EDCA_BASED_RANGING;
1446 is_ntb = pr_pasn_params->ranging_type &
1447 (PR_NTB_SECURE_LTF_BASED_RANGING |
1448 PR_NTB_OPEN_BASED_RANGING);
1449 is_ista = pr_pasn_params->ranging_role & PR_ISTA_SUPPORT;
1450
1451 /* Validate ranging type against device capabilities */
1452 if (is_edca) {
1453 if (is_ista && !cfg->edca_ista_support) {
1454 wpa_printf(MSG_INFO,
1455 "PR: EDCA ISTA ranging not supported by device");
1456 return -1;
1457 }
1458 if (!is_ista && !cfg->edca_rsta_support) {
1459 wpa_printf(MSG_INFO,
1460 "PR: EDCA RSTA ranging not supported by device");
1461 return -1;
1462 }
1463 }
1464
1465 if (is_ntb) {
1466 if (is_ista && !cfg->ntb_ista_support) {
1467 wpa_printf(MSG_INFO,
1468 "PR: NTB ISTA ranging not supported by device");
1469 return -1;
1470 }
1471 if (!is_ista && !cfg->ntb_rsta_support) {
1472 wpa_printf(MSG_INFO,
1473 "PR: NTB RSTA ranging not supported by device");
1474 return -1;
1475 }
1476
1477 /* Secure LTF requires explicit device support */
1478 if ((pr_pasn_params->ranging_type &
1479 PR_NTB_SECURE_LTF_BASED_RANGING) &&
1480 !cfg->secure_he_ltf) {
1481 wpa_printf(MSG_INFO,
1482 "PR: Secure HE-LTF NTB ranging not supported by device");
1483 return -1;
1484 }
1485
1486 /* min must not exceed max time between measurements */
1487 if (pr_pasn_params->min_time_between_measurements &&
1488 pr_pasn_params->max_time_between_measurements &&
1489 pr_pasn_params->min_time_between_measurements >
1490 pr_pasn_params->max_time_between_measurements * 100) {
1491 wpa_printf(MSG_INFO,
1492 "PR: min_time_between_measurements=%u > max=%u (units: 100us vs 10ms)",
1493 pr_pasn_params->min_time_between_measurements,
1494 pr_pasn_params->max_time_between_measurements);
1495 return -1;
1496 }
1497 }
1498
1499 /* lmr_feedback is only valid for NTB ranging */
1500 if (pr_pasn_params->lmr_feedback && !is_ntb) {
1501 wpa_printf(MSG_INFO,
1502 "PR: lmr_feedback is only valid for NTB ranging");
1503 return -1;
1504 }
1505
1506 wpa_printf(MSG_DEBUG, "PR: Ranging request validation successful");
1507 return 0;
1508 }
1509
1510
1511 /**
1512 * wpas_pr_pasn_trigger - Entry point to trigger PASN authentication for PR
1513 */
wpas_pr_pasn_trigger(struct wpa_supplicant * wpa_s,struct pr_pasn_ranging_params * pr_pasn_params)1514 int wpas_pr_pasn_trigger(struct wpa_supplicant *wpa_s,
1515 struct pr_pasn_ranging_params *pr_pasn_params)
1516 {
1517 struct pr_data *pr = wpa_s->global->pr;
1518
1519 if (!pr_pasn_params) {
1520 wpa_printf(MSG_DEBUG, "PR PASN: trigger: NULL params");
1521 return -1;
1522 }
1523
1524 if (!pr) {
1525 wpa_printf(MSG_DEBUG, "PR PASN: trigger: PR not initialized");
1526 return -1;
1527 }
1528
1529 if (pr->pr_pasn_params) {
1530 wpa_printf(MSG_DEBUG,
1531 "PR PASN: auth_trigger: Already in progress");
1532 pr_pasn_params->pr_pasn_status = PASN_STATUS_FAILURE;
1533 return -1;
1534 }
1535
1536 /* Validate request before proceeding */
1537 if (wpas_pr_validate_ranging_request(wpa_s, pr_pasn_params) < 0) {
1538 wpa_printf(MSG_DEBUG, "PR PASN: Request validation failed");
1539 pr_pasn_params->pr_pasn_status = PASN_STATUS_FAILURE;
1540 return -1;
1541 }
1542
1543 if (pr_pasn_params->action == PR_PASN_AND_RANGING) {
1544 wpa_printf(MSG_DEBUG,
1545 "PR PASN: Triggering PASN authentication for " MACSTR
1546 " type=%u role=%u mode=%u freq=%d",
1547 MAC2STR(pr_pasn_params->peer_addr),
1548 pr_pasn_params->ranging_type,
1549 pr_pasn_params->ranging_role,
1550 pr_pasn_params->auth_mode,
1551 pr_pasn_params->freq);
1552
1553 /* Allocate and store the params to track the request */
1554 pr->pr_pasn_params = os_zalloc(sizeof(*pr->pr_pasn_params));
1555 if (!pr->pr_pasn_params) {
1556 wpa_printf(MSG_INFO,
1557 "PR PASN: Failed to allocate params");
1558 pr_pasn_params->pr_pasn_status = PASN_STATUS_FAILURE;
1559 return -1;
1560 }
1561
1562 os_memcpy(pr->pr_pasn_params, pr_pasn_params,
1563 sizeof(*pr->pr_pasn_params));
1564
1565 /* Ensure peer device entry exists before setting credentials */
1566 if (pr_pasn_params->pmk_len > 0 ||
1567 pr_pasn_params->password_valid) {
1568 if (pr_ensure_oob_peer(pr, pr_pasn_params->peer_addr,
1569 pr_pasn_params->freq) < 0 ||
1570 pr_set_peer_credentials(
1571 pr, pr_pasn_params->peer_addr,
1572 pr_pasn_params->pmk_len > 0 ?
1573 pr_pasn_params->pmk : NULL,
1574 pr_pasn_params->pmk_len,
1575 pr_pasn_params->password_valid ?
1576 pr_pasn_params->password : NULL) < 0) {
1577 pr_pasn_params->pr_pasn_status =
1578 PASN_STATUS_FAILURE;
1579 wpas_pr_clear_ranging_params(pr);
1580 return -1;
1581 }
1582 }
1583
1584 /* Log EDCA parameters if applicable */
1585 if (pr_pasn_params->ranging_type & PR_EDCA_BASED_RANGING) {
1586 wpa_printf(MSG_DEBUG,
1587 "PR PASN: EDCA params - burst_period=%u num_bursts_exp=%u ftms_per_burst=%u ftmr_retries=%u burst_duration=%u",
1588 pr_pasn_params->burst_period,
1589 pr_pasn_params->num_bursts_exp,
1590 pr_pasn_params->ftms_per_burst,
1591 pr_pasn_params->ftmr_retries,
1592 pr_pasn_params->burst_duration);
1593 }
1594
1595 /* Log NTB parameters if applicable */
1596 if (pr_pasn_params->ranging_type &
1597 (PR_NTB_SECURE_LTF_BASED_RANGING |
1598 PR_NTB_OPEN_BASED_RANGING)) {
1599 wpa_printf(MSG_DEBUG,
1600 "PR PASN: NTB params - min_time=%u max_time=%u aw=%u nominal_time=%u",
1601 pr_pasn_params->min_time_between_measurements,
1602 pr_pasn_params->max_time_between_measurements,
1603 pr_pasn_params->availability_window,
1604 pr_pasn_params->nominal_time);
1605 }
1606
1607 /* Log location request parameters */
1608 if (pr_pasn_params->request_lci ||
1609 pr_pasn_params->request_civicloc) {
1610 wpa_printf(MSG_DEBUG,
1611 "PR PASN: Location requests - LCI=%d CivicLoc=%d",
1612 pr_pasn_params->request_lci,
1613 pr_pasn_params->request_civicloc);
1614 }
1615
1616 /* Initiate PASN authentication for the peer */
1617 if (wpas_pr_initiate_pasn_auth(wpa_s, pr_pasn_params->peer_addr,
1618 pr_pasn_params->freq,
1619 pr_pasn_params->auth_mode,
1620 pr_pasn_params->ranging_role,
1621 pr_pasn_params->ranging_type,
1622 pr_pasn_params->forced_pr_freq,
1623 pr_pasn_params->src_addr,
1624 pr_pasn_params->pasn_role)) {
1625 wpa_printf(MSG_DEBUG,
1626 "PR PASN: Failed to initiate PASN for "
1627 MACSTR,
1628 MAC2STR(pr_pasn_params->peer_addr));
1629 pr_pasn_params->pr_pasn_status = PASN_STATUS_FAILURE;
1630 wpas_pr_clear_ranging_params(pr);
1631 return -1;
1632 }
1633 return 0;
1634 } else {
1635 wpa_printf(MSG_INFO,
1636 "PR PASN: Unsupported action %u, ignoring request",
1637 pr_pasn_params->action);
1638 pr_pasn_params->pr_pasn_status = PASN_STATUS_FAILURE;
1639 return -1;
1640 }
1641 }
1642
1643
wpas_pr_pasn_auth_tx_status(struct wpa_supplicant * wpa_s,const u8 * data,size_t data_len,bool acked)1644 int wpas_pr_pasn_auth_tx_status(struct wpa_supplicant *wpa_s, const u8 *data,
1645 size_t data_len, bool acked)
1646 {
1647 struct pr_data *pr = wpa_s->global->pr;
1648 int ret;
1649
1650 if (!wpa_s->pr_pasn_auth_work && is_zero_ether_addr(wpa_s->pd_addr))
1651 return -1;
1652
1653 ret = pr_pasn_auth_tx_status(pr, data, data_len, acked);
1654 if (ret == 2) {
1655 eloop_cancel_timeout(wpas_pr_pasn_auth_retry_timeout, wpa_s,
1656 NULL);
1657 eloop_register_timeout(0,
1658 PR_PASN_AUTH1_RETRY_INTERVAL_MS * 1000,
1659 wpas_pr_pasn_auth_retry_timeout,
1660 wpa_s, NULL);
1661 return 0;
1662 }
1663
1664 return ret;
1665 }
1666
1667
wpas_pr_pasn_auth_retry_timeout(void * eloop_ctx,void * timeout_ctx)1668 static void wpas_pr_pasn_auth_retry_timeout(void *eloop_ctx, void *timeout_ctx)
1669 {
1670 struct wpa_supplicant *wpa_s = eloop_ctx;
1671 struct pr_data *pr = wpa_s->global->pr;
1672
1673 if (!pr || !pr->pr_pasn_params)
1674 return;
1675
1676 pr_pasn_auth_retransmit(pr, pr->pr_pasn_params->peer_addr);
1677 }
1678
1679
wpas_pr_check_pd_wdev_create(struct wpa_supplicant * wpa_s)1680 static int wpas_pr_check_pd_wdev_create(struct wpa_supplicant *wpa_s)
1681 {
1682 if (is_zero_ether_addr(wpa_s->pr_responder_src_addr)) {
1683 wpa_printf(MSG_DEBUG,
1684 "PR PASN: M1 received in responder mode, no custom MAC - using existing interface");
1685 return 0;
1686 }
1687
1688 wpa_printf(MSG_DEBUG,
1689 "PR PASN: M1 received in responder mode, creating PD wdev");
1690
1691 if (wpas_pr_start_pd(wpa_s, wpa_s->pr_responder_src_addr) < 0) {
1692 wpa_printf(MSG_INFO,
1693 "PR PASN: Failed to create PD wdev for responder");
1694 return -1;
1695 }
1696
1697 return 0;
1698 }
1699
1700
wpas_pr_pasn_auth_rx(struct wpa_supplicant * wpa_s,const struct ieee80211_mgmt * mgmt,size_t len,int freq)1701 int wpas_pr_pasn_auth_rx(struct wpa_supplicant *wpa_s,
1702 const struct ieee80211_mgmt *mgmt, size_t len,
1703 int freq)
1704 {
1705 struct pr_data *pr = wpa_s->global->pr;
1706 int ret;
1707
1708 if (!pr)
1709 return -2;
1710
1711 /*
1712 * Responder path: when we are waiting for PASN M1 on the parent
1713 * interface ROC, create the PD wdev on first receipt of Auth1 before
1714 * handing the frame to the common layer.
1715 */
1716 if (wpa_s->pr_responder_mode &&
1717 len >= offsetof(struct ieee80211_mgmt, u.auth.variable)) {
1718 u16 auth_transaction;
1719
1720 auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
1721
1722 if (auth_transaction == WLAN_AUTH_TR_SEQ_PASN_AUTH1) {
1723 if (wpas_pr_check_pd_wdev_create(wpa_s) < 0)
1724 return -1;
1725
1726 /*
1727 * Cancel the total-budget timer first so it does not
1728 * fire after we have already handed off to the PASN
1729 * layer.
1730 */
1731 eloop_cancel_timeout(wpas_pr_pasn_roc_total_timeout,
1732 wpa_s, NULL);
1733
1734 /*
1735 * Cancel ROC on the listening interface; the dedicated
1736 * PR interface (if created) will handle all subsequent
1737 * frames. wpas_pr_cancel_roc() also flushes any pending
1738 * pr-pasn-roc chunks that were queued but not yet
1739 * started (M1 can arrive between two ROC chunks when
1740 * pr_roc_work is already NULL but a next chunk is
1741 * already queued).
1742 */
1743 wpas_pr_cancel_roc(wpa_s);
1744
1745 /* Clear responder mode */
1746 wpa_s->pr_responder_mode = false;
1747 os_memset(wpa_s->pr_responder_src_addr, 0, ETH_ALEN);
1748
1749 wpa_printf(MSG_DEBUG,
1750 "PR PASN: M1 processed, proceeding with PASN");
1751 }
1752 }
1753
1754 ret = pr_pasn_auth_rx(pr, mgmt, len, freq);
1755
1756 if (ret < 0) {
1757 eloop_cancel_timeout(wpas_pr_pasn_timeout, wpa_s, NULL);
1758 wpas_pr_pasn_auth_work_done(wpa_s);
1759 wpas_pr_pd_stop(wpa_s);
1760 wpas_pr_clear_ranging_params(wpa_s->global->pr);
1761 wpas_notify_pr_ranging_terminated(wpa_s,
1762 PR_SESSION_END_NEG_FAILED);
1763 }
1764
1765 return ret;
1766 }
1767
1768
wpas_pr_abort_ranging(struct wpa_supplicant * wpa_s)1769 void wpas_pr_abort_ranging(struct wpa_supplicant *wpa_s)
1770 {
1771 struct pr_data *pr = wpa_s->global->pr;
1772
1773 if (!pr) {
1774 wpa_printf(MSG_DEBUG, "PR: abort_ranging: PR not initialized");
1775 return;
1776 }
1777
1778 /* Check if there's an active ranging session */
1779 if (is_zero_ether_addr(wpa_s->pd_addr) && !pr->pr_pasn_params) {
1780 wpa_printf(MSG_DEBUG,
1781 "PR: abort_ranging: no active ranging session");
1782 return;
1783 }
1784
1785 wpa_printf(MSG_DEBUG, "PR: Aborting ranging session");
1786
1787 /*
1788 * Cancel PASN and ROC in case PD wdev is not yet created
1789 * (PASN still in progress or responder ROC active).
1790 */
1791 wpas_pr_pasn_cancel_auth_work(wpa_s);
1792 wpa_s->pr_pasn_auth_work = NULL;
1793 if (wpa_s->pr_responder_mode) {
1794 wpas_pr_cancel_roc(wpa_s);
1795 wpas_pr_pasn_abort_responder(wpa_s);
1796 }
1797
1798 /* Stop PD wdev and cleanup all ranging resources */
1799 wpas_pr_pd_stop(wpa_s);
1800
1801 eloop_cancel_timeout(wpas_pr_pasn_auth_retry_timeout, wpa_s, NULL);
1802 /* Free ranging params so a new session can be started */
1803 wpas_pr_clear_ranging_params(pr);
1804 wpas_notify_pr_ranging_terminated(wpa_s, PR_SESSION_END_USER_ABORT);
1805 }
1806
1807 #endif /* CONFIG_PASN */
1808