Branch data Line data Source code
1 : : /*
2 : : * wpa_supplicant - P2P
3 : : * Copyright (c) 2009-2010, Atheros Communications
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 "common.h"
12 : : #include "eloop.h"
13 : : #include "common/ieee802_11_common.h"
14 : : #include "common/ieee802_11_defs.h"
15 : : #include "common/wpa_ctrl.h"
16 : : #include "wps/wps_i.h"
17 : : #include "p2p/p2p.h"
18 : : #include "ap/hostapd.h"
19 : : #include "ap/ap_config.h"
20 : : #include "ap/sta_info.h"
21 : : #include "ap/ap_drv_ops.h"
22 : : #include "ap/p2p_hostapd.h"
23 : : #include "eapol_supp/eapol_supp_sm.h"
24 : : #include "rsn_supp/wpa.h"
25 : : #include "wpa_supplicant_i.h"
26 : : #include "driver_i.h"
27 : : #include "ap.h"
28 : : #include "config_ssid.h"
29 : : #include "config.h"
30 : : #include "notify.h"
31 : : #include "scan.h"
32 : : #include "bss.h"
33 : : #include "offchannel.h"
34 : : #include "wps_supplicant.h"
35 : : #include "p2p_supplicant.h"
36 : : #include "wifi_display.h"
37 : :
38 : :
39 : : /*
40 : : * How many times to try to scan to find the GO before giving up on join
41 : : * request.
42 : : */
43 : : #define P2P_MAX_JOIN_SCAN_ATTEMPTS 10
44 : :
45 : : #define P2P_AUTO_PD_SCAN_ATTEMPTS 5
46 : :
47 : : #ifndef P2P_MAX_CLIENT_IDLE
48 : : /*
49 : : * How many seconds to try to reconnect to the GO when connection in P2P client
50 : : * role has been lost.
51 : : */
52 : : #define P2P_MAX_CLIENT_IDLE 10
53 : : #endif /* P2P_MAX_CLIENT_IDLE */
54 : :
55 : : #ifndef P2P_MAX_INITIAL_CONN_WAIT
56 : : /*
57 : : * How many seconds to wait for initial 4-way handshake to get completed after
58 : : * WPS provisioning step.
59 : : */
60 : : #define P2P_MAX_INITIAL_CONN_WAIT 10
61 : : #endif /* P2P_MAX_INITIAL_CONN_WAIT */
62 : :
63 : : #ifndef P2P_MAX_INITIAL_CONN_WAIT_GO
64 : : /*
65 : : * How many seconds to wait for initial 4-way handshake to get completed after
66 : : * WPS provisioning step on the GO. This controls the extra time the P2P
67 : : * operation is considered to be in progress (e.g., to delay other scans) after
68 : : * WPS provisioning has been completed on the GO during group formation.
69 : : */
70 : : #define P2P_MAX_INITIAL_CONN_WAIT_GO 10
71 : : #endif /* P2P_MAX_INITIAL_CONN_WAIT_GO */
72 : :
73 : : #ifndef P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE
74 : : /*
75 : : * How many seconds to wait for initial 4-way handshake to get completed after
76 : : * re-invocation of a persistent group on the GO when the client is expected
77 : : * to connect automatically (no user interaction).
78 : : */
79 : : #define P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE 15
80 : : #endif /* P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE */
81 : :
82 : : #ifndef P2P_CONCURRENT_SEARCH_DELAY
83 : : #define P2P_CONCURRENT_SEARCH_DELAY 500
84 : : #endif /* P2P_CONCURRENT_SEARCH_DELAY */
85 : :
86 : : #define P2P_MGMT_DEVICE_PREFIX "p2p-dev-"
87 : :
88 : : enum p2p_group_removal_reason {
89 : : P2P_GROUP_REMOVAL_UNKNOWN,
90 : : P2P_GROUP_REMOVAL_SILENT,
91 : : P2P_GROUP_REMOVAL_FORMATION_FAILED,
92 : : P2P_GROUP_REMOVAL_REQUESTED,
93 : : P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
94 : : P2P_GROUP_REMOVAL_UNAVAILABLE,
95 : : P2P_GROUP_REMOVAL_GO_ENDING_SESSION,
96 : : P2P_GROUP_REMOVAL_PSK_FAILURE,
97 : : P2P_GROUP_REMOVAL_FREQ_CONFLICT
98 : : };
99 : :
100 : :
101 : : static void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx);
102 : : static struct wpa_supplicant *
103 : : wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
104 : : int go);
105 : : static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s);
106 : : static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq);
107 : : static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx);
108 : : static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
109 : : const u8 *dev_addr, enum p2p_wps_method wps_method,
110 : : int auto_join);
111 : : static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s);
112 : : static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s);
113 : : static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx);
114 : : static void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s);
115 : : static void wpas_p2p_group_formation_timeout(void *eloop_ctx,
116 : : void *timeout_ctx);
117 : : static void wpas_p2p_group_freq_conflict(void *eloop_ctx, void *timeout_ctx);
118 : : static void wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s,
119 : : int group_added);
120 : : static int wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s);
121 : :
122 : :
123 : : /*
124 : : * Get the number of concurrent channels that the HW can operate, but that are
125 : : * currently not in use by any of the wpa_supplicant interfaces.
126 : : */
127 : 40 : static int wpas_p2p_num_unused_channels(struct wpa_supplicant *wpa_s)
128 : : {
129 : : int *freqs;
130 : : int num, unused;
131 : :
132 : 40 : freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
133 [ - + ]: 40 : if (!freqs)
134 : 0 : return -1;
135 : :
136 : 40 : num = get_shared_radio_freqs(wpa_s, freqs,
137 : : wpa_s->num_multichan_concurrent);
138 : 40 : os_free(freqs);
139 : :
140 : 40 : unused = wpa_s->num_multichan_concurrent - num;
141 : 40 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: num_unused_channels: %d", unused);
142 : 40 : return unused;
143 : : }
144 : :
145 : :
146 : : /*
147 : : * Get the frequencies that are currently in use by one or more of the virtual
148 : : * interfaces, and that are also valid for P2P operation.
149 : : */
150 : 32 : static int wpas_p2p_valid_oper_freqs(struct wpa_supplicant *wpa_s,
151 : : int *p2p_freqs, unsigned int len)
152 : : {
153 : : int *freqs;
154 : : unsigned int num, i, j;
155 : :
156 : 32 : freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
157 [ - + ]: 32 : if (!freqs)
158 : 0 : return -1;
159 : :
160 : 32 : num = get_shared_radio_freqs(wpa_s, freqs,
161 : : wpa_s->num_multichan_concurrent);
162 : :
163 : 32 : os_memset(p2p_freqs, 0, sizeof(int) * len);
164 : :
165 [ + + ][ + - ]: 34 : for (i = 0, j = 0; i < num && j < len; i++) {
166 [ + - ]: 2 : if (p2p_supported_freq(wpa_s->global->p2p, freqs[i]))
167 : 2 : p2p_freqs[j++] = freqs[i];
168 : : }
169 : :
170 : 32 : os_free(freqs);
171 : :
172 : 32 : dump_freq_array(wpa_s, "valid for P2P", p2p_freqs, j);
173 : :
174 : 32 : return j;
175 : : }
176 : :
177 : :
178 : 93 : static void wpas_p2p_set_own_freq_preference(struct wpa_supplicant *wpa_s,
179 : : int freq)
180 : : {
181 [ + - ][ - + ]: 93 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
182 : 93 : return;
183 [ - + ][ # # ]: 93 : if (wpa_s->parent->conf->p2p_ignore_shared_freq &&
184 [ # # # # ]: 0 : freq > 0 && wpa_s->num_multichan_concurrent > 1 &&
185 : 0 : wpas_p2p_num_unused_channels(wpa_s) > 0) {
186 : 0 : wpa_printf(MSG_DEBUG, "P2P: Ignore own channel preference %d MHz due to p2p_ignore_shared_freq=1 configuration",
187 : : freq);
188 : 0 : freq = 0;
189 : : }
190 : 93 : p2p_set_own_freq_preference(wpa_s->global->p2p, freq);
191 : : }
192 : :
193 : :
194 : 462 : static void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s,
195 : : struct wpa_scan_results *scan_res)
196 : : {
197 : : size_t i;
198 : :
199 [ + + ]: 462 : if (wpa_s->p2p_scan_work) {
200 : 444 : struct wpa_radio_work *work = wpa_s->p2p_scan_work;
201 : 444 : wpa_s->p2p_scan_work = NULL;
202 : 444 : radio_work_done(work);
203 : : }
204 : :
205 [ + - ][ - + ]: 462 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
206 : 462 : return;
207 : :
208 : 462 : wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS)",
209 : 462 : (int) scan_res->num);
210 : :
211 [ + + ]: 1452 : for (i = 0; i < scan_res->num; i++) {
212 : 990 : struct wpa_scan_res *bss = scan_res->res[i];
213 : : struct os_reltime time_tmp_age, entry_ts;
214 : : const u8 *ies;
215 : : size_t ies_len;
216 : :
217 : 990 : time_tmp_age.sec = bss->age / 1000;
218 : 990 : time_tmp_age.usec = (bss->age % 1000) * 1000;
219 : 990 : os_reltime_sub(&scan_res->fetch_time, &time_tmp_age, &entry_ts);
220 : :
221 : 990 : ies = (const u8 *) (bss + 1);
222 : 990 : ies_len = bss->ie_len;
223 [ + + + + ]: 1553 : if (bss->beacon_ie_len > 0 &&
224 [ + + ]: 752 : !wpa_scan_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) &&
225 : 189 : wpa_scan_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) {
226 : 2 : wpa_printf(MSG_DEBUG, "P2P: Use P2P IE(s) from Beacon frame since no P2P IE(s) in Probe Response frames received for "
227 : 12 : MACSTR, MAC2STR(bss->bssid));
228 : 2 : ies = ies + ies_len;
229 : 2 : ies_len = bss->beacon_ie_len;
230 : : }
231 : :
232 : :
233 [ - + ]: 990 : if (p2p_scan_res_handler(wpa_s->global->p2p, bss->bssid,
234 : : bss->freq, &entry_ts, bss->level,
235 : : ies, ies_len) > 0)
236 : 0 : break;
237 : : }
238 : :
239 : 462 : p2p_scan_res_handled(wpa_s->global->p2p);
240 : : }
241 : :
242 : :
243 : 445 : static void wpas_p2p_trigger_scan_cb(struct wpa_radio_work *work, int deinit)
244 : : {
245 : 445 : struct wpa_supplicant *wpa_s = work->wpa_s;
246 : 445 : struct wpa_driver_scan_params *params = work->ctx;
247 : : int ret;
248 : :
249 [ + + ]: 445 : if (deinit) {
250 : 1 : wpa_scan_free_params(params);
251 : 1 : return;
252 : : }
253 : :
254 : 444 : ret = wpa_drv_scan(wpa_s, params);
255 : 444 : wpa_scan_free_params(params);
256 : 444 : work->ctx = NULL;
257 [ - + ]: 444 : if (ret) {
258 : 0 : radio_work_done(work);
259 : 0 : return;
260 : : }
261 : :
262 : 444 : os_get_reltime(&wpa_s->scan_trigger_time);
263 : 444 : wpa_s->scan_res_handler = wpas_p2p_scan_res_handler;
264 : 444 : wpa_s->own_scan_requested = 1;
265 : 445 : wpa_s->p2p_scan_work = work;
266 : : }
267 : :
268 : :
269 : 448 : static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
270 : : unsigned int num_req_dev_types,
271 : : const u8 *req_dev_types, const u8 *dev_id, u16 pw_id)
272 : : {
273 : 448 : struct wpa_supplicant *wpa_s = ctx;
274 : 448 : struct wpa_driver_scan_params *params = NULL;
275 : : struct wpabuf *wps_ie, *ies;
276 : : size_t ielen;
277 : : u8 *n;
278 : :
279 [ + - ][ - + ]: 448 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
280 : 0 : return -1;
281 : :
282 [ + + ]: 448 : if (wpa_s->p2p_scan_work) {
283 : 3 : wpa_dbg(wpa_s, MSG_INFO, "P2P: Reject scan trigger since one is already pending");
284 : 3 : return -1;
285 : : }
286 : :
287 : 445 : params = os_zalloc(sizeof(*params));
288 [ - + ]: 445 : if (params == NULL)
289 : 0 : return -1;
290 : :
291 : : /* P2P Wildcard SSID */
292 : 445 : params->num_ssids = 1;
293 : 445 : n = os_malloc(P2P_WILDCARD_SSID_LEN);
294 [ - + ]: 445 : if (n == NULL)
295 : 0 : goto fail;
296 : 445 : os_memcpy(n, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN);
297 : 445 : params->ssids[0].ssid = n;
298 : 445 : params->ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
299 : :
300 : 445 : wpa_s->wps->dev.p2p = 1;
301 : 445 : wps_ie = wps_build_probe_req_ie(pw_id, &wpa_s->wps->dev,
302 : 445 : wpa_s->wps->uuid, WPS_REQ_ENROLLEE,
303 : : num_req_dev_types, req_dev_types);
304 [ - + ]: 445 : if (wps_ie == NULL)
305 : 0 : goto fail;
306 : :
307 : 445 : ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
308 : 445 : ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
309 [ - + ]: 445 : if (ies == NULL) {
310 : 0 : wpabuf_free(wps_ie);
311 : 0 : goto fail;
312 : : }
313 : 445 : wpabuf_put_buf(ies, wps_ie);
314 : 445 : wpabuf_free(wps_ie);
315 : :
316 : 445 : p2p_scan_ie(wpa_s->global->p2p, ies, dev_id);
317 : :
318 : 445 : params->p2p_probe = 1;
319 : 445 : n = os_malloc(wpabuf_len(ies));
320 [ - + ]: 445 : if (n == NULL) {
321 : 0 : wpabuf_free(ies);
322 : 0 : goto fail;
323 : : }
324 : 445 : os_memcpy(n, wpabuf_head(ies), wpabuf_len(ies));
325 : 445 : params->extra_ies = n;
326 : 445 : params->extra_ies_len = wpabuf_len(ies);
327 : 445 : wpabuf_free(ies);
328 : :
329 [ + + - - ]: 445 : switch (type) {
330 : : case P2P_SCAN_SOCIAL:
331 : 431 : params->freqs = os_malloc(4 * sizeof(int));
332 [ - + ]: 431 : if (params->freqs == NULL)
333 : 0 : goto fail;
334 : 431 : params->freqs[0] = 2412;
335 : 431 : params->freqs[1] = 2437;
336 : 431 : params->freqs[2] = 2462;
337 : 431 : params->freqs[3] = 0;
338 : 431 : break;
339 : : case P2P_SCAN_FULL:
340 : 14 : break;
341 : : case P2P_SCAN_SOCIAL_PLUS_ONE:
342 : 0 : params->freqs = os_malloc(5 * sizeof(int));
343 [ # # ]: 0 : if (params->freqs == NULL)
344 : 0 : goto fail;
345 : 0 : params->freqs[0] = 2412;
346 : 0 : params->freqs[1] = 2437;
347 : 0 : params->freqs[2] = 2462;
348 : 0 : params->freqs[3] = freq;
349 : 0 : params->freqs[4] = 0;
350 : 0 : break;
351 : : }
352 : :
353 : 445 : radio_remove_unstarted_work(wpa_s, "p2p-scan");
354 [ - + ]: 445 : if (radio_add_work(wpa_s, 0, "p2p-scan", 0, wpas_p2p_trigger_scan_cb,
355 : : params) < 0)
356 : 0 : goto fail;
357 : 445 : return 0;
358 : :
359 : : fail:
360 : 0 : wpa_scan_free_params(params);
361 : 448 : return -1;
362 : : }
363 : :
364 : :
365 : 22 : static enum wpa_driver_if_type wpas_p2p_if_type(int p2p_group_interface)
366 : : {
367 [ - + + - ]: 22 : switch (p2p_group_interface) {
368 : : case P2P_GROUP_INTERFACE_PENDING:
369 : 0 : return WPA_IF_P2P_GROUP;
370 : : case P2P_GROUP_INTERFACE_GO:
371 : 10 : return WPA_IF_P2P_GO;
372 : : case P2P_GROUP_INTERFACE_CLIENT:
373 : 12 : return WPA_IF_P2P_CLIENT;
374 : : }
375 : :
376 : 22 : return WPA_IF_P2P_GROUP;
377 : : }
378 : :
379 : :
380 : 25 : static struct wpa_supplicant * wpas_get_p2p_group(struct wpa_supplicant *wpa_s,
381 : : const u8 *ssid,
382 : : size_t ssid_len, int *go)
383 : : {
384 : : struct wpa_ssid *s;
385 : :
386 [ + + ]: 50 : for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
387 [ + + ]: 50 : for (s = wpa_s->conf->ssid; s; s = s->next) {
388 [ - + ][ # # ]: 25 : if (s->disabled != 0 || !s->p2p_group ||
[ # # ]
389 [ # # ]: 0 : s->ssid_len != ssid_len ||
390 : 0 : os_memcmp(ssid, s->ssid, ssid_len) != 0)
391 : 25 : continue;
392 [ # # ][ # # ]: 0 : if (s->mode == WPAS_MODE_P2P_GO &&
393 : 0 : s != wpa_s->current_ssid)
394 : 0 : continue;
395 [ # # ]: 0 : if (go)
396 : 0 : *go = s->mode == WPAS_MODE_P2P_GO;
397 : 0 : return wpa_s;
398 : : }
399 : : }
400 : :
401 : 25 : return NULL;
402 : : }
403 : :
404 : :
405 : 131 : static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
406 : : enum p2p_group_removal_reason removal_reason)
407 : : {
408 : : struct wpa_ssid *ssid;
409 : : char *gtype;
410 : : const char *reason;
411 : :
412 : 131 : ssid = wpa_s->current_ssid;
413 [ + + ]: 131 : if (ssid == NULL) {
414 : : /*
415 : : * The current SSID was not known, but there may still be a
416 : : * pending P2P group interface waiting for provisioning or a
417 : : * P2P group that is trying to reconnect.
418 : : */
419 : 11 : ssid = wpa_s->conf->ssid;
420 [ - + ]: 11 : while (ssid) {
421 [ # # ][ # # ]: 0 : if (ssid->p2p_group && ssid->disabled != 2)
422 : 0 : break;
423 : 0 : ssid = ssid->next;
424 : : }
425 [ + - ][ + - ]: 11 : if (ssid == NULL &&
426 : 11 : wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE)
427 : : {
428 : 11 : wpa_printf(MSG_ERROR, "P2P: P2P group interface "
429 : : "not found");
430 : 11 : return -1;
431 : : }
432 : : }
433 [ + + ]: 120 : if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO)
434 : 10 : gtype = "GO";
435 [ + + ][ + - ]: 110 : else if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT ||
436 [ + + ]: 98 : (ssid && ssid->mode == WPAS_MODE_INFRA)) {
437 : 62 : wpa_s->reassociate = 0;
438 : 62 : wpa_s->disconnected = 1;
439 : 62 : wpa_supplicant_deauthenticate(wpa_s,
440 : : WLAN_REASON_DEAUTH_LEAVING);
441 : 62 : gtype = "client";
442 : : } else
443 : 48 : gtype = "GO";
444 [ - + ]: 120 : if (wpa_s->cross_connect_in_use) {
445 : 0 : wpa_s->cross_connect_in_use = 0;
446 : 0 : wpa_msg_global(wpa_s->parent, MSG_INFO,
447 : : P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
448 : 0 : wpa_s->ifname, wpa_s->cross_connect_uplink);
449 : : }
450 [ + - - - : 120 : switch (removal_reason) {
+ + - - ]
451 : : case P2P_GROUP_REMOVAL_REQUESTED:
452 : 76 : reason = " reason=REQUESTED";
453 : 76 : break;
454 : : case P2P_GROUP_REMOVAL_FORMATION_FAILED:
455 : 0 : reason = " reason=FORMATION_FAILED";
456 : 0 : break;
457 : : case P2P_GROUP_REMOVAL_IDLE_TIMEOUT:
458 : 0 : reason = " reason=IDLE";
459 : 0 : break;
460 : : case P2P_GROUP_REMOVAL_UNAVAILABLE:
461 : 0 : reason = " reason=UNAVAILABLE";
462 : 0 : break;
463 : : case P2P_GROUP_REMOVAL_GO_ENDING_SESSION:
464 : 42 : reason = " reason=GO_ENDING_SESSION";
465 : 42 : break;
466 : : case P2P_GROUP_REMOVAL_PSK_FAILURE:
467 : 2 : reason = " reason=PSK_FAILURE";
468 : 2 : break;
469 : : case P2P_GROUP_REMOVAL_FREQ_CONFLICT:
470 : 0 : reason = " reason=FREQ_CONFLICT";
471 : 0 : break;
472 : : default:
473 : 0 : reason = "";
474 : 0 : break;
475 : : }
476 [ + - ]: 120 : if (removal_reason != P2P_GROUP_REMOVAL_SILENT) {
477 : 120 : wpa_msg_global(wpa_s->parent, MSG_INFO,
478 : : P2P_EVENT_GROUP_REMOVED "%s %s%s",
479 : 120 : wpa_s->ifname, gtype, reason);
480 : : }
481 : :
482 [ - + ]: 120 : if (eloop_cancel_timeout(wpas_p2p_group_freq_conflict, wpa_s, NULL) > 0)
483 : 0 : wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group freq_conflict timeout");
484 [ + + ]: 120 : if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
485 : 60 : wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");
486 [ + + ]: 120 : if (eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
487 : 120 : wpa_s->parent, NULL) > 0) {
488 : 1 : wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group formation "
489 : : "timeout");
490 : 1 : wpa_s->p2p_in_provisioning = 0;
491 : : }
492 : :
493 : : /*
494 : : * Make sure wait for the first client does not remain active after the
495 : : * group has been removed.
496 : : */
497 : 120 : wpa_s->global->p2p_go_wait_client.sec = 0;
498 : :
499 [ + - ][ + - ]: 120 : if (removal_reason != P2P_GROUP_REMOVAL_SILENT && ssid)
500 : 120 : wpas_notify_p2p_group_removed(wpa_s, ssid, gtype);
501 : :
502 [ + + ]: 120 : if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
503 : : struct wpa_global *global;
504 : : char *ifname;
505 : : enum wpa_driver_if_type type;
506 : 22 : wpa_printf(MSG_DEBUG, "P2P: Remove group interface %s",
507 : 22 : wpa_s->ifname);
508 : 22 : global = wpa_s->global;
509 : 22 : ifname = os_strdup(wpa_s->ifname);
510 : 22 : type = wpas_p2p_if_type(wpa_s->p2p_group_interface);
511 : 22 : wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0);
512 : 22 : wpa_s = global->ifaces;
513 [ + - ][ + - ]: 22 : if (wpa_s && ifname)
514 : 22 : wpa_drv_if_remove(wpa_s, type, ifname);
515 : 22 : os_free(ifname);
516 : 22 : return 1;
517 : : }
518 : :
519 [ + + ]: 98 : if (!wpa_s->p2p_go_group_formation_completed) {
520 : 1 : wpa_s->global->p2p_group_formation = NULL;
521 : 1 : wpa_s->p2p_in_provisioning = 0;
522 : : }
523 : :
524 : 98 : wpa_s->show_group_started = 0;
525 : 98 : os_free(wpa_s->go_params);
526 : 98 : wpa_s->go_params = NULL;
527 : :
528 : 98 : wpa_s->waiting_presence_resp = 0;
529 : :
530 : 98 : wpa_printf(MSG_DEBUG, "P2P: Remove temporary group network");
531 [ + - ][ - + ]: 98 : if (ssid && (ssid->p2p_group ||
[ # # ]
532 [ # # ]: 0 : ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION ||
533 : 98 : (ssid->key_mgmt & WPA_KEY_MGMT_WPS))) {
534 : 98 : int id = ssid->id;
535 [ + + ]: 98 : if (ssid == wpa_s->current_ssid) {
536 : 48 : wpa_sm_set_config(wpa_s->wpa, NULL);
537 : 48 : eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
538 : 48 : wpa_s->current_ssid = NULL;
539 : : }
540 : : /*
541 : : * Networks objects created during any P2P activities are not
542 : : * exposed out as they might/will confuse certain non-P2P aware
543 : : * applications since these network objects won't behave like
544 : : * regular ones.
545 : : *
546 : : * Likewise, we don't send out network removed signals for such
547 : : * network objects.
548 : : */
549 : 98 : wpa_config_remove_network(wpa_s->conf, id);
550 : 98 : wpa_supplicant_clear_status(wpa_s);
551 : 98 : wpa_supplicant_cancel_sched_scan(wpa_s);
552 : : } else {
553 : 0 : wpa_printf(MSG_DEBUG, "P2P: Temporary group network not "
554 : : "found");
555 : : }
556 [ + + ]: 98 : if (wpa_s->ap_iface)
557 : 48 : wpa_supplicant_ap_deinit(wpa_s);
558 : : else
559 : 50 : wpa_drv_deinit_p2p_cli(wpa_s);
560 : :
561 : 131 : return 0;
562 : : }
563 : :
564 : :
565 : 169 : static int wpas_p2p_persistent_group(struct wpa_supplicant *wpa_s,
566 : : u8 *go_dev_addr,
567 : : const u8 *ssid, size_t ssid_len)
568 : : {
569 : : struct wpa_bss *bss;
570 : : const u8 *bssid;
571 : : struct wpabuf *p2p;
572 : : u8 group_capab;
573 : : const u8 *addr;
574 : :
575 [ + + ]: 169 : if (wpa_s->go_params)
576 : 159 : bssid = wpa_s->go_params->peer_interface_addr;
577 : : else
578 : 10 : bssid = wpa_s->bssid;
579 : :
580 : 169 : bss = wpa_bss_get(wpa_s, bssid, ssid, ssid_len);
581 [ - + ]: 169 : if (bss == NULL) {
582 : : u8 iface_addr[ETH_ALEN];
583 [ # # ]: 0 : if (p2p_get_interface_addr(wpa_s->global->p2p, bssid,
584 : : iface_addr) == 0)
585 : 0 : bss = wpa_bss_get(wpa_s, iface_addr, ssid, ssid_len);
586 : : }
587 [ - + ]: 169 : if (bss == NULL) {
588 : 0 : wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether "
589 : : "group is persistent - BSS " MACSTR " not found",
590 : 0 : MAC2STR(bssid));
591 : 0 : return 0;
592 : : }
593 : :
594 : 169 : p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
595 [ + + ]: 169 : if (p2p == NULL)
596 : 1 : p2p = wpa_bss_get_vendor_ie_multi_beacon(bss,
597 : : P2P_IE_VENDOR_TYPE);
598 [ + + ]: 169 : if (p2p == NULL) {
599 : 1 : wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether "
600 : : "group is persistent - BSS " MACSTR
601 : 6 : " did not include P2P IE", MAC2STR(bssid));
602 : 1 : wpa_hexdump(MSG_DEBUG, "P2P: Probe Response IEs",
603 : : (u8 *) (bss + 1), bss->ie_len);
604 : 1 : wpa_hexdump(MSG_DEBUG, "P2P: Beacon IEs",
605 : 1 : ((u8 *) bss + 1) + bss->ie_len,
606 : : bss->beacon_ie_len);
607 : 1 : return 0;
608 : : }
609 : :
610 : 168 : group_capab = p2p_get_group_capab(p2p);
611 : 168 : addr = p2p_get_go_dev_addr(p2p);
612 : 168 : wpa_printf(MSG_DEBUG, "P2P: Checking whether group is persistent: "
613 : : "group_capab=0x%x", group_capab);
614 [ + - ]: 168 : if (addr) {
615 : 168 : os_memcpy(go_dev_addr, addr, ETH_ALEN);
616 : 168 : wpa_printf(MSG_DEBUG, "P2P: GO Device Address " MACSTR,
617 : 1008 : MAC2STR(addr));
618 : : } else
619 : 0 : os_memset(go_dev_addr, 0, ETH_ALEN);
620 : 168 : wpabuf_free(p2p);
621 : :
622 : 168 : wpa_printf(MSG_DEBUG, "P2P: BSS " MACSTR " group_capab=0x%x "
623 : : "go_dev_addr=" MACSTR,
624 : 2016 : MAC2STR(bssid), group_capab, MAC2STR(go_dev_addr));
625 : :
626 : 169 : return group_capab & P2P_GROUP_CAPAB_PERSISTENT_GROUP;
627 : : }
628 : :
629 : :
630 : 38 : static int wpas_p2p_store_persistent_group(struct wpa_supplicant *wpa_s,
631 : : struct wpa_ssid *ssid,
632 : : const u8 *go_dev_addr)
633 : : {
634 : : struct wpa_ssid *s;
635 : 38 : int changed = 0;
636 : :
637 : 38 : wpa_printf(MSG_DEBUG, "P2P: Storing credentials for a persistent "
638 : 228 : "group (GO Dev Addr " MACSTR ")", MAC2STR(go_dev_addr));
639 [ + + ]: 63 : for (s = wpa_s->conf->ssid; s; s = s->next) {
640 [ + + ][ + + ]: 48 : if (s->disabled == 2 &&
641 [ + - ]: 23 : os_memcmp(go_dev_addr, s->bssid, ETH_ALEN) == 0 &&
642 [ + - ]: 23 : s->ssid_len == ssid->ssid_len &&
643 : 23 : os_memcmp(ssid->ssid, s->ssid, ssid->ssid_len) == 0)
644 : 23 : break;
645 : : }
646 : :
647 [ + + ]: 38 : if (s) {
648 : 23 : wpa_printf(MSG_DEBUG, "P2P: Update existing persistent group "
649 : : "entry");
650 [ + + ][ - + ]: 23 : if (ssid->passphrase && !s->passphrase)
651 : 0 : changed = 1;
652 [ + + ][ + - ]: 23 : else if (ssid->passphrase && s->passphrase &&
[ - + ]
653 : 7 : os_strcmp(ssid->passphrase, s->passphrase) != 0)
654 : 23 : changed = 1;
655 : : } else {
656 : 15 : wpa_printf(MSG_DEBUG, "P2P: Create a new persistent group "
657 : : "entry");
658 : 15 : changed = 1;
659 : 15 : s = wpa_config_add_network(wpa_s->conf);
660 [ - + ]: 15 : if (s == NULL)
661 : 0 : return -1;
662 : :
663 : : /*
664 : : * Instead of network_added we emit persistent_group_added
665 : : * notification. Also to keep the defense checks in
666 : : * persistent_group obj registration method, we set the
667 : : * relevant flags in s to designate it as a persistent group.
668 : : */
669 : 15 : s->p2p_group = 1;
670 : 15 : s->p2p_persistent_group = 1;
671 : 15 : wpas_notify_persistent_group_added(wpa_s, s);
672 : 15 : wpa_config_set_network_defaults(s);
673 : : }
674 : :
675 : 38 : s->p2p_group = 1;
676 : 38 : s->p2p_persistent_group = 1;
677 : 38 : s->disabled = 2;
678 : 38 : s->bssid_set = 1;
679 : 38 : os_memcpy(s->bssid, go_dev_addr, ETH_ALEN);
680 : 38 : s->mode = ssid->mode;
681 : 38 : s->auth_alg = WPA_AUTH_ALG_OPEN;
682 : 38 : s->key_mgmt = WPA_KEY_MGMT_PSK;
683 : 38 : s->proto = WPA_PROTO_RSN;
684 : 38 : s->pairwise_cipher = WPA_CIPHER_CCMP;
685 : 38 : s->export_keys = 1;
686 [ + + ]: 38 : if (ssid->passphrase) {
687 : 13 : os_free(s->passphrase);
688 : 13 : s->passphrase = os_strdup(ssid->passphrase);
689 : : }
690 [ + - ]: 38 : if (ssid->psk_set) {
691 : 38 : s->psk_set = 1;
692 : 38 : os_memcpy(s->psk, ssid->psk, 32);
693 : : }
694 [ + + ][ - + ]: 38 : if (s->passphrase && !s->psk_set)
695 : 0 : wpa_config_update_psk(s);
696 [ + + ][ - + ]: 38 : if (s->ssid == NULL || s->ssid_len < ssid->ssid_len) {
697 : 15 : os_free(s->ssid);
698 : 15 : s->ssid = os_malloc(ssid->ssid_len);
699 : : }
700 [ + - ]: 38 : if (s->ssid) {
701 : 38 : s->ssid_len = ssid->ssid_len;
702 : 38 : os_memcpy(s->ssid, ssid->ssid, s->ssid_len);
703 : : }
704 [ + + ][ + + ]: 38 : if (ssid->mode == WPAS_MODE_P2P_GO && wpa_s->global->add_psk) {
705 : 2 : dl_list_add(&s->psk_list, &wpa_s->global->add_psk->list);
706 : 2 : wpa_s->global->add_psk = NULL;
707 : 2 : changed = 1;
708 : : }
709 : :
710 : : #ifndef CONFIG_NO_CONFIG_WRITE
711 [ + + ]: 38 : if (changed && wpa_s->conf->update_config &&
[ - + # # ]
712 : 0 : wpa_config_write(wpa_s->confname, wpa_s->conf)) {
713 : 0 : wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
714 : : }
715 : : #endif /* CONFIG_NO_CONFIG_WRITE */
716 : :
717 : 38 : return s->id;
718 : : }
719 : :
720 : :
721 : 61 : static void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s,
722 : : const u8 *addr)
723 : : {
724 : : struct wpa_ssid *ssid, *s;
725 : : u8 *n;
726 : : size_t i;
727 : 61 : int found = 0;
728 : :
729 : 61 : ssid = wpa_s->current_ssid;
730 [ + - ][ + - ]: 61 : if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
[ + + ]
731 : 61 : !ssid->p2p_persistent_group)
732 : 45 : return;
733 : :
734 [ + - ]: 24 : for (s = wpa_s->parent->conf->ssid; s; s = s->next) {
735 [ + + ][ - + ]: 24 : if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO)
736 : 8 : continue;
737 : :
738 [ + - ][ + - ]: 16 : if (s->ssid_len == ssid->ssid_len &&
739 : 16 : os_memcmp(s->ssid, ssid->ssid, s->ssid_len) == 0)
740 : 16 : break;
741 : : }
742 : :
743 [ - + ]: 16 : if (s == NULL)
744 : 0 : return;
745 : :
746 [ + + ][ + + ]: 19 : for (i = 0; s->p2p_client_list && i < s->num_p2p_clients; i++) {
747 [ + + ]: 10 : if (os_memcmp(s->p2p_client_list + i * ETH_ALEN, addr,
748 : : ETH_ALEN) != 0)
749 : 3 : continue;
750 : :
751 [ + - ]: 7 : if (i == s->num_p2p_clients - 1)
752 : 7 : return; /* already the most recent entry */
753 : :
754 : : /* move the entry to mark it most recent */
755 : 0 : os_memmove(s->p2p_client_list + i * ETH_ALEN,
756 : : s->p2p_client_list + (i + 1) * ETH_ALEN,
757 : : (s->num_p2p_clients - i - 1) * ETH_ALEN);
758 : 0 : os_memcpy(s->p2p_client_list +
759 : : (s->num_p2p_clients - 1) * ETH_ALEN, addr, ETH_ALEN);
760 : 0 : found = 1;
761 : 0 : break;
762 : : }
763 : :
764 [ + - ][ + - ]: 9 : if (!found && s->num_p2p_clients < P2P_MAX_STORED_CLIENTS) {
765 : 9 : n = os_realloc_array(s->p2p_client_list,
766 : 9 : s->num_p2p_clients + 1, ETH_ALEN);
767 [ - + ]: 9 : if (n == NULL)
768 : 0 : return;
769 : 9 : os_memcpy(n + s->num_p2p_clients * ETH_ALEN, addr, ETH_ALEN);
770 : 9 : s->p2p_client_list = n;
771 : 9 : s->num_p2p_clients++;
772 [ # # ]: 0 : } else if (!found) {
773 : : /* Not enough room for an additional entry - drop the oldest
774 : : * entry */
775 : 0 : os_memmove(s->p2p_client_list,
776 : : s->p2p_client_list + ETH_ALEN,
777 : : (s->num_p2p_clients - 1) * ETH_ALEN);
778 : 0 : os_memcpy(s->p2p_client_list +
779 : : (s->num_p2p_clients - 1) * ETH_ALEN,
780 : : addr, ETH_ALEN);
781 : : }
782 : :
783 : : #ifndef CONFIG_NO_CONFIG_WRITE
784 [ - + # # ]: 9 : if (wpa_s->parent->conf->update_config &&
785 : 0 : wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
786 : 61 : wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
787 : : #endif /* CONFIG_NO_CONFIG_WRITE */
788 : : }
789 : :
790 : :
791 : 88 : static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
792 : : int success)
793 : : {
794 : : struct wpa_ssid *ssid;
795 : : const char *ssid_txt;
796 : : int client;
797 : : int persistent;
798 : : u8 go_dev_addr[ETH_ALEN];
799 : 88 : int network_id = -1;
800 : :
801 : : /*
802 : : * This callback is likely called for the main interface. Update wpa_s
803 : : * to use the group interface if a new interface was created for the
804 : : * group.
805 : : */
806 [ + - ]: 88 : if (wpa_s->global->p2p_group_formation)
807 : 88 : wpa_s = wpa_s->global->p2p_group_formation;
808 [ + + ]: 88 : if (wpa_s->p2p_go_group_formation_completed) {
809 : 53 : wpa_s->global->p2p_group_formation = NULL;
810 : 53 : wpa_s->p2p_in_provisioning = 0;
811 : : }
812 : :
813 [ - + ]: 88 : if (!success) {
814 : 0 : wpa_msg_global(wpa_s->parent, MSG_INFO,
815 : : P2P_EVENT_GROUP_FORMATION_FAILURE);
816 : 0 : wpas_p2p_group_delete(wpa_s,
817 : : P2P_GROUP_REMOVAL_FORMATION_FAILED);
818 : 88 : return;
819 : : }
820 : :
821 : 88 : wpa_msg_global(wpa_s->parent, MSG_INFO,
822 : : P2P_EVENT_GROUP_FORMATION_SUCCESS);
823 : :
824 : 88 : ssid = wpa_s->current_ssid;
825 [ + - ][ + + ]: 88 : if (ssid && ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
826 : 35 : ssid->mode = WPAS_MODE_P2P_GO;
827 : 35 : p2p_group_notif_formation_done(wpa_s->p2p_group);
828 : 35 : wpa_supplicant_ap_mac_addr_filter(wpa_s, NULL);
829 : : }
830 : :
831 : 88 : persistent = 0;
832 [ + - ]: 88 : if (ssid) {
833 : 88 : ssid_txt = wpa_ssid_txt(ssid->ssid, ssid->ssid_len);
834 : 88 : client = ssid->mode == WPAS_MODE_INFRA;
835 [ + + ]: 88 : if (ssid->mode == WPAS_MODE_P2P_GO) {
836 : 35 : persistent = ssid->p2p_persistent_group;
837 : 35 : os_memcpy(go_dev_addr, wpa_s->global->p2p_dev_addr,
838 : : ETH_ALEN);
839 : : } else
840 : 53 : persistent = wpas_p2p_persistent_group(wpa_s,
841 : : go_dev_addr,
842 : 53 : ssid->ssid,
843 : : ssid->ssid_len);
844 : : } else {
845 : 0 : ssid_txt = "";
846 : 0 : client = wpa_s->p2p_group_interface ==
847 : : P2P_GROUP_INTERFACE_CLIENT;
848 : 0 : os_memset(go_dev_addr, 0, ETH_ALEN);
849 : : }
850 : :
851 : 88 : wpa_s->show_group_started = 0;
852 [ + + ]: 88 : if (client) {
853 : : /*
854 : : * Indicate event only after successfully completed 4-way
855 : : * handshake, i.e., when the interface is ready for data
856 : : * packets.
857 : : */
858 : 53 : wpa_s->show_group_started = 1;
859 [ + - ][ - + ]: 35 : } else if (ssid && ssid->passphrase == NULL && ssid->psk_set) {
[ # # ]
860 : : char psk[65];
861 : 0 : wpa_snprintf_hex(psk, sizeof(psk), ssid->psk, 32);
862 [ # # ]: 0 : wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
863 : : "%s GO ssid=\"%s\" freq=%d psk=%s go_dev_addr="
864 : : MACSTR "%s",
865 : 0 : wpa_s->ifname, ssid_txt, ssid->frequency, psk,
866 : 0 : MAC2STR(go_dev_addr),
867 : : persistent ? " [PERSISTENT]" : "");
868 : 0 : wpas_p2p_cross_connect_setup(wpa_s);
869 : 0 : wpas_p2p_set_group_idle_timeout(wpa_s);
870 : : } else {
871 [ + + ][ + - ]: 70 : wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
[ + - ]
872 : : "%s GO ssid=\"%s\" freq=%d passphrase=\"%s\" "
873 : : "go_dev_addr=" MACSTR "%s",
874 : 35 : wpa_s->ifname, ssid_txt,
875 : : ssid ? ssid->frequency : 0,
876 [ + - ]: 35 : ssid && ssid->passphrase ? ssid->passphrase : "",
877 : 210 : MAC2STR(go_dev_addr),
878 : : persistent ? " [PERSISTENT]" : "");
879 : 35 : wpas_p2p_cross_connect_setup(wpa_s);
880 : 35 : wpas_p2p_set_group_idle_timeout(wpa_s);
881 : : }
882 : :
883 [ + + ]: 88 : if (persistent)
884 : 14 : network_id = wpas_p2p_store_persistent_group(wpa_s->parent,
885 : : ssid, go_dev_addr);
886 : : else {
887 : 74 : os_free(wpa_s->global->add_psk);
888 : 74 : wpa_s->global->add_psk = NULL;
889 : : }
890 [ + + ][ + - ]: 88 : if (network_id < 0 && ssid)
891 : 74 : network_id = ssid->id;
892 [ + + ]: 88 : if (!client) {
893 : 35 : wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0);
894 : 35 : os_get_reltime(&wpa_s->global->p2p_go_wait_client);
895 : : }
896 : : }
897 : :
898 : :
899 : 262 : static void wpas_p2p_send_action_tx_status(struct wpa_supplicant *wpa_s,
900 : : unsigned int freq,
901 : : const u8 *dst, const u8 *src,
902 : : const u8 *bssid,
903 : : const u8 *data, size_t data_len,
904 : : enum offchannel_send_action_result
905 : : result)
906 : : {
907 : 262 : enum p2p_send_action_result res = P2P_SEND_ACTION_SUCCESS;
908 : :
909 [ + - ][ - + ]: 262 : if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled)
910 : 0 : return;
911 : :
912 [ + + - - ]: 262 : switch (result) {
913 : : case OFFCHANNEL_SEND_ACTION_SUCCESS:
914 : 244 : res = P2P_SEND_ACTION_SUCCESS;
915 : 244 : break;
916 : : case OFFCHANNEL_SEND_ACTION_NO_ACK:
917 : 18 : res = P2P_SEND_ACTION_NO_ACK;
918 : 18 : break;
919 : : case OFFCHANNEL_SEND_ACTION_FAILED:
920 : 0 : res = P2P_SEND_ACTION_FAILED;
921 : 0 : break;
922 : : }
923 : :
924 : 262 : p2p_send_action_cb(wpa_s->global->p2p, freq, dst, src, bssid, res);
925 : :
926 [ + + ][ - + ]: 262 : if (result != OFFCHANNEL_SEND_ACTION_SUCCESS &&
927 [ # # ]: 0 : wpa_s->pending_pd_before_join &&
928 [ # # ]: 0 : (os_memcmp(dst, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
929 [ # # ]: 0 : os_memcmp(dst, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0) &&
930 : : wpa_s->p2p_fallback_to_go_neg) {
931 : 0 : wpa_s->pending_pd_before_join = 0;
932 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No ACK for PD Req "
933 : : "during p2p_connect-auto");
934 : 0 : wpas_p2p_fallback_to_go_neg(wpa_s, 0);
935 : 262 : return;
936 : : }
937 : : }
938 : :
939 : :
940 : 263 : static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst,
941 : : const u8 *src, const u8 *bssid, const u8 *buf,
942 : : size_t len, unsigned int wait_time)
943 : : {
944 : 263 : struct wpa_supplicant *wpa_s = ctx;
945 : 263 : return offchannel_send_action(wpa_s, freq, dst, src, bssid, buf, len,
946 : : wait_time,
947 : : wpas_p2p_send_action_tx_status, 1);
948 : : }
949 : :
950 : :
951 : 135 : static void wpas_send_action_done(void *ctx)
952 : : {
953 : 135 : struct wpa_supplicant *wpa_s = ctx;
954 : 135 : offchannel_send_action_done(wpa_s);
955 : 135 : }
956 : :
957 : :
958 : 111 : static int wpas_copy_go_neg_results(struct wpa_supplicant *wpa_s,
959 : : struct p2p_go_neg_results *params)
960 : : {
961 [ + - ]: 111 : if (wpa_s->go_params == NULL) {
962 : 111 : wpa_s->go_params = os_malloc(sizeof(*params));
963 [ - + ]: 111 : if (wpa_s->go_params == NULL)
964 : 0 : return -1;
965 : : }
966 : 111 : os_memcpy(wpa_s->go_params, params, sizeof(*params));
967 : 111 : return 0;
968 : : }
969 : :
970 : :
971 : 53 : static void wpas_start_wps_enrollee(struct wpa_supplicant *wpa_s,
972 : : struct p2p_go_neg_results *res)
973 : : {
974 : 53 : wpa_printf(MSG_DEBUG, "P2P: Start WPS Enrollee for peer " MACSTR,
975 : 318 : MAC2STR(res->peer_interface_addr));
976 : 53 : wpa_hexdump_ascii(MSG_DEBUG, "P2P: Start WPS Enrollee for SSID",
977 : 53 : res->ssid, res->ssid_len);
978 : 53 : wpa_supplicant_ap_deinit(wpa_s);
979 : 53 : wpas_copy_go_neg_results(wpa_s, res);
980 [ + + ]: 53 : if (res->wps_method == WPS_PBC)
981 : 3 : wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1);
982 : : else {
983 : 50 : u16 dev_pw_id = DEV_PW_DEFAULT;
984 [ + + ]: 50 : if (wpa_s->p2p_wps_method == WPS_PIN_KEYPAD)
985 : 28 : dev_pw_id = DEV_PW_REGISTRAR_SPECIFIED;
986 : 50 : wpas_wps_start_pin(wpa_s, res->peer_interface_addr,
987 : 50 : wpa_s->p2p_pin, 1, dev_pw_id);
988 : : }
989 : 53 : }
990 : :
991 : :
992 : 8 : static void wpas_p2p_add_psk_list(struct wpa_supplicant *wpa_s,
993 : : struct wpa_ssid *ssid)
994 : : {
995 : : struct wpa_ssid *persistent;
996 : : struct psk_list_entry *psk;
997 : : struct hostapd_data *hapd;
998 : :
999 [ - + ]: 8 : if (!wpa_s->ap_iface)
1000 : 0 : return;
1001 : :
1002 : 8 : persistent = wpas_p2p_get_persistent(wpa_s->parent, NULL, ssid->ssid,
1003 : : ssid->ssid_len);
1004 [ - + ]: 8 : if (persistent == NULL)
1005 : 0 : return;
1006 : :
1007 : 8 : hapd = wpa_s->ap_iface->bss[0];
1008 : :
1009 [ - + ]: 8 : dl_list_for_each(psk, &persistent->psk_list, struct psk_list_entry,
1010 : : list) {
1011 : : struct hostapd_wpa_psk *hpsk;
1012 : :
1013 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add persistent group PSK entry for "
1014 : : MACSTR " psk=%d",
1015 : : MAC2STR(psk->addr), psk->p2p);
1016 : 0 : hpsk = os_zalloc(sizeof(*hpsk));
1017 [ # # ]: 0 : if (hpsk == NULL)
1018 : 0 : break;
1019 : 0 : os_memcpy(hpsk->psk, psk->psk, PMK_LEN);
1020 [ # # ]: 0 : if (psk->p2p)
1021 : 0 : os_memcpy(hpsk->p2p_dev_addr, psk->addr, ETH_ALEN);
1022 : : else
1023 : 0 : os_memcpy(hpsk->addr, psk->addr, ETH_ALEN);
1024 : 0 : hpsk->next = hapd->conf->ssid.wpa_psk;
1025 : 0 : hapd->conf->ssid.wpa_psk = hpsk;
1026 : : }
1027 : : }
1028 : :
1029 : :
1030 : 58 : static void p2p_go_configured(void *ctx, void *data)
1031 : : {
1032 : 58 : struct wpa_supplicant *wpa_s = ctx;
1033 : 58 : struct p2p_go_neg_results *params = data;
1034 : : struct wpa_ssid *ssid;
1035 : 58 : int network_id = -1;
1036 : :
1037 : 58 : ssid = wpa_s->current_ssid;
1038 [ + - ][ + + ]: 58 : if (ssid && ssid->mode == WPAS_MODE_P2P_GO) {
1039 : 23 : wpa_printf(MSG_DEBUG, "P2P: Group setup without provisioning");
1040 [ + + ]: 23 : if (wpa_s->global->p2p_group_formation == wpa_s)
1041 : 3 : wpa_s->global->p2p_group_formation = NULL;
1042 [ + - ]: 23 : if (os_strlen(params->passphrase) > 0) {
1043 [ + + ]: 23 : wpa_msg_global(wpa_s->parent, MSG_INFO,
1044 : : P2P_EVENT_GROUP_STARTED
1045 : : "%s GO ssid=\"%s\" freq=%d "
1046 : : "passphrase=\"%s\" go_dev_addr=" MACSTR
1047 : 23 : "%s", wpa_s->ifname,
1048 : 23 : wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
1049 : 23 : ssid->frequency, params->passphrase,
1050 : 138 : MAC2STR(wpa_s->global->p2p_dev_addr),
1051 : 23 : params->persistent_group ?
1052 : : " [PERSISTENT]" : "");
1053 : : } else {
1054 : : char psk[65];
1055 : 0 : wpa_snprintf_hex(psk, sizeof(psk), params->psk,
1056 : : sizeof(params->psk));
1057 [ # # ]: 0 : wpa_msg_global(wpa_s->parent, MSG_INFO,
1058 : : P2P_EVENT_GROUP_STARTED
1059 : : "%s GO ssid=\"%s\" freq=%d psk=%s "
1060 : : "go_dev_addr=" MACSTR "%s",
1061 : 0 : wpa_s->ifname,
1062 : 0 : wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
1063 : : ssid->frequency, psk,
1064 : 0 : MAC2STR(wpa_s->global->p2p_dev_addr),
1065 : 0 : params->persistent_group ?
1066 : : " [PERSISTENT]" : "");
1067 : : }
1068 : :
1069 : 23 : os_get_reltime(&wpa_s->global->p2p_go_wait_client);
1070 [ + + ]: 23 : if (params->persistent_group) {
1071 : 8 : network_id = wpas_p2p_store_persistent_group(
1072 : : wpa_s->parent, ssid,
1073 : 8 : wpa_s->global->p2p_dev_addr);
1074 : 8 : wpas_p2p_add_psk_list(wpa_s, ssid);
1075 : : }
1076 [ + + ]: 23 : if (network_id < 0)
1077 : 15 : network_id = ssid->id;
1078 : 23 : wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0);
1079 : 23 : wpas_p2p_cross_connect_setup(wpa_s);
1080 : 23 : wpas_p2p_set_group_idle_timeout(wpa_s);
1081 : :
1082 [ + + ]: 23 : if (wpa_s->p2p_first_connection_timeout) {
1083 : 7 : wpa_dbg(wpa_s, MSG_DEBUG,
1084 : : "P2P: Start group formation timeout of %d seconds until first data connection on GO",
1085 : : wpa_s->p2p_first_connection_timeout);
1086 : 7 : wpa_s->p2p_go_group_formation_completed = 0;
1087 : 7 : wpa_s->global->p2p_group_formation = wpa_s;
1088 : 7 : eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
1089 : 7 : wpa_s->parent, NULL);
1090 : 7 : eloop_register_timeout(
1091 : 7 : wpa_s->p2p_first_connection_timeout, 0,
1092 : : wpas_p2p_group_formation_timeout,
1093 : 7 : wpa_s->parent, NULL);
1094 : : }
1095 : :
1096 : 23 : return;
1097 : : }
1098 : :
1099 : 35 : wpa_printf(MSG_DEBUG, "P2P: Setting up WPS for GO provisioning");
1100 [ - + ]: 35 : if (wpa_supplicant_ap_mac_addr_filter(wpa_s,
1101 : 35 : params->peer_interface_addr)) {
1102 : 0 : wpa_printf(MSG_DEBUG, "P2P: Failed to setup MAC address "
1103 : : "filtering");
1104 : 0 : return;
1105 : : }
1106 [ + + ]: 35 : if (params->wps_method == WPS_PBC)
1107 : 3 : wpa_supplicant_ap_wps_pbc(wpa_s, params->peer_interface_addr,
1108 : 3 : params->peer_device_addr);
1109 [ + - ]: 32 : else if (wpa_s->p2p_pin[0])
1110 : 32 : wpa_supplicant_ap_wps_pin(wpa_s, params->peer_interface_addr,
1111 : 32 : wpa_s->p2p_pin, NULL, 0, 0);
1112 : 35 : os_free(wpa_s->go_params);
1113 : 58 : wpa_s->go_params = NULL;
1114 : : }
1115 : :
1116 : :
1117 : 58 : static void wpas_start_wps_go(struct wpa_supplicant *wpa_s,
1118 : : struct p2p_go_neg_results *params,
1119 : : int group_formation)
1120 : : {
1121 : : struct wpa_ssid *ssid;
1122 : :
1123 : 58 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Starting GO");
1124 [ - + ]: 58 : if (wpas_copy_go_neg_results(wpa_s, params) < 0) {
1125 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not copy GO Negotiation "
1126 : : "results");
1127 : 0 : return;
1128 : : }
1129 : :
1130 : 58 : ssid = wpa_config_add_network(wpa_s->conf);
1131 [ - + ]: 58 : if (ssid == NULL) {
1132 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not add network for GO");
1133 : 0 : return;
1134 : : }
1135 : :
1136 : 58 : wpa_s->show_group_started = 0;
1137 : :
1138 : 58 : wpa_config_set_network_defaults(ssid);
1139 : 58 : ssid->temporary = 1;
1140 : 58 : ssid->p2p_group = 1;
1141 : 58 : ssid->p2p_persistent_group = params->persistent_group;
1142 [ + + ]: 58 : ssid->mode = group_formation ? WPAS_MODE_P2P_GROUP_FORMATION :
1143 : : WPAS_MODE_P2P_GO;
1144 : 58 : ssid->frequency = params->freq;
1145 : 58 : ssid->ht40 = params->ht40;
1146 : 58 : ssid->vht = params->vht;
1147 : 58 : ssid->ssid = os_zalloc(params->ssid_len + 1);
1148 [ + - ]: 58 : if (ssid->ssid) {
1149 : 58 : os_memcpy(ssid->ssid, params->ssid, params->ssid_len);
1150 : 58 : ssid->ssid_len = params->ssid_len;
1151 : : }
1152 : 58 : ssid->auth_alg = WPA_AUTH_ALG_OPEN;
1153 : 58 : ssid->key_mgmt = WPA_KEY_MGMT_PSK;
1154 : 58 : ssid->proto = WPA_PROTO_RSN;
1155 : 58 : ssid->pairwise_cipher = WPA_CIPHER_CCMP;
1156 [ + - ]: 58 : if (os_strlen(params->passphrase) > 0) {
1157 : 58 : ssid->passphrase = os_strdup(params->passphrase);
1158 [ - + ]: 58 : if (ssid->passphrase == NULL) {
1159 : 0 : wpa_msg_global(wpa_s, MSG_ERROR,
1160 : : "P2P: Failed to copy passphrase for GO");
1161 : 0 : wpa_config_remove_network(wpa_s->conf, ssid->id);
1162 : 0 : return;
1163 : : }
1164 : : } else
1165 : 0 : ssid->passphrase = NULL;
1166 : 58 : ssid->psk_set = params->psk_set;
1167 [ + + ]: 58 : if (ssid->psk_set)
1168 : 8 : os_memcpy(ssid->psk, params->psk, sizeof(ssid->psk));
1169 [ + - ]: 50 : else if (ssid->passphrase)
1170 : 50 : wpa_config_update_psk(ssid);
1171 : 58 : ssid->ap_max_inactivity = wpa_s->parent->conf->p2p_go_max_inactivity;
1172 : :
1173 : 58 : wpa_s->ap_configured_cb = p2p_go_configured;
1174 : 58 : wpa_s->ap_configured_cb_ctx = wpa_s;
1175 : 58 : wpa_s->ap_configured_cb_data = wpa_s->go_params;
1176 : 58 : wpa_s->connect_without_scan = ssid;
1177 : 58 : wpa_s->reassociate = 1;
1178 : 58 : wpa_s->disconnected = 0;
1179 : 58 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Request scan (that will be skipped) to "
1180 : : "start GO)");
1181 : 58 : wpa_supplicant_req_scan(wpa_s, 0, 0);
1182 : : }
1183 : :
1184 : :
1185 : 22 : static void wpas_p2p_clone_config(struct wpa_supplicant *dst,
1186 : : const struct wpa_supplicant *src)
1187 : : {
1188 : : struct wpa_config *d;
1189 : : const struct wpa_config *s;
1190 : :
1191 : 22 : d = dst->conf;
1192 : 22 : s = src->conf;
1193 : :
1194 : : #define C(n) if (s->n) d->n = os_strdup(s->n)
1195 [ + + ]: 22 : C(device_name);
1196 [ - + ]: 22 : C(manufacturer);
1197 [ - + ]: 22 : C(model_name);
1198 [ - + ]: 22 : C(model_number);
1199 [ - + ]: 22 : C(serial_number);
1200 [ - + ]: 22 : C(config_methods);
1201 : : #undef C
1202 : :
1203 : 22 : os_memcpy(d->device_type, s->device_type, WPS_DEV_TYPE_LEN);
1204 : 22 : os_memcpy(d->sec_device_type, s->sec_device_type,
1205 : : sizeof(d->sec_device_type));
1206 : 22 : d->num_sec_device_types = s->num_sec_device_types;
1207 : :
1208 : 22 : d->p2p_group_idle = s->p2p_group_idle;
1209 : 22 : d->p2p_intra_bss = s->p2p_intra_bss;
1210 : 22 : d->persistent_reconnect = s->persistent_reconnect;
1211 : 22 : d->max_num_sta = s->max_num_sta;
1212 : 22 : d->pbc_in_m1 = s->pbc_in_m1;
1213 : 22 : d->ignore_old_scan_res = s->ignore_old_scan_res;
1214 : 22 : d->beacon_int = s->beacon_int;
1215 : 22 : d->disassoc_low_ack = s->disassoc_low_ack;
1216 : 22 : d->disable_scan_offload = s->disable_scan_offload;
1217 : 22 : }
1218 : :
1219 : :
1220 : 22 : static void wpas_p2p_get_group_ifname(struct wpa_supplicant *wpa_s,
1221 : : char *ifname, size_t len)
1222 : : {
1223 : 22 : char *ifname_ptr = wpa_s->ifname;
1224 : :
1225 [ - + ]: 22 : if (os_strncmp(wpa_s->ifname, P2P_MGMT_DEVICE_PREFIX,
1226 : : os_strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
1227 : 0 : ifname_ptr = os_strrchr(wpa_s->ifname, '-') + 1;
1228 : : }
1229 : :
1230 : 22 : os_snprintf(ifname, len, "p2p-%s-%d", ifname_ptr, wpa_s->p2p_group_idx);
1231 [ - + ][ # # ]: 22 : if (os_strlen(ifname) >= IFNAMSIZ &&
1232 : 0 : os_strlen(wpa_s->ifname) < IFNAMSIZ) {
1233 : : /* Try to avoid going over the IFNAMSIZ length limit */
1234 : 0 : os_snprintf(ifname, len, "p2p-%d", wpa_s->p2p_group_idx);
1235 : : }
1236 : 22 : }
1237 : :
1238 : :
1239 : 22 : static int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s,
1240 : : enum wpa_driver_if_type type)
1241 : : {
1242 : : char ifname[120], force_ifname[120];
1243 : :
1244 [ - + ]: 22 : if (wpa_s->pending_interface_name[0]) {
1245 : 0 : wpa_printf(MSG_DEBUG, "P2P: Pending virtual interface exists "
1246 : : "- skip creation of a new one");
1247 [ # # ]: 0 : if (is_zero_ether_addr(wpa_s->pending_interface_addr)) {
1248 : 0 : wpa_printf(MSG_DEBUG, "P2P: Pending virtual address "
1249 : : "unknown?! ifname='%s'",
1250 : 0 : wpa_s->pending_interface_name);
1251 : 0 : return -1;
1252 : : }
1253 : 0 : return 0;
1254 : : }
1255 : :
1256 : 22 : wpas_p2p_get_group_ifname(wpa_s, ifname, sizeof(ifname));
1257 : 22 : force_ifname[0] = '\0';
1258 : :
1259 : 22 : wpa_printf(MSG_DEBUG, "P2P: Create a new interface %s for the group",
1260 : : ifname);
1261 : 22 : wpa_s->p2p_group_idx++;
1262 : :
1263 : 22 : wpa_s->pending_interface_type = type;
1264 [ - + ]: 22 : if (wpa_drv_if_add(wpa_s, type, ifname, NULL, NULL, force_ifname,
1265 : 22 : wpa_s->pending_interface_addr, NULL) < 0) {
1266 : 0 : wpa_printf(MSG_ERROR, "P2P: Failed to create new group "
1267 : : "interface");
1268 : 0 : return -1;
1269 : : }
1270 : :
1271 [ - + ]: 22 : if (force_ifname[0]) {
1272 : 0 : wpa_printf(MSG_DEBUG, "P2P: Driver forced interface name %s",
1273 : : force_ifname);
1274 : 0 : os_strlcpy(wpa_s->pending_interface_name, force_ifname,
1275 : : sizeof(wpa_s->pending_interface_name));
1276 : : } else
1277 : 22 : os_strlcpy(wpa_s->pending_interface_name, ifname,
1278 : : sizeof(wpa_s->pending_interface_name));
1279 : 22 : wpa_printf(MSG_DEBUG, "P2P: Created pending virtual interface %s addr "
1280 : 22 : MACSTR, wpa_s->pending_interface_name,
1281 : 132 : MAC2STR(wpa_s->pending_interface_addr));
1282 : :
1283 : 22 : return 0;
1284 : : }
1285 : :
1286 : :
1287 : 785 : static void wpas_p2p_remove_pending_group_interface(
1288 : : struct wpa_supplicant *wpa_s)
1289 : : {
1290 [ - + # # ]: 785 : if (!wpa_s->pending_interface_name[0] ||
1291 : 0 : is_zero_ether_addr(wpa_s->pending_interface_addr))
1292 : 785 : return; /* No pending virtual interface */
1293 : :
1294 : 0 : wpa_printf(MSG_DEBUG, "P2P: Removing pending group interface %s",
1295 : 0 : wpa_s->pending_interface_name);
1296 : 0 : wpa_drv_if_remove(wpa_s, wpa_s->pending_interface_type,
1297 : 0 : wpa_s->pending_interface_name);
1298 : 0 : os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN);
1299 : 0 : wpa_s->pending_interface_name[0] = '\0';
1300 : : }
1301 : :
1302 : :
1303 : : static struct wpa_supplicant *
1304 : 22 : wpas_p2p_init_group_interface(struct wpa_supplicant *wpa_s, int go)
1305 : : {
1306 : : struct wpa_interface iface;
1307 : : struct wpa_supplicant *group_wpa_s;
1308 : :
1309 [ - + ]: 22 : if (!wpa_s->pending_interface_name[0]) {
1310 : 0 : wpa_printf(MSG_ERROR, "P2P: No pending group interface");
1311 [ # # ]: 0 : if (!wpas_p2p_create_iface(wpa_s))
1312 : 0 : return NULL;
1313 : : /*
1314 : : * Something has forced us to remove the pending interface; try
1315 : : * to create a new one and hope for the best that we will get
1316 : : * the same local address.
1317 : : */
1318 [ # # ][ # # ]: 0 : if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO :
1319 : : WPA_IF_P2P_CLIENT) < 0)
1320 : 0 : return NULL;
1321 : : }
1322 : :
1323 : 22 : os_memset(&iface, 0, sizeof(iface));
1324 : 22 : iface.ifname = wpa_s->pending_interface_name;
1325 : 22 : iface.driver = wpa_s->driver->name;
1326 [ - + ][ # # ]: 22 : if (wpa_s->conf->ctrl_interface == NULL &&
1327 [ # # ]: 0 : wpa_s->parent != wpa_s &&
1328 [ # # ]: 0 : wpa_s->p2p_mgmt &&
1329 : 0 : (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE))
1330 : 0 : iface.ctrl_interface = wpa_s->parent->conf->ctrl_interface;
1331 : : else
1332 : 22 : iface.ctrl_interface = wpa_s->conf->ctrl_interface;
1333 : 22 : iface.driver_param = wpa_s->conf->driver_param;
1334 : 22 : group_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface);
1335 [ - + ]: 22 : if (group_wpa_s == NULL) {
1336 : 0 : wpa_printf(MSG_ERROR, "P2P: Failed to create new "
1337 : : "wpa_supplicant interface");
1338 : 0 : return NULL;
1339 : : }
1340 : 22 : wpa_s->pending_interface_name[0] = '\0';
1341 : 22 : group_wpa_s->parent = wpa_s;
1342 [ + + ]: 22 : group_wpa_s->p2p_group_interface = go ? P2P_GROUP_INTERFACE_GO :
1343 : : P2P_GROUP_INTERFACE_CLIENT;
1344 : 22 : wpa_s->global->p2p_group_formation = group_wpa_s;
1345 : :
1346 : 22 : wpas_p2p_clone_config(group_wpa_s, wpa_s);
1347 : :
1348 : 22 : return group_wpa_s;
1349 : : }
1350 : :
1351 : :
1352 : 0 : static void wpas_p2p_group_formation_timeout(void *eloop_ctx,
1353 : : void *timeout_ctx)
1354 : : {
1355 : 0 : struct wpa_supplicant *wpa_s = eloop_ctx;
1356 : 0 : wpa_printf(MSG_DEBUG, "P2P: Group Formation timed out");
1357 : 0 : wpas_p2p_group_formation_failed(wpa_s);
1358 : 0 : }
1359 : :
1360 : :
1361 : 0 : void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s)
1362 : : {
1363 : 0 : eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
1364 : 0 : wpa_s->parent, NULL);
1365 [ # # ]: 0 : if (wpa_s->global->p2p)
1366 : 0 : p2p_group_formation_failed(wpa_s->global->p2p);
1367 : 0 : wpas_group_formation_completed(wpa_s, 0);
1368 : 0 : }
1369 : :
1370 : :
1371 : 0 : void wpas_p2p_ap_setup_failed(struct wpa_supplicant *wpa_s)
1372 : : {
1373 [ # # ]: 0 : if (wpa_s->global->p2p_group_formation != wpa_s)
1374 : 0 : return;
1375 : : /* Speed up group formation timeout since this cannot succeed */
1376 : 0 : eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
1377 : 0 : wpa_s->parent, NULL);
1378 : 0 : eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
1379 : 0 : wpa_s->parent, NULL);
1380 : : }
1381 : :
1382 : :
1383 : 75 : static void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
1384 : : {
1385 : 75 : struct wpa_supplicant *wpa_s = ctx;
1386 : :
1387 [ + + ][ - + ]: 75 : if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
1388 : 21 : wpa_drv_cancel_remain_on_channel(wpa_s);
1389 : 21 : wpa_s->off_channel_freq = 0;
1390 : 21 : wpa_s->roc_waiting_drv_freq = 0;
1391 : : }
1392 : :
1393 [ + + ]: 75 : if (res->status) {
1394 : 5 : wpa_msg_global(wpa_s, MSG_INFO,
1395 : : P2P_EVENT_GO_NEG_FAILURE "status=%d",
1396 : : res->status);
1397 : 5 : wpas_notify_p2p_go_neg_completed(wpa_s, res);
1398 : 5 : wpas_p2p_remove_pending_group_interface(wpa_s);
1399 : 5 : return;
1400 : : }
1401 : :
1402 [ - + ]: 70 : if (wpa_s->p2p_go_ht40)
1403 : 0 : res->ht40 = 1;
1404 [ - + ]: 70 : if (wpa_s->p2p_go_vht)
1405 : 0 : res->vht = 1;
1406 : :
1407 [ + + ]: 70 : wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_SUCCESS "role=%s "
1408 : : "freq=%d ht40=%d peer_dev=" MACSTR " peer_iface=" MACSTR
1409 : : " wps_method=%s",
1410 : 70 : res->role_go ? "GO" : "client", res->freq, res->ht40,
1411 : 420 : MAC2STR(res->peer_device_addr),
1412 : 420 : MAC2STR(res->peer_interface_addr),
1413 : : p2p_wps_method_text(res->wps_method));
1414 : 70 : wpas_notify_p2p_go_neg_completed(wpa_s, res);
1415 : :
1416 [ + + ][ - + ]: 70 : if (res->role_go && wpa_s->p2p_persistent_id >= 0) {
1417 : : struct wpa_ssid *ssid;
1418 : 0 : ssid = wpa_config_get_network(wpa_s->conf,
1419 : : wpa_s->p2p_persistent_id);
1420 [ # # ][ # # ]: 0 : if (ssid && ssid->disabled == 2 &&
[ # # ]
1421 [ # # ]: 0 : ssid->mode == WPAS_MODE_P2P_GO && ssid->passphrase) {
1422 : 0 : size_t len = os_strlen(ssid->passphrase);
1423 : 0 : wpa_printf(MSG_DEBUG, "P2P: Override passphrase based "
1424 : : "on requested persistent group");
1425 : 0 : os_memcpy(res->passphrase, ssid->passphrase, len);
1426 : 0 : res->passphrase[len] = '\0';
1427 : : }
1428 : : }
1429 : :
1430 [ + + ]: 70 : if (wpa_s->create_p2p_iface) {
1431 : 16 : struct wpa_supplicant *group_wpa_s =
1432 : 16 : wpas_p2p_init_group_interface(wpa_s, res->role_go);
1433 [ - + ]: 16 : if (group_wpa_s == NULL) {
1434 : 0 : wpas_p2p_remove_pending_group_interface(wpa_s);
1435 : 0 : return;
1436 : : }
1437 [ + - ]: 16 : if (group_wpa_s != wpa_s) {
1438 : 16 : os_memcpy(group_wpa_s->p2p_pin, wpa_s->p2p_pin,
1439 : : sizeof(group_wpa_s->p2p_pin));
1440 : 16 : group_wpa_s->p2p_wps_method = wpa_s->p2p_wps_method;
1441 : : }
1442 : 16 : os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN);
1443 : 16 : wpa_s->pending_interface_name[0] = '\0';
1444 : 16 : group_wpa_s->p2p_in_provisioning = 1;
1445 : :
1446 [ + + ]: 16 : if (res->role_go)
1447 : 7 : wpas_start_wps_go(group_wpa_s, res, 1);
1448 : : else
1449 : 9 : wpas_start_wps_enrollee(group_wpa_s, res);
1450 : : } else {
1451 : 54 : wpa_s->p2p_in_provisioning = 1;
1452 : 54 : wpa_s->global->p2p_group_formation = wpa_s;
1453 : :
1454 [ + + ]: 54 : if (res->role_go)
1455 : 28 : wpas_start_wps_go(wpa_s, res, 1);
1456 : : else
1457 : 26 : wpas_start_wps_enrollee(ctx, res);
1458 : : }
1459 : :
1460 : 70 : wpa_s->p2p_long_listen = 0;
1461 : 70 : eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
1462 : :
1463 : 70 : eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
1464 : 75 : eloop_register_timeout(15 + res->peer_config_timeout / 100,
1465 : 70 : (res->peer_config_timeout % 100) * 10000,
1466 : : wpas_p2p_group_formation_timeout, wpa_s, NULL);
1467 : : }
1468 : :
1469 : :
1470 : 7 : static void wpas_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id)
1471 : : {
1472 : 7 : struct wpa_supplicant *wpa_s = ctx;
1473 : 7 : wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_REQUEST MACSTR
1474 : 42 : " dev_passwd_id=%u", MAC2STR(src), dev_passwd_id);
1475 : :
1476 : 7 : wpas_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id);
1477 : 7 : }
1478 : :
1479 : :
1480 : 140 : static void wpas_dev_found(void *ctx, const u8 *addr,
1481 : : const struct p2p_peer_info *info,
1482 : : int new_device)
1483 : : {
1484 : : #ifndef CONFIG_NO_STDOUT_DEBUG
1485 : 140 : struct wpa_supplicant *wpa_s = ctx;
1486 : : char devtype[WPS_DEV_TYPE_BUFSIZE];
1487 : 140 : char *wfd_dev_info_hex = NULL;
1488 : :
1489 : : #ifdef CONFIG_WIFI_DISPLAY
1490 : 140 : wfd_dev_info_hex = wifi_display_subelem_hex(info->wfd_subelems,
1491 : : WFD_SUBELEM_DEVICE_INFO);
1492 : : #endif /* CONFIG_WIFI_DISPLAY */
1493 : :
1494 [ + + ][ + + ]: 140 : wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_FOUND MACSTR
1495 : : " p2p_dev_addr=" MACSTR
1496 : : " pri_dev_type=%s name='%s' config_methods=0x%x "
1497 : : "dev_capab=0x%x group_capab=0x%x%s%s",
1498 : 1680 : MAC2STR(addr), MAC2STR(info->p2p_device_addr),
1499 : 140 : wps_dev_type_bin2str(info->pri_dev_type, devtype,
1500 : : sizeof(devtype)),
1501 : 280 : info->device_name, info->config_methods,
1502 : 280 : info->dev_capab, info->group_capab,
1503 : : wfd_dev_info_hex ? " wfd_dev_info=0x" : "",
1504 : : wfd_dev_info_hex ? wfd_dev_info_hex : "");
1505 : : #endif /* CONFIG_NO_STDOUT_DEBUG */
1506 : :
1507 : 140 : os_free(wfd_dev_info_hex);
1508 : :
1509 : 140 : wpas_notify_p2p_device_found(ctx, info->p2p_device_addr, new_device);
1510 : 140 : }
1511 : :
1512 : :
1513 : 140 : static void wpas_dev_lost(void *ctx, const u8 *dev_addr)
1514 : : {
1515 : 140 : struct wpa_supplicant *wpa_s = ctx;
1516 : :
1517 : 140 : wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_LOST
1518 : 840 : "p2p_dev_addr=" MACSTR, MAC2STR(dev_addr));
1519 : :
1520 : 140 : wpas_notify_p2p_device_lost(wpa_s, dev_addr);
1521 : 140 : }
1522 : :
1523 : :
1524 : 107 : static void wpas_find_stopped(void *ctx)
1525 : : {
1526 : 107 : struct wpa_supplicant *wpa_s = ctx;
1527 : 107 : wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_FIND_STOPPED);
1528 : 107 : }
1529 : :
1530 : :
1531 : : struct wpas_p2p_listen_work {
1532 : : unsigned int freq;
1533 : : unsigned int duration;
1534 : : struct wpabuf *probe_resp_ie;
1535 : : };
1536 : :
1537 : :
1538 : 521 : static void wpas_p2p_listen_work_free(struct wpas_p2p_listen_work *lwork)
1539 : : {
1540 [ - + ]: 521 : if (lwork == NULL)
1541 : 521 : return;
1542 : 521 : wpabuf_free(lwork->probe_resp_ie);
1543 : 521 : os_free(lwork);
1544 : : }
1545 : :
1546 : :
1547 : 2686 : static void wpas_p2p_listen_work_done(struct wpa_supplicant *wpa_s)
1548 : : {
1549 : : struct wpas_p2p_listen_work *lwork;
1550 : :
1551 [ + + ]: 2686 : if (!wpa_s->p2p_listen_work)
1552 : 2686 : return;
1553 : :
1554 : 521 : lwork = wpa_s->p2p_listen_work->ctx;
1555 : 521 : wpas_p2p_listen_work_free(lwork);
1556 : 521 : radio_work_done(wpa_s->p2p_listen_work);
1557 : 521 : wpa_s->p2p_listen_work = NULL;
1558 : : }
1559 : :
1560 : :
1561 : 521 : static void wpas_start_listen_cb(struct wpa_radio_work *work, int deinit)
1562 : : {
1563 : 521 : struct wpa_supplicant *wpa_s = work->wpa_s;
1564 : 521 : struct wpas_p2p_listen_work *lwork = work->ctx;
1565 : :
1566 [ - + ]: 521 : if (deinit) {
1567 : 0 : wpas_p2p_listen_work_free(lwork);
1568 : 0 : return;
1569 : : }
1570 : :
1571 : 521 : wpa_s->p2p_listen_work = work;
1572 : :
1573 : 521 : wpa_drv_set_ap_wps_ie(wpa_s, NULL, lwork->probe_resp_ie, NULL);
1574 : :
1575 [ - + ]: 521 : if (wpa_drv_probe_req_report(wpa_s, 1) < 0) {
1576 : 0 : wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to "
1577 : : "report received Probe Request frames");
1578 : 0 : wpas_p2p_listen_work_done(wpa_s);
1579 : 0 : return;
1580 : : }
1581 : :
1582 : 521 : wpa_s->pending_listen_freq = lwork->freq;
1583 : 521 : wpa_s->pending_listen_duration = lwork->duration;
1584 : :
1585 [ - + ]: 521 : if (wpa_drv_remain_on_channel(wpa_s, lwork->freq, lwork->duration) < 0)
1586 : : {
1587 : 0 : wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver "
1588 : : "to remain on channel (%u MHz) for Listen "
1589 : : "state", lwork->freq);
1590 : 0 : wpas_p2p_listen_work_done(wpa_s);
1591 : 0 : wpa_s->pending_listen_freq = 0;
1592 : 0 : return;
1593 : : }
1594 : 521 : wpa_s->off_channel_freq = 0;
1595 : 521 : wpa_s->roc_waiting_drv_freq = lwork->freq;
1596 : : }
1597 : :
1598 : :
1599 : 521 : static int wpas_start_listen(void *ctx, unsigned int freq,
1600 : : unsigned int duration,
1601 : : const struct wpabuf *probe_resp_ie)
1602 : : {
1603 : 521 : struct wpa_supplicant *wpa_s = ctx;
1604 : : struct wpas_p2p_listen_work *lwork;
1605 : :
1606 [ - + ]: 521 : if (wpa_s->p2p_listen_work) {
1607 : 0 : wpa_printf(MSG_DEBUG, "P2P: Reject start_listen since p2p_listen_work already exists");
1608 : 0 : return -1;
1609 : : }
1610 : :
1611 : 521 : lwork = os_zalloc(sizeof(*lwork));
1612 [ - + ]: 521 : if (lwork == NULL)
1613 : 0 : return -1;
1614 : 521 : lwork->freq = freq;
1615 : 521 : lwork->duration = duration;
1616 [ + - ]: 521 : if (probe_resp_ie) {
1617 : 521 : lwork->probe_resp_ie = wpabuf_dup(probe_resp_ie);
1618 [ - + ]: 521 : if (lwork->probe_resp_ie == NULL) {
1619 : 0 : wpas_p2p_listen_work_free(lwork);
1620 : 0 : return -1;
1621 : : }
1622 : : }
1623 : :
1624 [ - + ]: 521 : if (radio_add_work(wpa_s, 0, "p2p-listen", freq, wpas_start_listen_cb,
1625 : : lwork) < 0) {
1626 : 0 : wpas_p2p_listen_work_free(lwork);
1627 : 0 : return -1;
1628 : : }
1629 : :
1630 : 521 : return 0;
1631 : : }
1632 : :
1633 : :
1634 : 2135 : static void wpas_stop_listen(void *ctx)
1635 : : {
1636 : 2135 : struct wpa_supplicant *wpa_s = ctx;
1637 [ + + ][ + + ]: 2135 : if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
1638 : 128 : wpa_drv_cancel_remain_on_channel(wpa_s);
1639 : 128 : wpa_s->off_channel_freq = 0;
1640 : 128 : wpa_s->roc_waiting_drv_freq = 0;
1641 : : }
1642 : 2135 : wpa_drv_set_ap_wps_ie(wpa_s, NULL, NULL, NULL);
1643 : 2135 : wpa_drv_probe_req_report(wpa_s, 0);
1644 : 2135 : wpas_p2p_listen_work_done(wpa_s);
1645 : 2135 : }
1646 : :
1647 : :
1648 : 248 : static int wpas_send_probe_resp(void *ctx, const struct wpabuf *buf)
1649 : : {
1650 : 248 : struct wpa_supplicant *wpa_s = ctx;
1651 : 248 : return wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1);
1652 : : }
1653 : :
1654 : :
1655 : : /*
1656 : : * DNS Header section is used only to calculate compression pointers, so the
1657 : : * contents of this data does not matter, but the length needs to be reserved
1658 : : * in the virtual packet.
1659 : : */
1660 : : #define DNS_HEADER_LEN 12
1661 : :
1662 : : /*
1663 : : * 27-octet in-memory packet from P2P specification containing two implied
1664 : : * queries for _tcp.lcoal. PTR IN and _udp.local. PTR IN
1665 : : */
1666 : : #define P2P_SD_IN_MEMORY_LEN 27
1667 : :
1668 : 4 : static int p2p_sd_dns_uncompress_label(char **upos, char *uend, u8 *start,
1669 : : u8 **spos, const u8 *end)
1670 : : {
1671 [ + - ]: 10 : while (*spos < end) {
1672 : 10 : u8 val = ((*spos)[0] & 0xc0) >> 6;
1673 : : int len;
1674 : :
1675 [ + - ][ - + ]: 10 : if (val == 1 || val == 2) {
1676 : : /* These are reserved values in RFC 1035 */
1677 : 0 : wpa_printf(MSG_DEBUG, "P2P: Invalid domain name "
1678 : : "sequence starting with 0x%x", val);
1679 : 0 : return -1;
1680 : : }
1681 : :
1682 [ + + ]: 10 : if (val == 3) {
1683 : : u16 offset;
1684 : : u8 *spos_tmp;
1685 : :
1686 : : /* Offset */
1687 [ - + ]: 2 : if (*spos + 2 > end) {
1688 : 0 : wpa_printf(MSG_DEBUG, "P2P: No room for full "
1689 : : "DNS offset field");
1690 : 0 : return -1;
1691 : : }
1692 : :
1693 : 2 : offset = (((*spos)[0] & 0x3f) << 8) | (*spos)[1];
1694 [ - + ]: 2 : if (offset >= *spos - start) {
1695 : 0 : wpa_printf(MSG_DEBUG, "P2P: Invalid DNS "
1696 : : "pointer offset %u", offset);
1697 : 0 : return -1;
1698 : : }
1699 : :
1700 : 2 : (*spos) += 2;
1701 : 2 : spos_tmp = start + offset;
1702 : 2 : return p2p_sd_dns_uncompress_label(upos, uend, start,
1703 : : &spos_tmp,
1704 : 2 : *spos - 2);
1705 : : }
1706 : :
1707 : : /* Label */
1708 : 8 : len = (*spos)[0] & 0x3f;
1709 [ + + ]: 8 : if (len == 0)
1710 : 2 : return 0;
1711 : :
1712 : 6 : (*spos)++;
1713 [ - + ]: 6 : if (*spos + len > end) {
1714 : 0 : wpa_printf(MSG_DEBUG, "P2P: Invalid domain name "
1715 : : "sequence - no room for label with length "
1716 : : "%u", len);
1717 : 0 : return -1;
1718 : : }
1719 : :
1720 [ - + ]: 6 : if (*upos + len + 2 > uend)
1721 : 0 : return -2;
1722 : :
1723 : 6 : os_memcpy(*upos, *spos, len);
1724 : 6 : *spos += len;
1725 : 6 : *upos += len;
1726 : 6 : (*upos)[0] = '.';
1727 : 6 : (*upos)++;
1728 : 6 : (*upos)[0] = '\0';
1729 : : }
1730 : :
1731 : 4 : return 0;
1732 : : }
1733 : :
1734 : :
1735 : : /* Uncompress domain names per RFC 1035 using the P2P SD in-memory packet.
1736 : : * Returns -1 on parsing error (invalid input sequence), -2 if output buffer is
1737 : : * not large enough */
1738 : 2 : static int p2p_sd_dns_uncompress(char *buf, size_t buf_len, const u8 *msg,
1739 : : size_t msg_len, size_t offset)
1740 : : {
1741 : : /* 27-octet in-memory packet from P2P specification */
1742 : 2 : const char *prefix = "\x04_tcp\x05local\x00\x00\x0C\x00\x01"
1743 : : "\x04_udp\xC0\x11\x00\x0C\x00\x01";
1744 : : u8 *tmp, *end, *spos;
1745 : : char *upos, *uend;
1746 : 2 : int ret = 0;
1747 : :
1748 [ - + ]: 2 : if (buf_len < 2)
1749 : 0 : return -1;
1750 [ - + ]: 2 : if (offset > msg_len)
1751 : 0 : return -1;
1752 : :
1753 : 2 : tmp = os_malloc(DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN + msg_len);
1754 [ - + ]: 2 : if (tmp == NULL)
1755 : 0 : return -1;
1756 : 2 : spos = tmp + DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN;
1757 : 2 : end = spos + msg_len;
1758 : 2 : spos += offset;
1759 : :
1760 : 2 : os_memset(tmp, 0, DNS_HEADER_LEN);
1761 : 2 : os_memcpy(tmp + DNS_HEADER_LEN, prefix, P2P_SD_IN_MEMORY_LEN);
1762 : 2 : os_memcpy(tmp + DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN, msg, msg_len);
1763 : :
1764 : 2 : upos = buf;
1765 : 2 : uend = buf + buf_len;
1766 : :
1767 : 2 : ret = p2p_sd_dns_uncompress_label(&upos, uend, tmp, &spos, end);
1768 [ - + ]: 2 : if (ret) {
1769 : 0 : os_free(tmp);
1770 : 0 : return ret;
1771 : : }
1772 : :
1773 [ - + ]: 2 : if (upos == buf) {
1774 : 0 : upos[0] = '.';
1775 : 0 : upos[1] = '\0';
1776 [ + - ]: 2 : } else if (upos[-1] == '.')
1777 : 2 : upos[-1] = '\0';
1778 : :
1779 : 2 : os_free(tmp);
1780 : 2 : return 0;
1781 : : }
1782 : :
1783 : :
1784 : : static struct p2p_srv_bonjour *
1785 : 0 : wpas_p2p_service_get_bonjour(struct wpa_supplicant *wpa_s,
1786 : : const struct wpabuf *query)
1787 : : {
1788 : : struct p2p_srv_bonjour *bsrv;
1789 : : size_t len;
1790 : :
1791 : 0 : len = wpabuf_len(query);
1792 [ # # ]: 0 : dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour,
1793 : : struct p2p_srv_bonjour, list) {
1794 [ # # # # ]: 0 : if (len == wpabuf_len(bsrv->query) &&
1795 : 0 : os_memcmp(wpabuf_head(query), wpabuf_head(bsrv->query),
1796 : : len) == 0)
1797 : 0 : return bsrv;
1798 : : }
1799 : 0 : return NULL;
1800 : : }
1801 : :
1802 : :
1803 : : static struct p2p_srv_upnp *
1804 : 245 : wpas_p2p_service_get_upnp(struct wpa_supplicant *wpa_s, u8 version,
1805 : : const char *service)
1806 : : {
1807 : : struct p2p_srv_upnp *usrv;
1808 : :
1809 [ + + ]: 21735 : dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp,
1810 : : struct p2p_srv_upnp, list) {
1811 [ + - ][ + + ]: 21500 : if (version == usrv->version &&
1812 : 21500 : os_strcmp(service, usrv->service) == 0)
1813 : 10 : return usrv;
1814 : : }
1815 : 245 : return NULL;
1816 : : }
1817 : :
1818 : :
1819 : 1 : static void wpas_sd_add_proto_not_avail(struct wpabuf *resp, u8 srv_proto,
1820 : : u8 srv_trans_id)
1821 : : {
1822 : : u8 *len_pos;
1823 : :
1824 [ - + ]: 1 : if (wpabuf_tailroom(resp) < 5)
1825 : 1 : return;
1826 : :
1827 : : /* Length (to be filled) */
1828 : 1 : len_pos = wpabuf_put(resp, 2);
1829 : 1 : wpabuf_put_u8(resp, srv_proto);
1830 : 1 : wpabuf_put_u8(resp, srv_trans_id);
1831 : : /* Status Code */
1832 : 1 : wpabuf_put_u8(resp, P2P_SD_PROTO_NOT_AVAILABLE);
1833 : : /* Response Data: empty */
1834 : 1 : WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2);
1835 : : }
1836 : :
1837 : :
1838 : 5 : static void wpas_sd_all_bonjour(struct wpa_supplicant *wpa_s,
1839 : : struct wpabuf *resp, u8 srv_trans_id)
1840 : : {
1841 : : struct p2p_srv_bonjour *bsrv;
1842 : : u8 *len_pos;
1843 : :
1844 : 5 : wpa_printf(MSG_DEBUG, "P2P: SD Request for all Bonjour services");
1845 : :
1846 [ - + ]: 5 : if (dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) {
1847 : 0 : wpa_printf(MSG_DEBUG, "P2P: Bonjour protocol not available");
1848 : 0 : return;
1849 : : }
1850 : :
1851 [ + + ]: 33 : dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour,
1852 : : struct p2p_srv_bonjour, list) {
1853 [ - + ]: 56 : if (wpabuf_tailroom(resp) <
1854 : 28 : 5 + wpabuf_len(bsrv->query) + wpabuf_len(bsrv->resp))
1855 : 0 : return;
1856 : : /* Length (to be filled) */
1857 : 28 : len_pos = wpabuf_put(resp, 2);
1858 : 28 : wpabuf_put_u8(resp, P2P_SERV_BONJOUR);
1859 : 28 : wpabuf_put_u8(resp, srv_trans_id);
1860 : : /* Status Code */
1861 : 28 : wpabuf_put_u8(resp, P2P_SD_SUCCESS);
1862 : 28 : wpa_hexdump_ascii(MSG_DEBUG, "P2P: Matching Bonjour service",
1863 : 28 : wpabuf_head(bsrv->resp),
1864 : 28 : wpabuf_len(bsrv->resp));
1865 : : /* Response Data */
1866 : 28 : wpabuf_put_buf(resp, bsrv->query); /* Key */
1867 : 28 : wpabuf_put_buf(resp, bsrv->resp); /* Value */
1868 : 28 : WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos -
1869 : : 2);
1870 : : }
1871 : : }
1872 : :
1873 : :
1874 : 4 : static int match_bonjour_query(struct p2p_srv_bonjour *bsrv, const u8 *query,
1875 : : size_t query_len)
1876 : : {
1877 : : char str_rx[256], str_srv[256];
1878 : :
1879 [ + - ][ - + ]: 4 : if (query_len < 3 || wpabuf_len(bsrv->query) < 3)
1880 : 0 : return 0; /* Too short to include DNS Type and Version */
1881 [ + + ]: 4 : if (os_memcmp(query + query_len - 3,
1882 : : wpabuf_head_u8(bsrv->query) + wpabuf_len(bsrv->query) - 3,
1883 : : 3) != 0)
1884 : 2 : return 0; /* Mismatch in DNS Type or Version */
1885 [ + + + - ]: 3 : if (query_len == wpabuf_len(bsrv->query) &&
1886 : 1 : os_memcmp(query, wpabuf_head(bsrv->query), query_len - 3) == 0)
1887 : 1 : return 1; /* Binary match */
1888 : :
1889 [ - + ]: 1 : if (p2p_sd_dns_uncompress(str_rx, sizeof(str_rx), query, query_len - 3,
1890 : : 0))
1891 : 0 : return 0; /* Failed to uncompress query */
1892 [ - + ]: 1 : if (p2p_sd_dns_uncompress(str_srv, sizeof(str_srv),
1893 : 1 : wpabuf_head(bsrv->query),
1894 : 1 : wpabuf_len(bsrv->query) - 3, 0))
1895 : 0 : return 0; /* Failed to uncompress service */
1896 : :
1897 : 4 : return os_strcmp(str_rx, str_srv) == 0;
1898 : : }
1899 : :
1900 : :
1901 : 2 : static void wpas_sd_req_bonjour(struct wpa_supplicant *wpa_s,
1902 : : struct wpabuf *resp, u8 srv_trans_id,
1903 : : const u8 *query, size_t query_len)
1904 : : {
1905 : : struct p2p_srv_bonjour *bsrv;
1906 : : u8 *len_pos;
1907 : 2 : int matches = 0;
1908 : :
1909 : 2 : wpa_hexdump_ascii(MSG_DEBUG, "P2P: SD Request for Bonjour",
1910 : : query, query_len);
1911 [ - + ]: 2 : if (dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) {
1912 : 0 : wpa_printf(MSG_DEBUG, "P2P: Bonjour protocol not available");
1913 : 0 : wpas_sd_add_proto_not_avail(resp, P2P_SERV_BONJOUR,
1914 : : srv_trans_id);
1915 : 0 : return;
1916 : : }
1917 : :
1918 [ + + ]: 2 : if (query_len == 0) {
1919 : 1 : wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id);
1920 : 1 : return;
1921 : : }
1922 : :
1923 [ + + ]: 5 : dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour,
1924 : : struct p2p_srv_bonjour, list) {
1925 [ + + ]: 4 : if (!match_bonjour_query(bsrv, query, query_len))
1926 : 3 : continue;
1927 : :
1928 [ - + ]: 2 : if (wpabuf_tailroom(resp) <
1929 : 1 : 5 + query_len + wpabuf_len(bsrv->resp))
1930 : 0 : return;
1931 : :
1932 : 1 : matches++;
1933 : :
1934 : : /* Length (to be filled) */
1935 : 1 : len_pos = wpabuf_put(resp, 2);
1936 : 1 : wpabuf_put_u8(resp, P2P_SERV_BONJOUR);
1937 : 1 : wpabuf_put_u8(resp, srv_trans_id);
1938 : :
1939 : : /* Status Code */
1940 : 1 : wpabuf_put_u8(resp, P2P_SD_SUCCESS);
1941 : 1 : wpa_hexdump_ascii(MSG_DEBUG, "P2P: Matching Bonjour service",
1942 : 1 : wpabuf_head(bsrv->resp),
1943 : 1 : wpabuf_len(bsrv->resp));
1944 : :
1945 : : /* Response Data */
1946 : 1 : wpabuf_put_data(resp, query, query_len); /* Key */
1947 : 1 : wpabuf_put_buf(resp, bsrv->resp); /* Value */
1948 : :
1949 : 1 : WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2);
1950 : : }
1951 : :
1952 [ - + ]: 1 : if (matches == 0) {
1953 : 0 : wpa_printf(MSG_DEBUG, "P2P: Requested Bonjour service not "
1954 : : "available");
1955 [ # # ]: 0 : if (wpabuf_tailroom(resp) < 5)
1956 : 0 : return;
1957 : :
1958 : : /* Length (to be filled) */
1959 : 0 : len_pos = wpabuf_put(resp, 2);
1960 : 0 : wpabuf_put_u8(resp, P2P_SERV_BONJOUR);
1961 : 0 : wpabuf_put_u8(resp, srv_trans_id);
1962 : :
1963 : : /* Status Code */
1964 : 0 : wpabuf_put_u8(resp, P2P_SD_REQUESTED_INFO_NOT_AVAILABLE);
1965 : : /* Response Data: empty */
1966 : 2 : WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos -
1967 : : 2);
1968 : : }
1969 : : }
1970 : :
1971 : :
1972 : 5 : static void wpas_sd_all_upnp(struct wpa_supplicant *wpa_s,
1973 : : struct wpabuf *resp, u8 srv_trans_id)
1974 : : {
1975 : : struct p2p_srv_upnp *usrv;
1976 : : u8 *len_pos;
1977 : :
1978 : 5 : wpa_printf(MSG_DEBUG, "P2P: SD Request for all UPnP services");
1979 : :
1980 [ - + ]: 5 : if (dl_list_empty(&wpa_s->global->p2p_srv_upnp)) {
1981 : 0 : wpa_printf(MSG_DEBUG, "P2P: UPnP protocol not available");
1982 : 0 : return;
1983 : : }
1984 : :
1985 [ + + ]: 277 : dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp,
1986 : : struct p2p_srv_upnp, list) {
1987 [ + + ]: 272 : if (wpabuf_tailroom(resp) < 5 + 1 + os_strlen(usrv->service))
1988 : 1 : return;
1989 : :
1990 : : /* Length (to be filled) */
1991 : 271 : len_pos = wpabuf_put(resp, 2);
1992 : 271 : wpabuf_put_u8(resp, P2P_SERV_UPNP);
1993 : 271 : wpabuf_put_u8(resp, srv_trans_id);
1994 : :
1995 : : /* Status Code */
1996 : 271 : wpabuf_put_u8(resp, P2P_SD_SUCCESS);
1997 : : /* Response Data */
1998 : 271 : wpabuf_put_u8(resp, usrv->version);
1999 : 271 : wpa_printf(MSG_DEBUG, "P2P: Matching UPnP Service: %s",
2000 : : usrv->service);
2001 : 271 : wpabuf_put_str(resp, usrv->service);
2002 : 271 : WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos -
2003 : : 2);
2004 : : }
2005 : : }
2006 : :
2007 : :
2008 : 2 : static void wpas_sd_req_upnp(struct wpa_supplicant *wpa_s,
2009 : : struct wpabuf *resp, u8 srv_trans_id,
2010 : : const u8 *query, size_t query_len)
2011 : : {
2012 : : struct p2p_srv_upnp *usrv;
2013 : : u8 *len_pos;
2014 : : u8 version;
2015 : : char *str;
2016 : 2 : int count = 0;
2017 : :
2018 : 2 : wpa_hexdump_ascii(MSG_DEBUG, "P2P: SD Request for UPnP",
2019 : : query, query_len);
2020 : :
2021 [ - + ]: 2 : if (dl_list_empty(&wpa_s->global->p2p_srv_upnp)) {
2022 : 0 : wpa_printf(MSG_DEBUG, "P2P: UPnP protocol not available");
2023 : 0 : wpas_sd_add_proto_not_avail(resp, P2P_SERV_UPNP,
2024 : : srv_trans_id);
2025 : 0 : return;
2026 : : }
2027 : :
2028 [ + + ]: 2 : if (query_len == 0) {
2029 : 1 : wpas_sd_all_upnp(wpa_s, resp, srv_trans_id);
2030 : 1 : return;
2031 : : }
2032 : :
2033 [ - + ]: 1 : if (wpabuf_tailroom(resp) < 5)
2034 : 0 : return;
2035 : :
2036 : : /* Length (to be filled) */
2037 : 1 : len_pos = wpabuf_put(resp, 2);
2038 : 1 : wpabuf_put_u8(resp, P2P_SERV_UPNP);
2039 : 1 : wpabuf_put_u8(resp, srv_trans_id);
2040 : :
2041 : 1 : version = query[0];
2042 : 1 : str = os_malloc(query_len);
2043 [ - + ]: 1 : if (str == NULL)
2044 : 0 : return;
2045 : 1 : os_memcpy(str, query + 1, query_len - 1);
2046 : 1 : str[query_len - 1] = '\0';
2047 : :
2048 [ + + ]: 6 : dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp,
2049 : : struct p2p_srv_upnp, list) {
2050 [ - + ]: 5 : if (version != usrv->version)
2051 : 0 : continue;
2052 : :
2053 [ - + ][ # # ]: 5 : if (os_strcmp(str, "ssdp:all") != 0 &&
2054 : 0 : os_strstr(usrv->service, str) == NULL)
2055 : 0 : continue;
2056 : :
2057 [ - + ]: 5 : if (wpabuf_tailroom(resp) < 2)
2058 : 0 : break;
2059 [ + + ]: 5 : if (count == 0) {
2060 : : /* Status Code */
2061 : 1 : wpabuf_put_u8(resp, P2P_SD_SUCCESS);
2062 : : /* Response Data */
2063 : 1 : wpabuf_put_u8(resp, version);
2064 : : } else
2065 : 4 : wpabuf_put_u8(resp, ',');
2066 : :
2067 : 5 : count++;
2068 : :
2069 : 5 : wpa_printf(MSG_DEBUG, "P2P: Matching UPnP Service: %s",
2070 : : usrv->service);
2071 [ - + ]: 5 : if (wpabuf_tailroom(resp) < os_strlen(usrv->service))
2072 : 0 : break;
2073 : 5 : wpabuf_put_str(resp, usrv->service);
2074 : : }
2075 : 1 : os_free(str);
2076 : :
2077 [ - + ]: 1 : if (count == 0) {
2078 : 0 : wpa_printf(MSG_DEBUG, "P2P: Requested UPnP service not "
2079 : : "available");
2080 : : /* Status Code */
2081 : 0 : wpabuf_put_u8(resp, P2P_SD_REQUESTED_INFO_NOT_AVAILABLE);
2082 : : /* Response Data: empty */
2083 : : }
2084 : :
2085 : 2 : WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2);
2086 : : }
2087 : :
2088 : :
2089 : : #ifdef CONFIG_WIFI_DISPLAY
2090 : 0 : static void wpas_sd_req_wfd(struct wpa_supplicant *wpa_s,
2091 : : struct wpabuf *resp, u8 srv_trans_id,
2092 : : const u8 *query, size_t query_len)
2093 : : {
2094 : : const u8 *pos;
2095 : : u8 role;
2096 : : u8 *len_pos;
2097 : :
2098 : 0 : wpa_hexdump(MSG_DEBUG, "P2P: SD Request for WFD", query, query_len);
2099 : :
2100 [ # # ]: 0 : if (!wpa_s->global->wifi_display) {
2101 : 0 : wpa_printf(MSG_DEBUG, "P2P: WFD protocol not available");
2102 : 0 : wpas_sd_add_proto_not_avail(resp, P2P_SERV_WIFI_DISPLAY,
2103 : : srv_trans_id);
2104 : 0 : return;
2105 : : }
2106 : :
2107 [ # # ]: 0 : if (query_len < 1) {
2108 : 0 : wpa_printf(MSG_DEBUG, "P2P: Missing WFD Requested Device "
2109 : : "Role");
2110 : 0 : return;
2111 : : }
2112 : :
2113 [ # # ]: 0 : if (wpabuf_tailroom(resp) < 5)
2114 : 0 : return;
2115 : :
2116 : 0 : pos = query;
2117 : 0 : role = *pos++;
2118 : 0 : wpa_printf(MSG_DEBUG, "P2P: WSD for device role 0x%x", role);
2119 : :
2120 : : /* TODO: role specific handling */
2121 : :
2122 : : /* Length (to be filled) */
2123 : 0 : len_pos = wpabuf_put(resp, 2);
2124 : 0 : wpabuf_put_u8(resp, P2P_SERV_WIFI_DISPLAY);
2125 : 0 : wpabuf_put_u8(resp, srv_trans_id);
2126 : 0 : wpabuf_put_u8(resp, P2P_SD_SUCCESS); /* Status Code */
2127 : :
2128 [ # # ]: 0 : while (pos < query + query_len) {
2129 [ # # ][ # # ]: 0 : if (*pos < MAX_WFD_SUBELEMS &&
2130 [ # # ]: 0 : wpa_s->global->wfd_subelem[*pos] &&
2131 : 0 : wpabuf_tailroom(resp) >=
2132 : 0 : wpabuf_len(wpa_s->global->wfd_subelem[*pos])) {
2133 : 0 : wpa_printf(MSG_DEBUG, "P2P: Add WSD response "
2134 : 0 : "subelement %u", *pos);
2135 : 0 : wpabuf_put_buf(resp, wpa_s->global->wfd_subelem[*pos]);
2136 : : }
2137 : 0 : pos++;
2138 : : }
2139 : :
2140 : 0 : WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2);
2141 : : }
2142 : : #endif /* CONFIG_WIFI_DISPLAY */
2143 : :
2144 : :
2145 : 9 : static void wpas_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token,
2146 : : u16 update_indic, const u8 *tlvs, size_t tlvs_len)
2147 : : {
2148 : 9 : struct wpa_supplicant *wpa_s = ctx;
2149 : 9 : const u8 *pos = tlvs;
2150 : 9 : const u8 *end = tlvs + tlvs_len;
2151 : : const u8 *tlv_end;
2152 : : u16 slen;
2153 : : struct wpabuf *resp;
2154 : : u8 srv_proto, srv_trans_id;
2155 : : size_t buf_len;
2156 : : char *buf;
2157 : :
2158 : 9 : wpa_hexdump(MSG_MSGDUMP, "P2P: Service Discovery Request TLVs",
2159 : : tlvs, tlvs_len);
2160 : 9 : buf_len = 2 * tlvs_len + 1;
2161 : 9 : buf = os_malloc(buf_len);
2162 [ + - ]: 9 : if (buf) {
2163 : 9 : wpa_snprintf_hex(buf, buf_len, tlvs, tlvs_len);
2164 : 9 : wpa_msg_ctrl(wpa_s, MSG_INFO, P2P_EVENT_SERV_DISC_REQ "%d "
2165 : : MACSTR " %u %u %s",
2166 : 54 : freq, MAC2STR(sa), dialog_token, update_indic,
2167 : : buf);
2168 : 9 : os_free(buf);
2169 : : }
2170 : :
2171 [ - + ]: 9 : if (wpa_s->p2p_sd_over_ctrl_iface) {
2172 : 0 : wpas_notify_p2p_sd_request(wpa_s, freq, sa, dialog_token,
2173 : : update_indic, tlvs, tlvs_len);
2174 : 0 : return; /* to be processed by an external program */
2175 : : }
2176 : :
2177 : 9 : resp = wpabuf_alloc(10000);
2178 [ - + ]: 9 : if (resp == NULL)
2179 : 0 : return;
2180 : :
2181 [ + + ]: 18 : while (pos + 1 < end) {
2182 : 9 : wpa_printf(MSG_DEBUG, "P2P: Service Request TLV");
2183 : 9 : slen = WPA_GET_LE16(pos);
2184 : 9 : pos += 2;
2185 [ + - ][ - + ]: 9 : if (pos + slen > end || slen < 2) {
2186 : 0 : wpa_printf(MSG_DEBUG, "P2P: Unexpected Query Data "
2187 : : "length");
2188 : 0 : wpabuf_free(resp);
2189 : 0 : return;
2190 : : }
2191 : 9 : tlv_end = pos + slen;
2192 : :
2193 : 9 : srv_proto = *pos++;
2194 : 9 : wpa_printf(MSG_DEBUG, "P2P: Service Protocol Type %u",
2195 : : srv_proto);
2196 : 9 : srv_trans_id = *pos++;
2197 : 9 : wpa_printf(MSG_DEBUG, "P2P: Service Transaction ID %u",
2198 : : srv_trans_id);
2199 : :
2200 : 9 : wpa_hexdump(MSG_MSGDUMP, "P2P: Query Data",
2201 : 9 : pos, tlv_end - pos);
2202 : :
2203 : :
2204 [ - + ]: 9 : if (wpa_s->force_long_sd) {
2205 : 0 : wpa_printf(MSG_DEBUG, "P2P: SD test - force long "
2206 : : "response");
2207 : 0 : wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id);
2208 : 0 : wpas_sd_all_upnp(wpa_s, resp, srv_trans_id);
2209 : 0 : goto done;
2210 : : }
2211 : :
2212 [ + + + - : 9 : switch (srv_proto) {
+ ]
2213 : : case P2P_SERV_ALL_SERVICES:
2214 : 4 : wpa_printf(MSG_DEBUG, "P2P: Service Discovery Request "
2215 : : "for all services");
2216 [ - + # # ]: 4 : if (dl_list_empty(&wpa_s->global->p2p_srv_upnp) &&
2217 : 0 : dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) {
2218 : 0 : wpa_printf(MSG_DEBUG, "P2P: No service "
2219 : : "discovery protocols available");
2220 : 0 : wpas_sd_add_proto_not_avail(
2221 : : resp, P2P_SERV_ALL_SERVICES,
2222 : : srv_trans_id);
2223 : 0 : break;
2224 : : }
2225 : 4 : wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id);
2226 : 4 : wpas_sd_all_upnp(wpa_s, resp, srv_trans_id);
2227 : 4 : break;
2228 : : case P2P_SERV_BONJOUR:
2229 : 2 : wpas_sd_req_bonjour(wpa_s, resp, srv_trans_id,
2230 : 2 : pos, tlv_end - pos);
2231 : 2 : break;
2232 : : case P2P_SERV_UPNP:
2233 : 2 : wpas_sd_req_upnp(wpa_s, resp, srv_trans_id,
2234 : 2 : pos, tlv_end - pos);
2235 : 2 : break;
2236 : : #ifdef CONFIG_WIFI_DISPLAY
2237 : : case P2P_SERV_WIFI_DISPLAY:
2238 : 0 : wpas_sd_req_wfd(wpa_s, resp, srv_trans_id,
2239 : 0 : pos, tlv_end - pos);
2240 : 0 : break;
2241 : : #endif /* CONFIG_WIFI_DISPLAY */
2242 : : default:
2243 : 1 : wpa_printf(MSG_DEBUG, "P2P: Unavailable service "
2244 : : "protocol %u", srv_proto);
2245 : 1 : wpas_sd_add_proto_not_avail(resp, srv_proto,
2246 : : srv_trans_id);
2247 : 1 : break;
2248 : : }
2249 : :
2250 : 9 : pos = tlv_end;
2251 : : }
2252 : :
2253 : : done:
2254 : 9 : wpas_notify_p2p_sd_request(wpa_s, freq, sa, dialog_token,
2255 : : update_indic, tlvs, tlvs_len);
2256 : :
2257 : 9 : wpas_p2p_sd_response(wpa_s, freq, sa, dialog_token, resp);
2258 : :
2259 : 9 : wpabuf_free(resp);
2260 : : }
2261 : :
2262 : :
2263 : 9 : static void wpas_sd_response(void *ctx, const u8 *sa, u16 update_indic,
2264 : : const u8 *tlvs, size_t tlvs_len)
2265 : : {
2266 : 9 : struct wpa_supplicant *wpa_s = ctx;
2267 : 9 : const u8 *pos = tlvs;
2268 : 9 : const u8 *end = tlvs + tlvs_len;
2269 : : const u8 *tlv_end;
2270 : : u16 slen;
2271 : : size_t buf_len;
2272 : : char *buf;
2273 : :
2274 : 9 : wpa_hexdump(MSG_MSGDUMP, "P2P: Service Discovery Response TLVs",
2275 : : tlvs, tlvs_len);
2276 [ + + ]: 9 : if (tlvs_len > 1500) {
2277 : : /* TODO: better way for handling this */
2278 : 2 : wpa_msg_ctrl(wpa_s, MSG_INFO,
2279 : : P2P_EVENT_SERV_DISC_RESP MACSTR
2280 : : " %u <long response: %u bytes>",
2281 : 12 : MAC2STR(sa), update_indic,
2282 : : (unsigned int) tlvs_len);
2283 : : } else {
2284 : 7 : buf_len = 2 * tlvs_len + 1;
2285 : 7 : buf = os_malloc(buf_len);
2286 [ + - ]: 7 : if (buf) {
2287 : 7 : wpa_snprintf_hex(buf, buf_len, tlvs, tlvs_len);
2288 : 7 : wpa_msg_ctrl(wpa_s, MSG_INFO,
2289 : : P2P_EVENT_SERV_DISC_RESP MACSTR " %u %s",
2290 : 42 : MAC2STR(sa), update_indic, buf);
2291 : 7 : os_free(buf);
2292 : : }
2293 : : }
2294 : :
2295 [ + + ]: 311 : while (pos < end) {
2296 : : u8 srv_proto, srv_trans_id, status;
2297 : :
2298 : 302 : wpa_printf(MSG_DEBUG, "P2P: Service Response TLV");
2299 : 302 : slen = WPA_GET_LE16(pos);
2300 : 302 : pos += 2;
2301 [ + - ][ - + ]: 302 : if (pos + slen > end || slen < 3) {
2302 : 0 : wpa_printf(MSG_DEBUG, "P2P: Unexpected Response Data "
2303 : : "length");
2304 : 9 : return;
2305 : : }
2306 : 302 : tlv_end = pos + slen;
2307 : :
2308 : 302 : srv_proto = *pos++;
2309 : 302 : wpa_printf(MSG_DEBUG, "P2P: Service Protocol Type %u",
2310 : : srv_proto);
2311 : 302 : srv_trans_id = *pos++;
2312 : 302 : wpa_printf(MSG_DEBUG, "P2P: Service Transaction ID %u",
2313 : : srv_trans_id);
2314 : 302 : status = *pos++;
2315 : 302 : wpa_printf(MSG_DEBUG, "P2P: Status Code ID %u",
2316 : : status);
2317 : :
2318 : 302 : wpa_hexdump(MSG_MSGDUMP, "P2P: Response Data",
2319 : 302 : pos, tlv_end - pos);
2320 : :
2321 : 302 : pos = tlv_end;
2322 : : }
2323 : :
2324 : 9 : wpas_notify_p2p_sd_response(wpa_s, sa, update_indic, tlvs, tlvs_len);
2325 : : }
2326 : :
2327 : :
2328 : 13 : u64 wpas_p2p_sd_request(struct wpa_supplicant *wpa_s, const u8 *dst,
2329 : : const struct wpabuf *tlvs)
2330 : : {
2331 [ + - ][ - + ]: 13 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
2332 : 0 : return 0;
2333 : 13 : return (uintptr_t) p2p_sd_request(wpa_s->global->p2p, dst, tlvs);
2334 : : }
2335 : :
2336 : :
2337 : 1 : u64 wpas_p2p_sd_request_upnp(struct wpa_supplicant *wpa_s, const u8 *dst,
2338 : : u8 version, const char *query)
2339 : : {
2340 : : struct wpabuf *tlvs;
2341 : : u64 ret;
2342 : :
2343 : 1 : tlvs = wpabuf_alloc(2 + 1 + 1 + 1 + os_strlen(query));
2344 [ - + ]: 1 : if (tlvs == NULL)
2345 : 0 : return 0;
2346 : 1 : wpabuf_put_le16(tlvs, 1 + 1 + 1 + os_strlen(query));
2347 : 1 : wpabuf_put_u8(tlvs, P2P_SERV_UPNP); /* Service Protocol Type */
2348 : 1 : wpabuf_put_u8(tlvs, 1); /* Service Transaction ID */
2349 : 1 : wpabuf_put_u8(tlvs, version);
2350 : 1 : wpabuf_put_str(tlvs, query);
2351 : 1 : ret = wpas_p2p_sd_request(wpa_s, dst, tlvs);
2352 : 1 : wpabuf_free(tlvs);
2353 : 1 : return ret;
2354 : : }
2355 : :
2356 : :
2357 : : #ifdef CONFIG_WIFI_DISPLAY
2358 : :
2359 : 0 : static u64 wpas_p2p_sd_request_wfd(struct wpa_supplicant *wpa_s, const u8 *dst,
2360 : : const struct wpabuf *tlvs)
2361 : : {
2362 [ # # ][ # # ]: 0 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
2363 : 0 : return 0;
2364 : 0 : return (uintptr_t) p2p_sd_request_wfd(wpa_s->global->p2p, dst, tlvs);
2365 : : }
2366 : :
2367 : :
2368 : : #define MAX_WFD_SD_SUBELEMS 20
2369 : :
2370 : 0 : static void wfd_add_sd_req_role(struct wpabuf *tlvs, u8 id, u8 role,
2371 : : const char *subelems)
2372 : : {
2373 : : u8 *len;
2374 : : const char *pos;
2375 : : int val;
2376 : 0 : int count = 0;
2377 : :
2378 : 0 : len = wpabuf_put(tlvs, 2);
2379 : 0 : wpabuf_put_u8(tlvs, P2P_SERV_WIFI_DISPLAY); /* Service Protocol Type */
2380 : 0 : wpabuf_put_u8(tlvs, id); /* Service Transaction ID */
2381 : :
2382 : 0 : wpabuf_put_u8(tlvs, role);
2383 : :
2384 : 0 : pos = subelems;
2385 [ # # ]: 0 : while (*pos) {
2386 : 0 : val = atoi(pos);
2387 [ # # ][ # # ]: 0 : if (val >= 0 && val < 256) {
2388 : 0 : wpabuf_put_u8(tlvs, val);
2389 : 0 : count++;
2390 [ # # ]: 0 : if (count == MAX_WFD_SD_SUBELEMS)
2391 : 0 : break;
2392 : : }
2393 : 0 : pos = os_strchr(pos + 1, ',');
2394 [ # # ]: 0 : if (pos == NULL)
2395 : 0 : break;
2396 : 0 : pos++;
2397 : : }
2398 : :
2399 : 0 : WPA_PUT_LE16(len, (u8 *) wpabuf_put(tlvs, 0) - len - 2);
2400 : 0 : }
2401 : :
2402 : :
2403 : 0 : u64 wpas_p2p_sd_request_wifi_display(struct wpa_supplicant *wpa_s,
2404 : : const u8 *dst, const char *role)
2405 : : {
2406 : : struct wpabuf *tlvs;
2407 : : u64 ret;
2408 : : const char *subelems;
2409 : 0 : u8 id = 1;
2410 : :
2411 : 0 : subelems = os_strchr(role, ' ');
2412 [ # # ]: 0 : if (subelems == NULL)
2413 : 0 : return 0;
2414 : 0 : subelems++;
2415 : :
2416 : 0 : tlvs = wpabuf_alloc(4 * (2 + 1 + 1 + 1 + MAX_WFD_SD_SUBELEMS));
2417 [ # # ]: 0 : if (tlvs == NULL)
2418 : 0 : return 0;
2419 : :
2420 [ # # ]: 0 : if (os_strstr(role, "[source]"))
2421 : 0 : wfd_add_sd_req_role(tlvs, id++, 0x00, subelems);
2422 [ # # ]: 0 : if (os_strstr(role, "[pri-sink]"))
2423 : 0 : wfd_add_sd_req_role(tlvs, id++, 0x01, subelems);
2424 [ # # ]: 0 : if (os_strstr(role, "[sec-sink]"))
2425 : 0 : wfd_add_sd_req_role(tlvs, id++, 0x02, subelems);
2426 [ # # ]: 0 : if (os_strstr(role, "[source+sink]"))
2427 : 0 : wfd_add_sd_req_role(tlvs, id++, 0x03, subelems);
2428 : :
2429 : 0 : ret = wpas_p2p_sd_request_wfd(wpa_s, dst, tlvs);
2430 : 0 : wpabuf_free(tlvs);
2431 : 0 : return ret;
2432 : : }
2433 : :
2434 : : #endif /* CONFIG_WIFI_DISPLAY */
2435 : :
2436 : :
2437 : 5 : int wpas_p2p_sd_cancel_request(struct wpa_supplicant *wpa_s, u64 req)
2438 : : {
2439 [ + - ][ - + ]: 5 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
2440 : 0 : return -1;
2441 : 5 : return p2p_sd_cancel_request(wpa_s->global->p2p,
2442 : : (void *) (uintptr_t) req);
2443 : : }
2444 : :
2445 : :
2446 : 9 : void wpas_p2p_sd_response(struct wpa_supplicant *wpa_s, int freq,
2447 : : const u8 *dst, u8 dialog_token,
2448 : : const struct wpabuf *resp_tlvs)
2449 : : {
2450 [ + - ][ - + ]: 9 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
2451 : 9 : return;
2452 : 9 : p2p_sd_response(wpa_s->global->p2p, freq, dst, dialog_token,
2453 : : resp_tlvs);
2454 : : }
2455 : :
2456 : :
2457 : 998 : void wpas_p2p_sd_service_update(struct wpa_supplicant *wpa_s)
2458 : : {
2459 [ + - ]: 998 : if (wpa_s->global->p2p)
2460 : 998 : p2p_sd_service_update(wpa_s->global->p2p);
2461 : 998 : }
2462 : :
2463 : :
2464 : 36 : static void wpas_p2p_srv_bonjour_free(struct p2p_srv_bonjour *bsrv)
2465 : : {
2466 : 36 : dl_list_del(&bsrv->list);
2467 : 36 : wpabuf_free(bsrv->query);
2468 : 36 : wpabuf_free(bsrv->resp);
2469 : 36 : os_free(bsrv);
2470 : 36 : }
2471 : :
2472 : :
2473 : 235 : static void wpas_p2p_srv_upnp_free(struct p2p_srv_upnp *usrv)
2474 : : {
2475 : 235 : dl_list_del(&usrv->list);
2476 : 235 : os_free(usrv->service);
2477 : 235 : os_free(usrv);
2478 : 235 : }
2479 : :
2480 : :
2481 : 727 : void wpas_p2p_service_flush(struct wpa_supplicant *wpa_s)
2482 : : {
2483 : : struct p2p_srv_bonjour *bsrv, *bn;
2484 : : struct p2p_srv_upnp *usrv, *un;
2485 : :
2486 [ + + ]: 763 : dl_list_for_each_safe(bsrv, bn, &wpa_s->global->p2p_srv_bonjour,
2487 : : struct p2p_srv_bonjour, list)
2488 : 36 : wpas_p2p_srv_bonjour_free(bsrv);
2489 : :
2490 [ + + ]: 962 : dl_list_for_each_safe(usrv, un, &wpa_s->global->p2p_srv_upnp,
2491 : : struct p2p_srv_upnp, list)
2492 : 235 : wpas_p2p_srv_upnp_free(usrv);
2493 : :
2494 : 727 : wpas_p2p_sd_service_update(wpa_s);
2495 : 727 : }
2496 : :
2497 : :
2498 : 36 : int wpas_p2p_service_add_bonjour(struct wpa_supplicant *wpa_s,
2499 : : struct wpabuf *query, struct wpabuf *resp)
2500 : : {
2501 : : struct p2p_srv_bonjour *bsrv;
2502 : :
2503 : 36 : bsrv = os_zalloc(sizeof(*bsrv));
2504 [ - + ]: 36 : if (bsrv == NULL)
2505 : 0 : return -1;
2506 : 36 : bsrv->query = query;
2507 : 36 : bsrv->resp = resp;
2508 : 36 : dl_list_add(&wpa_s->global->p2p_srv_bonjour, &bsrv->list);
2509 : :
2510 : 36 : wpas_p2p_sd_service_update(wpa_s);
2511 : 36 : return 0;
2512 : : }
2513 : :
2514 : :
2515 : 0 : int wpas_p2p_service_del_bonjour(struct wpa_supplicant *wpa_s,
2516 : : const struct wpabuf *query)
2517 : : {
2518 : : struct p2p_srv_bonjour *bsrv;
2519 : :
2520 : 0 : bsrv = wpas_p2p_service_get_bonjour(wpa_s, query);
2521 [ # # ]: 0 : if (bsrv == NULL)
2522 : 0 : return -1;
2523 : 0 : wpas_p2p_srv_bonjour_free(bsrv);
2524 : 0 : wpas_p2p_sd_service_update(wpa_s);
2525 : 0 : return 0;
2526 : : }
2527 : :
2528 : :
2529 : 245 : int wpas_p2p_service_add_upnp(struct wpa_supplicant *wpa_s, u8 version,
2530 : : const char *service)
2531 : : {
2532 : : struct p2p_srv_upnp *usrv;
2533 : :
2534 [ + + ]: 245 : if (wpas_p2p_service_get_upnp(wpa_s, version, service))
2535 : 10 : return 0; /* Already listed */
2536 : 235 : usrv = os_zalloc(sizeof(*usrv));
2537 [ - + ]: 235 : if (usrv == NULL)
2538 : 0 : return -1;
2539 : 235 : usrv->version = version;
2540 : 235 : usrv->service = os_strdup(service);
2541 [ - + ]: 235 : if (usrv->service == NULL) {
2542 : 0 : os_free(usrv);
2543 : 0 : return -1;
2544 : : }
2545 : 235 : dl_list_add(&wpa_s->global->p2p_srv_upnp, &usrv->list);
2546 : :
2547 : 235 : wpas_p2p_sd_service_update(wpa_s);
2548 : 245 : return 0;
2549 : : }
2550 : :
2551 : :
2552 : 0 : int wpas_p2p_service_del_upnp(struct wpa_supplicant *wpa_s, u8 version,
2553 : : const char *service)
2554 : : {
2555 : : struct p2p_srv_upnp *usrv;
2556 : :
2557 : 0 : usrv = wpas_p2p_service_get_upnp(wpa_s, version, service);
2558 [ # # ]: 0 : if (usrv == NULL)
2559 : 0 : return -1;
2560 : 0 : wpas_p2p_srv_upnp_free(usrv);
2561 : 0 : wpas_p2p_sd_service_update(wpa_s);
2562 : 0 : return 0;
2563 : : }
2564 : :
2565 : :
2566 : 20 : static void wpas_prov_disc_local_display(struct wpa_supplicant *wpa_s,
2567 : : const u8 *peer, const char *params,
2568 : : unsigned int generated_pin)
2569 : : {
2570 : 20 : wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_SHOW_PIN MACSTR
2571 : 120 : " %08d%s", MAC2STR(peer), generated_pin, params);
2572 : 20 : }
2573 : :
2574 : :
2575 : 3 : static void wpas_prov_disc_local_keypad(struct wpa_supplicant *wpa_s,
2576 : : const u8 *peer, const char *params)
2577 : : {
2578 : 3 : wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_ENTER_PIN MACSTR
2579 : 18 : "%s", MAC2STR(peer), params);
2580 : 3 : }
2581 : :
2582 : :
2583 : 22 : static void wpas_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods,
2584 : : const u8 *dev_addr, const u8 *pri_dev_type,
2585 : : const char *dev_name, u16 supp_config_methods,
2586 : : u8 dev_capab, u8 group_capab, const u8 *group_id,
2587 : : size_t group_id_len)
2588 : : {
2589 : 22 : struct wpa_supplicant *wpa_s = ctx;
2590 : : char devtype[WPS_DEV_TYPE_BUFSIZE];
2591 : : char params[300];
2592 : : u8 empty_dev_type[8];
2593 : 22 : unsigned int generated_pin = 0;
2594 : 22 : struct wpa_supplicant *group = NULL;
2595 : :
2596 [ + + ]: 22 : if (group_id) {
2597 [ + - ]: 18 : for (group = wpa_s->global->ifaces; group; group = group->next)
2598 : : {
2599 : 18 : struct wpa_ssid *s = group->current_ssid;
2600 [ + - ][ + - ]: 18 : if (s != NULL &&
2601 [ + - ]: 18 : s->mode == WPAS_MODE_P2P_GO &&
2602 [ + - ]: 18 : group_id_len - ETH_ALEN == s->ssid_len &&
2603 : 18 : os_memcmp(group_id + ETH_ALEN, s->ssid,
2604 : : s->ssid_len) == 0)
2605 : 18 : break;
2606 : : }
2607 : : }
2608 : :
2609 [ - + ]: 22 : if (pri_dev_type == NULL) {
2610 : 0 : os_memset(empty_dev_type, 0, sizeof(empty_dev_type));
2611 : 0 : pri_dev_type = empty_dev_type;
2612 : : }
2613 [ + + ][ + + ]: 22 : os_snprintf(params, sizeof(params), " p2p_dev_addr=" MACSTR
2614 : : " pri_dev_type=%s name='%s' config_methods=0x%x "
2615 : : "dev_capab=0x%x group_capab=0x%x%s%s",
2616 : 132 : MAC2STR(dev_addr),
2617 : : wps_dev_type_bin2str(pri_dev_type, devtype,
2618 : : sizeof(devtype)),
2619 : : dev_name, supp_config_methods, dev_capab, group_capab,
2620 : : group ? " group=" : "",
2621 : : group ? group->ifname : "");
2622 : 22 : params[sizeof(params) - 1] = '\0';
2623 : :
2624 [ + + ]: 22 : if (config_methods & WPS_CONFIG_DISPLAY) {
2625 : 19 : generated_pin = wps_generate_pin();
2626 : 19 : wpas_prov_disc_local_display(wpa_s, peer, params,
2627 : : generated_pin);
2628 [ + + ]: 3 : } else if (config_methods & WPS_CONFIG_KEYPAD)
2629 : 2 : wpas_prov_disc_local_keypad(wpa_s, peer, params);
2630 [ + - ]: 1 : else if (config_methods & WPS_CONFIG_PUSHBUTTON)
2631 : 1 : wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_REQ
2632 : 6 : MACSTR "%s", MAC2STR(peer), params);
2633 : :
2634 : 22 : wpas_notify_p2p_provision_discovery(wpa_s, peer, 1 /* request */,
2635 : : P2P_PROV_DISC_SUCCESS,
2636 : : config_methods, generated_pin);
2637 : 22 : }
2638 : :
2639 : :
2640 : 21 : static void wpas_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods)
2641 : : {
2642 : 21 : struct wpa_supplicant *wpa_s = ctx;
2643 : 21 : unsigned int generated_pin = 0;
2644 : : char params[20];
2645 : :
2646 [ + + ][ - + ]: 21 : if (wpa_s->pending_pd_before_join &&
2647 [ # # ]: 0 : (os_memcmp(peer, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
2648 : 0 : os_memcmp(peer, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) {
2649 : 18 : wpa_s->pending_pd_before_join = 0;
2650 : 18 : wpa_printf(MSG_DEBUG, "P2P: Starting pending "
2651 : : "join-existing-group operation");
2652 : 18 : wpas_p2p_join_start(wpa_s);
2653 : 21 : return;
2654 : : }
2655 : :
2656 [ + - ][ - + ]: 3 : if (wpa_s->pending_pd_use == AUTO_PD_JOIN ||
2657 : 3 : wpa_s->pending_pd_use == AUTO_PD_GO_NEG)
2658 : 0 : os_snprintf(params, sizeof(params), " peer_go=%d",
2659 : 0 : wpa_s->pending_pd_use == AUTO_PD_JOIN);
2660 : : else
2661 : 3 : params[0] = '\0';
2662 : :
2663 [ + + ]: 3 : if (config_methods & WPS_CONFIG_DISPLAY)
2664 : 1 : wpas_prov_disc_local_keypad(wpa_s, peer, params);
2665 [ + + ]: 2 : else if (config_methods & WPS_CONFIG_KEYPAD) {
2666 : 1 : generated_pin = wps_generate_pin();
2667 : 1 : wpas_prov_disc_local_display(wpa_s, peer, params,
2668 : : generated_pin);
2669 [ + - ]: 1 : } else if (config_methods & WPS_CONFIG_PUSHBUTTON)
2670 : 1 : wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_RESP
2671 : 6 : MACSTR "%s", MAC2STR(peer), params);
2672 : :
2673 : 3 : wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
2674 : : P2P_PROV_DISC_SUCCESS,
2675 : : config_methods, generated_pin);
2676 : : }
2677 : :
2678 : :
2679 : 0 : static void wpas_prov_disc_fail(void *ctx, const u8 *peer,
2680 : : enum p2p_prov_disc_status status)
2681 : : {
2682 : 0 : struct wpa_supplicant *wpa_s = ctx;
2683 : :
2684 [ # # ]: 0 : if (wpa_s->p2p_fallback_to_go_neg) {
2685 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: PD for p2p_connect-auto "
2686 : : "failed - fall back to GO Negotiation");
2687 : 0 : wpas_p2p_fallback_to_go_neg(wpa_s, 0);
2688 : 0 : return;
2689 : : }
2690 : :
2691 [ # # ]: 0 : if (status == P2P_PROV_DISC_TIMEOUT_JOIN) {
2692 : 0 : wpa_s->pending_pd_before_join = 0;
2693 : 0 : wpa_printf(MSG_DEBUG, "P2P: Starting pending "
2694 : : "join-existing-group operation (no ACK for PD "
2695 : : "Req attempts)");
2696 : 0 : wpas_p2p_join_start(wpa_s);
2697 : 0 : return;
2698 : : }
2699 : :
2700 : 0 : wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE
2701 : : " p2p_dev_addr=" MACSTR " status=%d",
2702 : 0 : MAC2STR(peer), status);
2703 : :
2704 : 0 : wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
2705 : : status, 0, 0);
2706 : : }
2707 : :
2708 : :
2709 : 27 : static int freq_included(const struct p2p_channels *channels, unsigned int freq)
2710 : : {
2711 [ + + ]: 27 : if (channels == NULL)
2712 : 21 : return 1; /* Assume no restrictions */
2713 : 27 : return p2p_channels_includes_freq(channels, freq);
2714 : :
2715 : : }
2716 : :
2717 : :
2718 : 11 : static u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid,
2719 : : const u8 *go_dev_addr, const u8 *ssid,
2720 : : size_t ssid_len, int *go, u8 *group_bssid,
2721 : : int *force_freq, int persistent_group,
2722 : : const struct p2p_channels *channels)
2723 : : {
2724 : 11 : struct wpa_supplicant *wpa_s = ctx;
2725 : : struct wpa_ssid *s;
2726 : : int res;
2727 : : struct wpa_supplicant *grp;
2728 : :
2729 [ + + ]: 11 : if (!persistent_group) {
2730 : 4 : wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR
2731 : 24 : " to join an active group", MAC2STR(sa));
2732 [ + + ][ - + ]: 4 : if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) &&
2733 : 1 : (os_memcmp(go_dev_addr, wpa_s->p2p_auth_invite, ETH_ALEN)
2734 [ # # ]: 0 : == 0 ||
2735 : 0 : os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0)) {
2736 : 1 : wpa_printf(MSG_DEBUG, "P2P: Accept previously "
2737 : : "authorized invitation");
2738 : 1 : goto accept_inv;
2739 : : }
2740 : : /*
2741 : : * Do not accept the invitation automatically; notify user and
2742 : : * request approval.
2743 : : */
2744 : 3 : return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
2745 : : }
2746 : :
2747 : 7 : grp = wpas_get_p2p_group(wpa_s, ssid, ssid_len, go);
2748 [ - + ]: 7 : if (grp) {
2749 : 0 : wpa_printf(MSG_DEBUG, "P2P: Accept invitation to already "
2750 : : "running persistent group");
2751 [ # # ]: 0 : if (*go)
2752 : 0 : os_memcpy(group_bssid, grp->own_addr, ETH_ALEN);
2753 : 0 : goto accept_inv;
2754 : : }
2755 : :
2756 [ + + ][ + - ]: 7 : if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) &&
2757 : 3 : os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0) {
2758 : 3 : wpa_printf(MSG_DEBUG, "P2P: Accept previously initiated "
2759 : : "invitation to re-invoke a persistent group");
2760 [ - + ]: 4 : } else if (!wpa_s->conf->persistent_reconnect)
2761 : 0 : return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
2762 : :
2763 [ + - ]: 7 : for (s = wpa_s->conf->ssid; s; s = s->next) {
2764 [ + - ][ + - ]: 7 : if (s->disabled == 2 &&
2765 [ + - ]: 7 : os_memcmp(s->bssid, go_dev_addr, ETH_ALEN) == 0 &&
2766 [ + - ]: 7 : s->ssid_len == ssid_len &&
2767 : 7 : os_memcmp(ssid, s->ssid, ssid_len) == 0)
2768 : 7 : break;
2769 : : }
2770 : :
2771 [ - + ]: 7 : if (!s) {
2772 : 0 : wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR
2773 : : " requested reinvocation of an unknown group",
2774 : 0 : MAC2STR(sa));
2775 : 0 : return P2P_SC_FAIL_UNKNOWN_GROUP;
2776 : : }
2777 : :
2778 [ + + ][ + - ]: 7 : if (s->mode == WPAS_MODE_P2P_GO && !wpas_p2p_create_iface(wpa_s)) {
2779 : 4 : *go = 1;
2780 [ - + ]: 4 : if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
2781 : 0 : wpa_printf(MSG_DEBUG, "P2P: The only available "
2782 : : "interface is already in use - reject "
2783 : : "invitation");
2784 : 0 : return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
2785 : : }
2786 : 4 : os_memcpy(group_bssid, wpa_s->own_addr, ETH_ALEN);
2787 [ - + ]: 3 : } else if (s->mode == WPAS_MODE_P2P_GO) {
2788 : 0 : *go = 1;
2789 [ # # ]: 0 : if (wpas_p2p_add_group_interface(wpa_s, WPA_IF_P2P_GO) < 0)
2790 : : {
2791 : 0 : wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
2792 : : "interface address for the group");
2793 : 0 : return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
2794 : : }
2795 : 0 : os_memcpy(group_bssid, wpa_s->pending_interface_addr,
2796 : : ETH_ALEN);
2797 : : }
2798 : :
2799 : : accept_inv:
2800 : 8 : wpas_p2p_set_own_freq_preference(wpa_s, 0);
2801 : :
2802 : : /* Get one of the frequencies currently in use */
2803 [ - + ]: 8 : if (wpas_p2p_valid_oper_freqs(wpa_s, &res, 1) > 0) {
2804 : 0 : wpa_printf(MSG_DEBUG, "P2P: Trying to prefer a channel already used by one of the interfaces");
2805 : 0 : wpas_p2p_set_own_freq_preference(wpa_s, res);
2806 : :
2807 [ # # # # ]: 0 : if (wpa_s->num_multichan_concurrent < 2 ||
2808 : 0 : wpas_p2p_num_unused_channels(wpa_s) < 1) {
2809 : 0 : wpa_printf(MSG_DEBUG, "P2P: No extra channels available - trying to force channel to match a channel already used by one of the interfaces");
2810 : 0 : *force_freq = res;
2811 : : }
2812 : : }
2813 : :
2814 [ - + ]: 8 : if (*force_freq > 0 && wpa_s->num_multichan_concurrent > 1 &&
[ # # # # ]
2815 : 0 : wpas_p2p_num_unused_channels(wpa_s) > 0) {
2816 [ # # ]: 0 : if (*go == 0) {
2817 : : /* We are the client */
2818 : 0 : wpa_printf(MSG_DEBUG, "P2P: Peer was found to be "
2819 : : "running a GO but we are capable of MCC, "
2820 : : "figure out the best channel to use");
2821 : 0 : *force_freq = 0;
2822 [ # # ]: 0 : } else if (!freq_included(channels, *force_freq)) {
2823 : : /* We are the GO, and *force_freq is not in the
2824 : : * intersection */
2825 : 0 : wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not "
2826 : : "in intersection but we are capable of MCC, "
2827 : : "figure out the best channel to use",
2828 : : *force_freq);
2829 : 0 : *force_freq = 0;
2830 : : }
2831 : : }
2832 : :
2833 : 11 : return P2P_SC_SUCCESS;
2834 : : }
2835 : :
2836 : :
2837 : 11 : static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
2838 : : const u8 *ssid, size_t ssid_len,
2839 : : const u8 *go_dev_addr, u8 status,
2840 : : int op_freq)
2841 : : {
2842 : 11 : struct wpa_supplicant *wpa_s = ctx;
2843 : : struct wpa_ssid *s;
2844 : :
2845 [ + + ]: 11 : for (s = wpa_s->conf->ssid; s; s = s->next) {
2846 [ + - ][ + - ]: 8 : if (s->disabled == 2 &&
2847 [ + - ]: 8 : s->ssid_len == ssid_len &&
2848 : 8 : os_memcmp(ssid, s->ssid, ssid_len) == 0)
2849 : 8 : break;
2850 : : }
2851 : :
2852 [ + + ]: 11 : if (status == P2P_SC_SUCCESS) {
2853 : 8 : wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR
2854 : : " was accepted; op_freq=%d MHz",
2855 : 48 : MAC2STR(sa), op_freq);
2856 [ + + ]: 8 : if (s) {
2857 : 7 : int go = s->mode == WPAS_MODE_P2P_GO;
2858 [ + + ][ + + ]: 7 : wpas_p2p_group_add_persistent(
2859 : : wpa_s, s, go, go ? op_freq : 0, 0, 0, NULL,
2860 : : go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0);
2861 [ + - ]: 1 : } else if (bssid) {
2862 : 1 : wpa_s->user_initiated_pd = 0;
2863 : 1 : wpas_p2p_join(wpa_s, bssid, go_dev_addr,
2864 : 1 : wpa_s->p2p_wps_method, 0);
2865 : : }
2866 : 8 : return;
2867 : : }
2868 : :
2869 [ - + ]: 3 : if (status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
2870 : 0 : wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR
2871 : 0 : " was rejected (status %u)", MAC2STR(sa), status);
2872 : 0 : return;
2873 : : }
2874 : :
2875 [ + + ]: 3 : if (!s) {
2876 [ + - ]: 2 : if (bssid) {
2877 : 2 : wpa_msg_global(wpa_s, MSG_INFO,
2878 : : P2P_EVENT_INVITATION_RECEIVED
2879 : : "sa=" MACSTR " go_dev_addr=" MACSTR
2880 : : " bssid=" MACSTR " unknown-network",
2881 : 24 : MAC2STR(sa), MAC2STR(go_dev_addr),
2882 : 12 : MAC2STR(bssid));
2883 : : } else {
2884 : 0 : wpa_msg_global(wpa_s, MSG_INFO,
2885 : : P2P_EVENT_INVITATION_RECEIVED
2886 : : "sa=" MACSTR " go_dev_addr=" MACSTR
2887 : : " unknown-network",
2888 : 0 : MAC2STR(sa), MAC2STR(go_dev_addr));
2889 : : }
2890 : 2 : return;
2891 : : }
2892 : :
2893 [ - + ][ # # ]: 1 : if (s->mode == WPAS_MODE_P2P_GO && op_freq) {
2894 : 0 : wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED
2895 : : "sa=" MACSTR " persistent=%d freq=%d",
2896 : 0 : MAC2STR(sa), s->id, op_freq);
2897 : : } else {
2898 : 11 : wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED
2899 : : "sa=" MACSTR " persistent=%d",
2900 : 6 : MAC2STR(sa), s->id);
2901 : : }
2902 : : }
2903 : :
2904 : :
2905 : 3 : static void wpas_remove_persistent_peer(struct wpa_supplicant *wpa_s,
2906 : : struct wpa_ssid *ssid,
2907 : : const u8 *peer, int inv)
2908 : : {
2909 : : size_t i;
2910 : :
2911 [ - + ]: 3 : if (ssid == NULL)
2912 : 0 : return;
2913 : :
2914 [ + - ][ + - ]: 4 : for (i = 0; ssid->p2p_client_list && i < ssid->num_p2p_clients; i++) {
2915 [ + + ]: 4 : if (os_memcmp(ssid->p2p_client_list + i * ETH_ALEN, peer,
2916 : : ETH_ALEN) == 0)
2917 : 3 : break;
2918 : : }
2919 [ - + ]: 3 : if (i >= ssid->num_p2p_clients) {
2920 [ # # ][ # # ]: 0 : if (ssid->mode != WPAS_MODE_P2P_GO &&
2921 : 0 : os_memcmp(ssid->bssid, peer, ETH_ALEN) == 0) {
2922 : 0 : wpa_printf(MSG_DEBUG, "P2P: Remove persistent group %d "
2923 : : "due to invitation result", ssid->id);
2924 : 0 : wpas_notify_network_removed(wpa_s, ssid);
2925 : 0 : wpa_config_remove_network(wpa_s->conf, ssid->id);
2926 : 0 : return;
2927 : : }
2928 : 0 : return; /* Peer not found in client list */
2929 : : }
2930 : :
2931 [ - + ]: 3 : wpa_printf(MSG_DEBUG, "P2P: Remove peer " MACSTR " from persistent "
2932 : : "group %d client list%s",
2933 : 18 : MAC2STR(peer), ssid->id,
2934 : : inv ? " due to invitation result" : "");
2935 : 3 : os_memmove(ssid->p2p_client_list + i * ETH_ALEN,
2936 : : ssid->p2p_client_list + (i + 1) * ETH_ALEN,
2937 : : (ssid->num_p2p_clients - i - 1) * ETH_ALEN);
2938 : 3 : ssid->num_p2p_clients--;
2939 : : #ifndef CONFIG_NO_CONFIG_WRITE
2940 [ - + # # ]: 3 : if (wpa_s->parent->conf->update_config &&
2941 : 0 : wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
2942 : 3 : wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
2943 : : #endif /* CONFIG_NO_CONFIG_WRITE */
2944 : : }
2945 : :
2946 : :
2947 : 0 : static void wpas_remove_persistent_client(struct wpa_supplicant *wpa_s,
2948 : : const u8 *peer)
2949 : : {
2950 : : struct wpa_ssid *ssid;
2951 : :
2952 : 0 : wpa_s = wpa_s->global->p2p_invite_group;
2953 [ # # ]: 0 : if (wpa_s == NULL)
2954 : 0 : return; /* No known invitation group */
2955 : 0 : ssid = wpa_s->current_ssid;
2956 [ # # ][ # # ]: 0 : if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
[ # # ]
2957 : 0 : !ssid->p2p_persistent_group)
2958 : 0 : return; /* Not operating as a GO in persistent group */
2959 : 0 : ssid = wpas_p2p_get_persistent(wpa_s->parent, peer,
2960 : 0 : ssid->ssid, ssid->ssid_len);
2961 : 0 : wpas_remove_persistent_peer(wpa_s, ssid, peer, 1);
2962 : : }
2963 : :
2964 : :
2965 : 11 : static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
2966 : : const struct p2p_channels *channels,
2967 : : const u8 *peer, int neg_freq)
2968 : : {
2969 : 11 : struct wpa_supplicant *wpa_s = ctx;
2970 : : struct wpa_ssid *ssid;
2971 : : int freq;
2972 : :
2973 [ + + ]: 11 : if (bssid) {
2974 : 4 : wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT
2975 : : "status=%d " MACSTR,
2976 : 24 : status, MAC2STR(bssid));
2977 : : } else {
2978 : 7 : wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT
2979 : : "status=%d ", status);
2980 : : }
2981 : 11 : wpas_notify_p2p_invitation_result(wpa_s, status, bssid);
2982 : :
2983 : 11 : wpa_printf(MSG_DEBUG, "P2P: Invitation result - status=%d peer=" MACSTR,
2984 : 66 : status, MAC2STR(peer));
2985 [ + + ]: 11 : if (wpa_s->pending_invite_ssid_id == -1) {
2986 [ - + ]: 4 : if (status == P2P_SC_FAIL_UNKNOWN_GROUP)
2987 : 0 : wpas_remove_persistent_client(wpa_s, peer);
2988 : 4 : return; /* Invitation to active group */
2989 : : }
2990 : :
2991 [ - + ]: 7 : if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
2992 : 0 : wpa_printf(MSG_DEBUG, "P2P: Waiting for peer to start another "
2993 : : "invitation exchange to indicate readiness for "
2994 : : "re-invocation");
2995 : : }
2996 : :
2997 [ - + ]: 7 : if (status != P2P_SC_SUCCESS) {
2998 [ # # ]: 0 : if (status == P2P_SC_FAIL_UNKNOWN_GROUP) {
2999 : 0 : ssid = wpa_config_get_network(
3000 : : wpa_s->conf, wpa_s->pending_invite_ssid_id);
3001 : 0 : wpas_remove_persistent_peer(wpa_s, ssid, peer, 1);
3002 : : }
3003 : 0 : wpas_p2p_remove_pending_group_interface(wpa_s);
3004 : 0 : return;
3005 : : }
3006 : :
3007 : 7 : ssid = wpa_config_get_network(wpa_s->conf,
3008 : : wpa_s->pending_invite_ssid_id);
3009 [ - + ]: 7 : if (ssid == NULL) {
3010 : 0 : wpa_printf(MSG_ERROR, "P2P: Could not find persistent group "
3011 : : "data matching with invitation");
3012 : 0 : return;
3013 : : }
3014 : :
3015 : : /*
3016 : : * The peer could have missed our ctrl::ack frame for Invitation
3017 : : * Response and continue retransmitting the frame. To reduce the
3018 : : * likelihood of the peer not getting successful TX status for the
3019 : : * Invitation Response frame, wait a short time here before starting
3020 : : * the persistent group so that we will remain on the current channel to
3021 : : * acknowledge any possible retransmission from the peer.
3022 : : */
3023 : 7 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: 50 ms wait on current channel before "
3024 : : "starting persistent group");
3025 : 7 : os_sleep(0, 50000);
3026 : :
3027 : 7 : freq = wpa_s->p2p_persistent_go_freq;
3028 [ + - ]: 10 : if (neg_freq > 0 && ssid->mode == WPAS_MODE_P2P_GO &&
[ + + + - ]
3029 : 3 : freq_included(channels, neg_freq)) {
3030 : 3 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use frequence %d MHz from invitation for GO mode",
3031 : : neg_freq);
3032 : 3 : freq = neg_freq;
3033 : : }
3034 : :
3035 [ + + ]: 11 : wpas_p2p_group_add_persistent(wpa_s, ssid,
3036 : 7 : ssid->mode == WPAS_MODE_P2P_GO,
3037 : : freq,
3038 : 14 : wpa_s->p2p_go_ht40, wpa_s->p2p_go_vht,
3039 : : channels,
3040 : 7 : ssid->mode == WPAS_MODE_P2P_GO ?
3041 : : P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
3042 : : 0);
3043 : : }
3044 : :
3045 : :
3046 : 86725 : static int wpas_p2p_disallowed_freq(struct wpa_global *global,
3047 : : unsigned int freq)
3048 : : {
3049 : 86725 : return freq_range_list_includes(&global->p2p_disallow_freq, freq);
3050 : : }
3051 : :
3052 : :
3053 : 0 : static void wpas_p2p_add_chan(struct p2p_reg_class *reg, u8 chan)
3054 : : {
3055 : 0 : reg->channel[reg->channels] = chan;
3056 : 0 : reg->channels++;
3057 : 0 : }
3058 : :
3059 : :
3060 : 0 : static int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s,
3061 : : struct p2p_channels *chan,
3062 : : struct p2p_channels *cli_chan)
3063 : : {
3064 : 0 : int i, cla = 0;
3065 : :
3066 : 0 : os_memset(cli_chan, 0, sizeof(*cli_chan));
3067 : :
3068 : 0 : wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for 2.4 GHz "
3069 : : "band");
3070 : :
3071 : : /* Operating class 81 - 2.4 GHz band channels 1..13 */
3072 : 0 : chan->reg_class[cla].reg_class = 81;
3073 : 0 : chan->reg_class[cla].channels = 0;
3074 [ # # ]: 0 : for (i = 0; i < 11; i++) {
3075 [ # # ]: 0 : if (!wpas_p2p_disallowed_freq(wpa_s->global, 2412 + i * 5))
3076 : 0 : wpas_p2p_add_chan(&chan->reg_class[cla], i + 1);
3077 : : }
3078 [ # # ]: 0 : if (chan->reg_class[cla].channels)
3079 : 0 : cla++;
3080 : :
3081 : 0 : wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for lower 5 GHz "
3082 : : "band");
3083 : :
3084 : : /* Operating class 115 - 5 GHz, channels 36-48 */
3085 : 0 : chan->reg_class[cla].reg_class = 115;
3086 : 0 : chan->reg_class[cla].channels = 0;
3087 [ # # ]: 0 : if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 36 * 5))
3088 : 0 : wpas_p2p_add_chan(&chan->reg_class[cla], 36);
3089 [ # # ]: 0 : if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 40 * 5))
3090 : 0 : wpas_p2p_add_chan(&chan->reg_class[cla], 40);
3091 [ # # ]: 0 : if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 44 * 5))
3092 : 0 : wpas_p2p_add_chan(&chan->reg_class[cla], 44);
3093 [ # # ]: 0 : if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 48 * 5))
3094 : 0 : wpas_p2p_add_chan(&chan->reg_class[cla], 48);
3095 [ # # ]: 0 : if (chan->reg_class[cla].channels)
3096 : 0 : cla++;
3097 : :
3098 : 0 : wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for higher 5 GHz "
3099 : : "band");
3100 : :
3101 : : /* Operating class 124 - 5 GHz, channels 149,153,157,161 */
3102 : 0 : chan->reg_class[cla].reg_class = 124;
3103 : 0 : chan->reg_class[cla].channels = 0;
3104 [ # # ]: 0 : if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 149 * 5))
3105 : 0 : wpas_p2p_add_chan(&chan->reg_class[cla], 149);
3106 [ # # ]: 0 : if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 153 * 5))
3107 : 0 : wpas_p2p_add_chan(&chan->reg_class[cla], 153);
3108 [ # # ]: 0 : if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 156 * 5))
3109 : 0 : wpas_p2p_add_chan(&chan->reg_class[cla], 157);
3110 [ # # ]: 0 : if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 161 * 5))
3111 : 0 : wpas_p2p_add_chan(&chan->reg_class[cla], 161);
3112 [ # # ]: 0 : if (chan->reg_class[cla].channels)
3113 : 0 : cla++;
3114 : :
3115 : 0 : chan->reg_classes = cla;
3116 : 0 : return 0;
3117 : : }
3118 : :
3119 : :
3120 : 9128 : static struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
3121 : : u16 num_modes,
3122 : : enum hostapd_hw_mode mode)
3123 : : {
3124 : : u16 i;
3125 : :
3126 [ + - ]: 17115 : for (i = 0; i < num_modes; i++) {
3127 [ + + ]: 17115 : if (modes[i].mode == mode)
3128 : 9128 : return &modes[i];
3129 : : }
3130 : :
3131 : 9128 : return NULL;
3132 : : }
3133 : :
3134 : :
3135 : : enum chan_allowed {
3136 : : NOT_ALLOWED, PASSIVE_ONLY, ALLOWED
3137 : : };
3138 : :
3139 : 86716 : static int has_channel(struct wpa_global *global,
3140 : : struct hostapd_hw_modes *mode, u8 chan, int *flags)
3141 : : {
3142 : : int i;
3143 : : unsigned int freq;
3144 : :
3145 [ + + ]: 86716 : freq = (mode->mode == HOSTAPD_MODE_IEEE80211A ? 5000 : 2407) +
3146 : 86716 : chan * 5;
3147 [ - + ]: 86716 : if (wpas_p2p_disallowed_freq(global, freq))
3148 : 0 : return NOT_ALLOWED;
3149 : :
3150 [ + + ]: 1093078 : for (i = 0; i < mode->num_channels; i++) {
3151 [ + + ]: 1078245 : if (mode->channels[i].chan == chan) {
3152 [ + + ]: 71883 : if (flags)
3153 : 62755 : *flags = mode->channels[i].flag;
3154 [ + + ]: 71883 : if (mode->channels[i].flag &
3155 : : (HOSTAPD_CHAN_DISABLED |
3156 : : HOSTAPD_CHAN_RADAR))
3157 : 17115 : return NOT_ALLOWED;
3158 [ + + ]: 54768 : if (mode->channels[i].flag &
3159 : : (HOSTAPD_CHAN_PASSIVE_SCAN |
3160 : : HOSTAPD_CHAN_NO_IBSS))
3161 : 42217 : return PASSIVE_ONLY;
3162 : 12551 : return ALLOWED;
3163 : : }
3164 : : }
3165 : :
3166 : 86716 : return NOT_ALLOWED;
3167 : : }
3168 : :
3169 : :
3170 : : struct p2p_oper_class_map {
3171 : : enum hostapd_hw_mode mode;
3172 : : u8 op_class;
3173 : : u8 min_chan;
3174 : : u8 max_chan;
3175 : : u8 inc;
3176 : : enum { BW20, BW40PLUS, BW40MINUS, BW80 } bw;
3177 : : };
3178 : :
3179 : : static struct p2p_oper_class_map op_class[] = {
3180 : : { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20 },
3181 : : #if 0 /* Do not enable HT40 on 2 GHz for now */
3182 : : { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS },
3183 : : { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS },
3184 : : #endif
3185 : : { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20 },
3186 : : { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20 },
3187 : : { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS },
3188 : : { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS },
3189 : : { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS },
3190 : : { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS },
3191 : :
3192 : : /*
3193 : : * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
3194 : : * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
3195 : : * 80 MHz, but currently use the following definition for simplicity
3196 : : * (these center frequencies are not actual channels, which makes
3197 : : * has_channel() fail). wpas_p2p_verify_80mhz() should take care of
3198 : : * removing invalid channels.
3199 : : */
3200 : : { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80 },
3201 : : { -1, 0, 0, 0, 0, BW20 }
3202 : : };
3203 : :
3204 : :
3205 : 36512 : static int wpas_p2p_get_center_80mhz(struct wpa_supplicant *wpa_s,
3206 : : struct hostapd_hw_modes *mode,
3207 : : u8 channel)
3208 : : {
3209 : 36512 : u8 center_channels[] = { 42, 58, 106, 122, 138, 155 };
3210 : : unsigned int i;
3211 : :
3212 [ - + ]: 36512 : if (mode->mode != HOSTAPD_MODE_IEEE80211A)
3213 : 0 : return 0;
3214 : :
3215 [ + + ]: 160881 : for (i = 0; i < ARRAY_SIZE(center_channels); i++)
3216 : : /*
3217 : : * In 80 MHz, the bandwidth "spans" 12 channels (e.g., 36-48),
3218 : : * so the center channel is 6 channels away from the start/end.
3219 : : */
3220 [ + + ][ + + ]: 150612 : if (channel >= center_channels[i] - 6 &&
3221 : 112959 : channel <= center_channels[i] + 6)
3222 : 26243 : return center_channels[i];
3223 : :
3224 : 36512 : return 0;
3225 : : }
3226 : :
3227 : :
3228 : 36512 : static enum chan_allowed wpas_p2p_verify_80mhz(struct wpa_supplicant *wpa_s,
3229 : : struct hostapd_hw_modes *mode,
3230 : : u8 channel, u8 bw)
3231 : : {
3232 : : u8 center_chan;
3233 : : int i, flags;
3234 : 36512 : enum chan_allowed res, ret = ALLOWED;
3235 : :
3236 : 36512 : center_chan = wpas_p2p_get_center_80mhz(wpa_s, mode, channel);
3237 [ + + ]: 36512 : if (!center_chan)
3238 : 10269 : return NOT_ALLOWED;
3239 [ + + ][ + + ]: 26243 : if (center_chan >= 58 && center_chan <= 138)
3240 : 18256 : return NOT_ALLOWED; /* Do not allow DFS channels for P2P */
3241 : :
3242 : : /* check all the channels are available */
3243 [ + - ]: 7987 : for (i = 0; i < 4; i++) {
3244 : 7987 : int adj_chan = center_chan - 6 + i * 4;
3245 : :
3246 : 7987 : res = has_channel(wpa_s->global, mode, adj_chan, &flags);
3247 [ - + ]: 7987 : if (res == NOT_ALLOWED)
3248 : 0 : return NOT_ALLOWED;
3249 [ + - ]: 7987 : if (res == PASSIVE_ONLY)
3250 : 7987 : ret = PASSIVE_ONLY;
3251 : :
3252 [ + - ][ + - ]: 7987 : if (i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70))
3253 : 7987 : return NOT_ALLOWED;
3254 [ # # ][ # # ]: 0 : if (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_50))
3255 : 0 : return NOT_ALLOWED;
3256 [ # # ][ # # ]: 0 : if (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_30))
3257 : 0 : return NOT_ALLOWED;
3258 [ # # ][ # # ]: 0 : if (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_10))
3259 : 0 : return NOT_ALLOWED;
3260 : : }
3261 : :
3262 : 36512 : return ret;
3263 : : }
3264 : :
3265 : :
3266 : 69601 : static enum chan_allowed wpas_p2p_verify_channel(struct wpa_supplicant *wpa_s,
3267 : : struct hostapd_hw_modes *mode,
3268 : : u8 channel, u8 bw)
3269 : : {
3270 : : int flag;
3271 : : enum chan_allowed res, res2;
3272 : :
3273 : 69601 : res2 = res = has_channel(wpa_s->global, mode, channel, &flag);
3274 [ + + ]: 69601 : if (bw == BW40MINUS) {
3275 [ - + ]: 4564 : if (!(flag & HOSTAPD_CHAN_HT40MINUS))
3276 : 0 : return NOT_ALLOWED;
3277 : 4564 : res2 = has_channel(wpa_s->global, mode, channel - 4, NULL);
3278 [ + + ]: 65037 : } else if (bw == BW40PLUS) {
3279 [ - + ]: 4564 : if (!(flag & HOSTAPD_CHAN_HT40PLUS))
3280 : 0 : return NOT_ALLOWED;
3281 : 4564 : res2 = has_channel(wpa_s->global, mode, channel + 4, NULL);
3282 [ + + ]: 60473 : } else if (bw == BW80) {
3283 : 36512 : res2 = wpas_p2p_verify_80mhz(wpa_s, mode, channel, bw);
3284 : : }
3285 : :
3286 [ + + ][ + + ]: 69601 : if (res == NOT_ALLOWED || res2 == NOT_ALLOWED)
3287 : 36512 : return NOT_ALLOWED;
3288 [ + + ][ - + ]: 33089 : if (res == PASSIVE_ONLY || res2 == PASSIVE_ONLY)
3289 : 20538 : return PASSIVE_ONLY;
3290 : 69601 : return res;
3291 : : }
3292 : :
3293 : :
3294 : 1141 : static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
3295 : : struct p2p_channels *chan,
3296 : : struct p2p_channels *cli_chan)
3297 : : {
3298 : : struct hostapd_hw_modes *mode;
3299 : : int cla, op, cli_cla;
3300 : :
3301 [ - + ]: 1141 : if (wpa_s->hw.modes == NULL) {
3302 : 0 : wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching "
3303 : : "of all supported channels; assume dualband "
3304 : : "support");
3305 : 0 : return wpas_p2p_default_channels(wpa_s, chan, cli_chan);
3306 : : }
3307 : :
3308 : 1141 : cla = cli_cla = 0;
3309 : :
3310 [ + + ]: 10269 : for (op = 0; op_class[op].op_class; op++) {
3311 : 9128 : struct p2p_oper_class_map *o = &op_class[op];
3312 : : u8 ch;
3313 : 9128 : struct p2p_reg_class *reg = NULL, *cli_reg = NULL;
3314 : :
3315 : 9128 : mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode);
3316 [ - + ]: 9128 : if (mode == NULL)
3317 : 0 : continue;
3318 [ + + ]: 78729 : for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
3319 : : enum chan_allowed res;
3320 : 69601 : res = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw);
3321 [ + + ]: 69601 : if (res == ALLOWED) {
3322 [ + + ]: 12551 : if (reg == NULL) {
3323 : 1141 : wpa_printf(MSG_DEBUG, "P2P: Add operating class %u",
3324 : 1141 : o->op_class);
3325 : 1141 : reg = &chan->reg_class[cla];
3326 : 1141 : cla++;
3327 : 1141 : reg->reg_class = o->op_class;
3328 : : }
3329 : 12551 : reg->channel[reg->channels] = ch;
3330 : 12551 : reg->channels++;
3331 [ + + ][ + + ]: 57050 : } else if (res == PASSIVE_ONLY &&
3332 : 20538 : wpa_s->conf->p2p_add_cli_chan) {
3333 [ + + ]: 234 : if (cli_reg == NULL) {
3334 : 91 : wpa_printf(MSG_DEBUG, "P2P: Add operating class %u (client only)",
3335 : 91 : o->op_class);
3336 : 91 : cli_reg = &cli_chan->reg_class[cli_cla];
3337 : 91 : cli_cla++;
3338 : 91 : cli_reg->reg_class = o->op_class;
3339 : : }
3340 : 234 : cli_reg->channel[cli_reg->channels] = ch;
3341 : 234 : cli_reg->channels++;
3342 : : }
3343 : : }
3344 [ + + ]: 9128 : if (reg) {
3345 : 1141 : wpa_hexdump(MSG_DEBUG, "P2P: Channels",
3346 : 1141 : reg->channel, reg->channels);
3347 : : }
3348 [ + + ]: 9128 : if (cli_reg) {
3349 : 91 : wpa_hexdump(MSG_DEBUG, "P2P: Channels (client only)",
3350 : 91 : cli_reg->channel, cli_reg->channels);
3351 : : }
3352 : : }
3353 : :
3354 : 1141 : chan->reg_classes = cla;
3355 : 1141 : cli_chan->reg_classes = cli_cla;
3356 : :
3357 : 1141 : return 0;
3358 : : }
3359 : :
3360 : :
3361 : 0 : int wpas_p2p_get_ht40_mode(struct wpa_supplicant *wpa_s,
3362 : : struct hostapd_hw_modes *mode, u8 channel)
3363 : : {
3364 : : int op;
3365 : : enum chan_allowed ret;
3366 : :
3367 [ # # ]: 0 : for (op = 0; op_class[op].op_class; op++) {
3368 : 0 : struct p2p_oper_class_map *o = &op_class[op];
3369 : : u8 ch;
3370 : :
3371 [ # # ]: 0 : for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
3372 [ # # ][ # # ]: 0 : if (o->mode != HOSTAPD_MODE_IEEE80211A ||
3373 [ # # ]: 0 : o->bw == BW20 || ch != channel)
3374 : 0 : continue;
3375 : 0 : ret = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw);
3376 [ # # ]: 0 : if (ret == ALLOWED)
3377 [ # # ]: 0 : return (o->bw == BW40MINUS) ? -1 : 1;
3378 : : }
3379 : : }
3380 : 0 : return 0;
3381 : : }
3382 : :
3383 : :
3384 : 0 : int wpas_p2p_get_vht80_center(struct wpa_supplicant *wpa_s,
3385 : : struct hostapd_hw_modes *mode, u8 channel)
3386 : : {
3387 [ # # ]: 0 : if (!wpas_p2p_verify_channel(wpa_s, mode, channel, BW80))
3388 : 0 : return 0;
3389 : :
3390 : 0 : return wpas_p2p_get_center_80mhz(wpa_s, mode, channel);
3391 : : }
3392 : :
3393 : :
3394 : 2 : static int wpas_get_noa(void *ctx, const u8 *interface_addr, u8 *buf,
3395 : : size_t buf_len)
3396 : : {
3397 : 2 : struct wpa_supplicant *wpa_s = ctx;
3398 : :
3399 [ + - ]: 2 : for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3400 [ + - ]: 2 : if (os_memcmp(wpa_s->own_addr, interface_addr, ETH_ALEN) == 0)
3401 : 2 : break;
3402 : : }
3403 [ - + ]: 2 : if (wpa_s == NULL)
3404 : 0 : return -1;
3405 : :
3406 : 2 : return wpa_drv_get_noa(wpa_s, buf, buf_len);
3407 : : }
3408 : :
3409 : :
3410 : 0 : static int wpas_go_connected(void *ctx, const u8 *dev_addr)
3411 : : {
3412 : 0 : struct wpa_supplicant *wpa_s = ctx;
3413 : :
3414 [ # # ]: 0 : for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3415 : 0 : struct wpa_ssid *ssid = wpa_s->current_ssid;
3416 [ # # ]: 0 : if (ssid == NULL)
3417 : 0 : continue;
3418 [ # # ]: 0 : if (ssid->mode != WPAS_MODE_INFRA)
3419 : 0 : continue;
3420 [ # # ][ # # ]: 0 : if (wpa_s->wpa_state != WPA_COMPLETED &&
3421 : 0 : wpa_s->wpa_state != WPA_GROUP_HANDSHAKE)
3422 : 0 : continue;
3423 [ # # ]: 0 : if (os_memcmp(wpa_s->go_dev_addr, dev_addr, ETH_ALEN) == 0)
3424 : 0 : return 1;
3425 : : }
3426 : :
3427 : 0 : return 0;
3428 : : }
3429 : :
3430 : :
3431 : 19166 : static void wpas_p2p_debug_print(void *ctx, int level, const char *msg)
3432 : : {
3433 : 19166 : struct wpa_supplicant *wpa_s = ctx;
3434 : 19166 : wpa_msg_global(wpa_s, level, "P2P: %s", msg);
3435 : 19166 : }
3436 : :
3437 : :
3438 : 0 : int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s)
3439 : : {
3440 : : struct wpa_interface iface;
3441 : : struct wpa_supplicant *p2pdev_wpa_s;
3442 : : char ifname[100];
3443 : : char force_name[100];
3444 : : int ret;
3445 : :
3446 : 0 : os_snprintf(ifname, sizeof(ifname), P2P_MGMT_DEVICE_PREFIX "%s",
3447 : 0 : wpa_s->ifname);
3448 : 0 : force_name[0] = '\0';
3449 : 0 : wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE;
3450 : 0 : ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, NULL, NULL,
3451 : 0 : force_name, wpa_s->pending_interface_addr, NULL);
3452 [ # # ]: 0 : if (ret < 0) {
3453 : 0 : wpa_printf(MSG_DEBUG, "P2P: Failed to create P2P Device interface");
3454 : 0 : return ret;
3455 : : }
3456 : 0 : os_strlcpy(wpa_s->pending_interface_name, ifname,
3457 : : sizeof(wpa_s->pending_interface_name));
3458 : :
3459 : 0 : os_memset(&iface, 0, sizeof(iface));
3460 : 0 : iface.p2p_mgmt = 1;
3461 : 0 : iface.ifname = wpa_s->pending_interface_name;
3462 : 0 : iface.driver = wpa_s->driver->name;
3463 : 0 : iface.driver_param = wpa_s->conf->driver_param;
3464 : 0 : iface.confname = wpa_s->confname;
3465 : 0 : p2pdev_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface);
3466 [ # # ]: 0 : if (!p2pdev_wpa_s) {
3467 : 0 : wpa_printf(MSG_DEBUG, "P2P: Failed to add P2P Device interface");
3468 : 0 : return -1;
3469 : : }
3470 : 0 : p2pdev_wpa_s->parent = wpa_s;
3471 : :
3472 : 0 : wpa_s->pending_interface_name[0] = '\0';
3473 : 0 : return 0;
3474 : : }
3475 : :
3476 : :
3477 : 1 : static void wpas_presence_resp(void *ctx, const u8 *src, u8 status,
3478 : : const u8 *noa, size_t noa_len)
3479 : : {
3480 : 1 : struct wpa_supplicant *wpa_s, *intf = ctx;
3481 : : char hex[100];
3482 : :
3483 [ + - ]: 1 : for (wpa_s = intf->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3484 [ + - ]: 1 : if (wpa_s->waiting_presence_resp)
3485 : 1 : break;
3486 : : }
3487 [ - + ]: 1 : if (!wpa_s) {
3488 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No group interface was waiting for presence response");
3489 : 1 : return;
3490 : : }
3491 : 1 : wpa_s->waiting_presence_resp = 0;
3492 : :
3493 : 1 : wpa_snprintf_hex(hex, sizeof(hex), noa, noa_len);
3494 : 1 : wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PRESENCE_RESPONSE "src=" MACSTR
3495 : 6 : " status=%u noa=%s", MAC2STR(src), status, hex);
3496 : : }
3497 : :
3498 : :
3499 : : /**
3500 : : * wpas_p2p_init - Initialize P2P module for %wpa_supplicant
3501 : : * @global: Pointer to global data from wpa_supplicant_init()
3502 : : * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
3503 : : * Returns: 0 on success, -1 on failure
3504 : : */
3505 : 33 : int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
3506 : : {
3507 : : struct p2p_config p2p;
3508 : : unsigned int r;
3509 : : int i;
3510 : :
3511 [ - + ]: 33 : if (wpa_s->conf->p2p_disabled)
3512 : 0 : return 0;
3513 : :
3514 [ - + ]: 33 : if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
3515 : 0 : return 0;
3516 : :
3517 [ + + ]: 33 : if (global->p2p)
3518 : 22 : return 0;
3519 : :
3520 : 11 : os_memset(&p2p, 0, sizeof(p2p));
3521 : 11 : p2p.cb_ctx = wpa_s;
3522 : 11 : p2p.debug_print = wpas_p2p_debug_print;
3523 : 11 : p2p.p2p_scan = wpas_p2p_scan;
3524 : 11 : p2p.send_action = wpas_send_action;
3525 : 11 : p2p.send_action_done = wpas_send_action_done;
3526 : 11 : p2p.go_neg_completed = wpas_go_neg_completed;
3527 : 11 : p2p.go_neg_req_rx = wpas_go_neg_req_rx;
3528 : 11 : p2p.dev_found = wpas_dev_found;
3529 : 11 : p2p.dev_lost = wpas_dev_lost;
3530 : 11 : p2p.find_stopped = wpas_find_stopped;
3531 : 11 : p2p.start_listen = wpas_start_listen;
3532 : 11 : p2p.stop_listen = wpas_stop_listen;
3533 : 11 : p2p.send_probe_resp = wpas_send_probe_resp;
3534 : 11 : p2p.sd_request = wpas_sd_request;
3535 : 11 : p2p.sd_response = wpas_sd_response;
3536 : 11 : p2p.prov_disc_req = wpas_prov_disc_req;
3537 : 11 : p2p.prov_disc_resp = wpas_prov_disc_resp;
3538 : 11 : p2p.prov_disc_fail = wpas_prov_disc_fail;
3539 : 11 : p2p.invitation_process = wpas_invitation_process;
3540 : 11 : p2p.invitation_received = wpas_invitation_received;
3541 : 11 : p2p.invitation_result = wpas_invitation_result;
3542 : 11 : p2p.get_noa = wpas_get_noa;
3543 : 11 : p2p.go_connected = wpas_go_connected;
3544 : 11 : p2p.presence_resp = wpas_presence_resp;
3545 : :
3546 : 11 : os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
3547 : 11 : os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
3548 : 11 : p2p.dev_name = wpa_s->conf->device_name;
3549 : 11 : p2p.manufacturer = wpa_s->conf->manufacturer;
3550 : 11 : p2p.model_name = wpa_s->conf->model_name;
3551 : 11 : p2p.model_number = wpa_s->conf->model_number;
3552 : 11 : p2p.serial_number = wpa_s->conf->serial_number;
3553 [ + - ]: 11 : if (wpa_s->wps) {
3554 : 11 : os_memcpy(p2p.uuid, wpa_s->wps->uuid, 16);
3555 : 11 : p2p.config_methods = wpa_s->wps->config_methods;
3556 : : }
3557 : :
3558 [ - + ][ # # ]: 11 : if (wpa_s->conf->p2p_listen_reg_class &&
3559 : 0 : wpa_s->conf->p2p_listen_channel) {
3560 : 0 : p2p.reg_class = wpa_s->conf->p2p_listen_reg_class;
3561 : 0 : p2p.channel = wpa_s->conf->p2p_listen_channel;
3562 : : } else {
3563 : 11 : p2p.reg_class = 81;
3564 : : /*
3565 : : * Pick one of the social channels randomly as the listen
3566 : : * channel.
3567 : : */
3568 : 11 : os_get_random((u8 *) &r, sizeof(r));
3569 : 11 : p2p.channel = 1 + (r % 3) * 5;
3570 : : }
3571 : 11 : wpa_printf(MSG_DEBUG, "P2P: Own listen channel: %d", p2p.channel);
3572 : :
3573 [ - + ][ # # ]: 11 : if (wpa_s->conf->p2p_oper_reg_class &&
3574 : 0 : wpa_s->conf->p2p_oper_channel) {
3575 : 0 : p2p.op_reg_class = wpa_s->conf->p2p_oper_reg_class;
3576 : 0 : p2p.op_channel = wpa_s->conf->p2p_oper_channel;
3577 : 0 : p2p.cfg_op_channel = 1;
3578 : 0 : wpa_printf(MSG_DEBUG, "P2P: Configured operating channel: "
3579 : 0 : "%d:%d", p2p.op_reg_class, p2p.op_channel);
3580 : :
3581 : : } else {
3582 : 11 : p2p.op_reg_class = 81;
3583 : : /*
3584 : : * Use random operation channel from (1, 6, 11) if no other
3585 : : * preference is indicated.
3586 : : */
3587 : 11 : os_get_random((u8 *) &r, sizeof(r));
3588 : 11 : p2p.op_channel = 1 + (r % 3) * 5;
3589 : 11 : p2p.cfg_op_channel = 0;
3590 : 11 : wpa_printf(MSG_DEBUG, "P2P: Random operating channel: "
3591 : 22 : "%d:%d", p2p.op_reg_class, p2p.op_channel);
3592 : : }
3593 : :
3594 [ - + ][ # # ]: 11 : if (wpa_s->conf->p2p_pref_chan && wpa_s->conf->num_p2p_pref_chan) {
3595 : 0 : p2p.pref_chan = wpa_s->conf->p2p_pref_chan;
3596 : 0 : p2p.num_pref_chan = wpa_s->conf->num_p2p_pref_chan;
3597 : : }
3598 : :
3599 [ - + ][ # # ]: 11 : if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
3600 : 0 : os_memcpy(p2p.country, wpa_s->conf->country, 2);
3601 : 0 : p2p.country[2] = 0x04;
3602 : : } else
3603 : 11 : os_memcpy(p2p.country, "XX\x04", 3);
3604 : :
3605 [ - + ]: 11 : if (wpas_p2p_setup_channels(wpa_s, &p2p.channels, &p2p.cli_channels)) {
3606 : 0 : wpa_printf(MSG_ERROR, "P2P: Failed to configure supported "
3607 : : "channel list");
3608 : 0 : return -1;
3609 : : }
3610 : :
3611 : 11 : os_memcpy(p2p.pri_dev_type, wpa_s->conf->device_type,
3612 : : WPS_DEV_TYPE_LEN);
3613 : :
3614 : 11 : p2p.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
3615 : 11 : os_memcpy(p2p.sec_dev_type, wpa_s->conf->sec_device_type,
3616 : : p2p.num_sec_dev_types * WPS_DEV_TYPE_LEN);
3617 : :
3618 : 11 : p2p.concurrent_operations = !!(wpa_s->drv_flags &
3619 : : WPA_DRIVER_FLAGS_P2P_CONCURRENT);
3620 : :
3621 : 11 : p2p.max_peers = 100;
3622 : :
3623 [ - + ]: 11 : if (wpa_s->conf->p2p_ssid_postfix) {
3624 : 0 : p2p.ssid_postfix_len =
3625 : 0 : os_strlen(wpa_s->conf->p2p_ssid_postfix);
3626 [ # # ]: 0 : if (p2p.ssid_postfix_len > sizeof(p2p.ssid_postfix))
3627 : 0 : p2p.ssid_postfix_len = sizeof(p2p.ssid_postfix);
3628 : 0 : os_memcpy(p2p.ssid_postfix, wpa_s->conf->p2p_ssid_postfix,
3629 : : p2p.ssid_postfix_len);
3630 : : }
3631 : :
3632 : 11 : p2p.p2p_intra_bss = wpa_s->conf->p2p_intra_bss;
3633 : :
3634 : 11 : p2p.max_listen = wpa_s->max_remain_on_chan;
3635 : :
3636 : 11 : global->p2p = p2p_init(&p2p);
3637 [ - + ]: 11 : if (global->p2p == NULL)
3638 : 0 : return -1;
3639 : 11 : global->p2p_init_wpa_s = wpa_s;
3640 : :
3641 [ + + ]: 121 : for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) {
3642 [ + - ]: 110 : if (wpa_s->conf->wps_vendor_ext[i] == NULL)
3643 : 110 : continue;
3644 : 0 : p2p_add_wps_vendor_extension(
3645 : 0 : global->p2p, wpa_s->conf->wps_vendor_ext[i]);
3646 : : }
3647 : :
3648 : 11 : p2p_set_no_go_freq(global->p2p, &wpa_s->conf->p2p_no_go_freq);
3649 : :
3650 : 33 : return 0;
3651 : : }
3652 : :
3653 : :
3654 : : /**
3655 : : * wpas_p2p_deinit - Deinitialize per-interface P2P data
3656 : : * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
3657 : : *
3658 : : * This function deinitialize per-interface P2P data.
3659 : : */
3660 : 33 : void wpas_p2p_deinit(struct wpa_supplicant *wpa_s)
3661 : : {
3662 [ + - ][ + - ]: 33 : if (wpa_s->driver && wpa_s->drv_priv)
3663 : 33 : wpa_drv_probe_req_report(wpa_s, 0);
3664 : :
3665 [ + + ]: 33 : if (wpa_s->go_params) {
3666 : : /* Clear any stored provisioning info */
3667 : 15 : p2p_clear_provisioning_info(
3668 : 15 : wpa_s->global->p2p,
3669 : 15 : wpa_s->go_params->peer_device_addr);
3670 : : }
3671 : :
3672 : 33 : os_free(wpa_s->go_params);
3673 : 33 : wpa_s->go_params = NULL;
3674 : 33 : eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
3675 : 33 : eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
3676 : 33 : wpa_s->p2p_long_listen = 0;
3677 : 33 : eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
3678 : 33 : eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
3679 : 33 : wpas_p2p_remove_pending_group_interface(wpa_s);
3680 : 33 : eloop_cancel_timeout(wpas_p2p_group_freq_conflict, wpa_s, NULL);
3681 : 33 : wpas_p2p_listen_work_done(wpa_s);
3682 : :
3683 : : /* TODO: remove group interface from the driver if this wpa_s instance
3684 : : * is on top of a P2P group interface */
3685 : 33 : }
3686 : :
3687 : :
3688 : : /**
3689 : : * wpas_p2p_deinit_global - Deinitialize global P2P module
3690 : : * @global: Pointer to global data from wpa_supplicant_init()
3691 : : *
3692 : : * This function deinitializes the global (per device) P2P module.
3693 : : */
3694 : 11 : void wpas_p2p_deinit_global(struct wpa_global *global)
3695 : : {
3696 : : struct wpa_supplicant *wpa_s, *tmp;
3697 : :
3698 : 11 : wpa_s = global->ifaces;
3699 [ - + ]: 11 : if (wpa_s)
3700 : 0 : wpas_p2p_service_flush(wpa_s);
3701 : :
3702 [ - + ]: 11 : if (global->p2p == NULL)
3703 : 11 : return;
3704 : :
3705 : : /* Remove remaining P2P group interfaces */
3706 [ - + ][ # # ]: 11 : while (wpa_s && wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
3707 : 0 : wpa_s = wpa_s->next;
3708 [ - + ]: 11 : while (wpa_s) {
3709 : 0 : tmp = global->ifaces;
3710 [ # # ][ # # ]: 0 : while (tmp &&
3711 [ # # ]: 0 : (tmp == wpa_s ||
3712 : 0 : tmp->p2p_group_interface == NOT_P2P_GROUP_INTERFACE)) {
3713 : 0 : tmp = tmp->next;
3714 : : }
3715 [ # # ]: 0 : if (tmp == NULL)
3716 : 0 : break;
3717 : : /* Disconnect from the P2P group and deinit the interface */
3718 : 0 : wpas_p2p_disconnect(tmp);
3719 : : }
3720 : :
3721 : : /*
3722 : : * Deinit GO data on any possibly remaining interface (if main
3723 : : * interface is used as GO).
3724 : : */
3725 [ - + ]: 11 : for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3726 [ # # ]: 0 : if (wpa_s->ap_iface)
3727 : 0 : wpas_p2p_group_deinit(wpa_s);
3728 : : }
3729 : :
3730 : 11 : p2p_deinit(global->p2p);
3731 : 11 : global->p2p = NULL;
3732 : 11 : global->p2p_init_wpa_s = NULL;
3733 : : }
3734 : :
3735 : :
3736 : 139 : static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s)
3737 : : {
3738 [ + - ][ + + ]: 139 : if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
3739 : 139 : wpa_s->conf->p2p_no_group_iface)
3740 : 117 : return 0; /* separate interface disabled per configuration */
3741 [ + - ]: 22 : if (wpa_s->drv_flags &
3742 : : (WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE |
3743 : : WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P))
3744 : 22 : return 1; /* P2P group requires a new interface in every case
3745 : : */
3746 [ # # ]: 0 : if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CONCURRENT))
3747 : 0 : return 0; /* driver does not support concurrent operations */
3748 [ # # ]: 0 : if (wpa_s->global->ifaces->next)
3749 : 0 : return 1; /* more that one interface already in use */
3750 [ # # ]: 0 : if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
3751 : 0 : return 1; /* this interface is already in use */
3752 : 139 : return 0;
3753 : : }
3754 : :
3755 : :
3756 : 46 : static int wpas_p2p_start_go_neg(struct wpa_supplicant *wpa_s,
3757 : : const u8 *peer_addr,
3758 : : enum p2p_wps_method wps_method,
3759 : : int go_intent, const u8 *own_interface_addr,
3760 : : unsigned int force_freq, int persistent_group,
3761 : : struct wpa_ssid *ssid, unsigned int pref_freq)
3762 : : {
3763 [ + + ][ + + ]: 46 : if (persistent_group && wpa_s->conf->persistent_reconnect)
3764 : 4 : persistent_group = 2;
3765 : :
3766 : : /*
3767 : : * Increase GO config timeout if HT40 is used since it takes some time
3768 : : * to scan channels for coex purposes before the BSS can be started.
3769 : : */
3770 [ - + ]: 46 : p2p_set_config_timeout(wpa_s->global->p2p,
3771 : 46 : wpa_s->p2p_go_ht40 ? 255 : 100, 20);
3772 : :
3773 [ - + ][ - + ]: 46 : return p2p_connect(wpa_s->global->p2p, peer_addr, wps_method,
3774 : : go_intent, own_interface_addr, force_freq,
3775 : : persistent_group, ssid ? ssid->ssid : NULL,
3776 : : ssid ? ssid->ssid_len : 0,
3777 : 46 : wpa_s->p2p_pd_before_go_neg, pref_freq);
3778 : : }
3779 : :
3780 : :
3781 : 35 : static int wpas_p2p_auth_go_neg(struct wpa_supplicant *wpa_s,
3782 : : const u8 *peer_addr,
3783 : : enum p2p_wps_method wps_method,
3784 : : int go_intent, const u8 *own_interface_addr,
3785 : : unsigned int force_freq, int persistent_group,
3786 : : struct wpa_ssid *ssid, unsigned int pref_freq)
3787 : : {
3788 [ + + ][ + + ]: 35 : if (persistent_group && wpa_s->conf->persistent_reconnect)
3789 : 4 : persistent_group = 2;
3790 : :
3791 [ - + ][ - + ]: 35 : return p2p_authorize(wpa_s->global->p2p, peer_addr, wps_method,
3792 : : go_intent, own_interface_addr, force_freq,
3793 : : persistent_group, ssid ? ssid->ssid : NULL,
3794 : : ssid ? ssid->ssid_len : 0, pref_freq);
3795 : : }
3796 : :
3797 : :
3798 : 0 : static void wpas_p2p_check_join_scan_limit(struct wpa_supplicant *wpa_s)
3799 : : {
3800 : 0 : wpa_s->p2p_join_scan_count++;
3801 : 0 : wpa_printf(MSG_DEBUG, "P2P: Join scan attempt %d",
3802 : : wpa_s->p2p_join_scan_count);
3803 [ # # ]: 0 : if (wpa_s->p2p_join_scan_count > P2P_MAX_JOIN_SCAN_ATTEMPTS) {
3804 : 0 : wpa_printf(MSG_DEBUG, "P2P: Failed to find GO " MACSTR
3805 : : " for join operationg - stop join attempt",
3806 : 0 : MAC2STR(wpa_s->pending_join_iface_addr));
3807 : 0 : eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
3808 [ # # ]: 0 : if (wpa_s->p2p_auto_pd) {
3809 : 0 : wpa_s->p2p_auto_pd = 0;
3810 : 0 : wpa_msg_global(wpa_s, MSG_INFO,
3811 : : P2P_EVENT_PROV_DISC_FAILURE
3812 : : " p2p_dev_addr=" MACSTR " status=N/A",
3813 : 0 : MAC2STR(wpa_s->pending_join_dev_addr));
3814 : 0 : return;
3815 : : }
3816 : 0 : wpa_msg_global(wpa_s->parent, MSG_INFO,
3817 : : P2P_EVENT_GROUP_FORMATION_FAILURE);
3818 : : }
3819 : : }
3820 : :
3821 : :
3822 : 18 : static int wpas_check_freq_conflict(struct wpa_supplicant *wpa_s, int freq)
3823 : : {
3824 : : int *freqs, res, num, i;
3825 : :
3826 [ + + ]: 18 : if (wpas_p2p_num_unused_channels(wpa_s) > 0) {
3827 : : /* Multiple channels are supported and not all are in use */
3828 : 17 : return 0;
3829 : : }
3830 : :
3831 : 1 : freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
3832 [ - + ]: 1 : if (!freqs)
3833 : 0 : return 1;
3834 : :
3835 : 1 : num = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
3836 : : wpa_s->num_multichan_concurrent);
3837 [ - + ]: 1 : if (num < 0) {
3838 : 0 : res = 1;
3839 : 0 : goto exit_free;
3840 : : }
3841 : :
3842 [ + - ]: 1 : for (i = 0; i < num; i++) {
3843 [ + - ]: 1 : if (freqs[i] == freq) {
3844 : 1 : wpa_printf(MSG_DEBUG, "P2P: Frequency %d MHz in use by another virtual interface and can be used",
3845 : : freq);
3846 : 1 : res = 0;
3847 : 1 : goto exit_free;
3848 : : }
3849 : : }
3850 : :
3851 : 0 : res = 1;
3852 : :
3853 : : exit_free:
3854 : 1 : os_free(freqs);
3855 : 18 : return res;
3856 : : }
3857 : :
3858 : :
3859 : 0 : static int wpas_p2p_peer_go(struct wpa_supplicant *wpa_s,
3860 : : const u8 *peer_dev_addr)
3861 : : {
3862 : : struct wpa_bss *bss;
3863 : : int updated;
3864 : :
3865 : 0 : bss = wpa_bss_get_p2p_dev_addr(wpa_s, peer_dev_addr);
3866 [ # # ]: 0 : if (bss == NULL)
3867 : 0 : return -1;
3868 [ # # ]: 0 : if (bss->last_update_idx < wpa_s->bss_update_idx) {
3869 : 0 : wpa_printf(MSG_DEBUG, "P2P: Peer BSS entry not updated in the "
3870 : : "last scan");
3871 : 0 : return 0;
3872 : : }
3873 : :
3874 : 0 : updated = os_reltime_before(&wpa_s->p2p_auto_started,
3875 : : &bss->last_update);
3876 [ # # ]: 0 : wpa_printf(MSG_DEBUG, "P2P: Current BSS entry for peer updated at "
3877 : : "%ld.%06ld (%supdated in last scan)",
3878 : : bss->last_update.sec, bss->last_update.usec,
3879 : : updated ? "": "not ");
3880 : :
3881 : 0 : return updated;
3882 : : }
3883 : :
3884 : :
3885 : 18 : static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
3886 : : struct wpa_scan_results *scan_res)
3887 : : {
3888 : : struct wpa_bss *bss;
3889 : : int freq;
3890 : : u8 iface_addr[ETH_ALEN];
3891 : :
3892 : 18 : eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
3893 : :
3894 [ - + ]: 18 : if (wpa_s->global->p2p_disabled)
3895 : 0 : return;
3896 : :
3897 [ - + ][ + - ]: 18 : wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS) for %sjoin",
3898 : 18 : scan_res ? (int) scan_res->num : -1,
3899 : 18 : wpa_s->p2p_auto_join ? "auto_" : "");
3900 : :
3901 [ + - ]: 18 : if (scan_res)
3902 : 18 : wpas_p2p_scan_res_handler(wpa_s, scan_res);
3903 : :
3904 [ - + ]: 18 : if (wpa_s->p2p_auto_pd) {
3905 : 0 : int join = wpas_p2p_peer_go(wpa_s,
3906 : 0 : wpa_s->pending_join_dev_addr);
3907 [ # # ][ # # ]: 0 : if (join == 0 &&
3908 : 0 : wpa_s->auto_pd_scan_retry < P2P_AUTO_PD_SCAN_ATTEMPTS) {
3909 : 0 : wpa_s->auto_pd_scan_retry++;
3910 : 0 : bss = wpa_bss_get_bssid_latest(
3911 : 0 : wpa_s, wpa_s->pending_join_dev_addr);
3912 [ # # ]: 0 : if (bss) {
3913 : 0 : freq = bss->freq;
3914 : 0 : wpa_printf(MSG_DEBUG, "P2P: Scan retry %d for "
3915 : : "the peer " MACSTR " at %d MHz",
3916 : : wpa_s->auto_pd_scan_retry,
3917 : 0 : MAC2STR(wpa_s->
3918 : : pending_join_dev_addr),
3919 : : freq);
3920 : 0 : wpas_p2p_join_scan_req(wpa_s, freq);
3921 : 0 : return;
3922 : : }
3923 : : }
3924 : :
3925 [ # # ]: 0 : if (join < 0)
3926 : 0 : join = 0;
3927 : :
3928 : 0 : wpa_s->p2p_auto_pd = 0;
3929 [ # # ]: 0 : wpa_s->pending_pd_use = join ? AUTO_PD_JOIN : AUTO_PD_GO_NEG;
3930 : 0 : wpa_printf(MSG_DEBUG, "P2P: Auto PD with " MACSTR " join=%d",
3931 : 0 : MAC2STR(wpa_s->pending_join_dev_addr), join);
3932 [ # # ]: 0 : if (p2p_prov_disc_req(wpa_s->global->p2p,
3933 : 0 : wpa_s->pending_join_dev_addr,
3934 : 0 : wpa_s->pending_pd_config_methods, join,
3935 : 0 : 0, wpa_s->user_initiated_pd) < 0) {
3936 : 0 : wpa_s->p2p_auto_pd = 0;
3937 : 0 : wpa_msg_global(wpa_s, MSG_INFO,
3938 : : P2P_EVENT_PROV_DISC_FAILURE
3939 : : " p2p_dev_addr=" MACSTR " status=N/A",
3940 : 0 : MAC2STR(wpa_s->pending_join_dev_addr));
3941 : : }
3942 : 0 : return;
3943 : : }
3944 : :
3945 [ - + ]: 18 : if (wpa_s->p2p_auto_join) {
3946 : 0 : int join = wpas_p2p_peer_go(wpa_s,
3947 : 0 : wpa_s->pending_join_dev_addr);
3948 [ # # ]: 0 : if (join < 0) {
3949 : 0 : wpa_printf(MSG_DEBUG, "P2P: Peer was not found to be "
3950 : : "running a GO -> use GO Negotiation");
3951 : 0 : wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr,
3952 : 0 : wpa_s->p2p_pin, wpa_s->p2p_wps_method,
3953 : 0 : wpa_s->p2p_persistent_group, 0, 0, 0,
3954 : : wpa_s->p2p_go_intent,
3955 : : wpa_s->p2p_connect_freq,
3956 : : wpa_s->p2p_persistent_id,
3957 : 0 : wpa_s->p2p_pd_before_go_neg,
3958 : 0 : wpa_s->p2p_go_ht40,
3959 : 0 : wpa_s->p2p_go_vht);
3960 : 0 : return;
3961 : : }
3962 : :
3963 [ # # ]: 0 : wpa_printf(MSG_DEBUG, "P2P: Peer was found running GO%s -> "
3964 : : "try to join the group", join ? "" :
3965 : : " in older scan");
3966 [ # # ]: 0 : if (!join)
3967 : 0 : wpa_s->p2p_fallback_to_go_neg = 1;
3968 : : }
3969 : :
3970 : 18 : freq = p2p_get_oper_freq(wpa_s->global->p2p,
3971 : 18 : wpa_s->pending_join_iface_addr);
3972 [ + - + + ]: 36 : if (freq < 0 &&
3973 : 18 : p2p_get_interface_addr(wpa_s->global->p2p,
3974 : 18 : wpa_s->pending_join_dev_addr,
3975 [ + - ]: 3 : iface_addr) == 0 &&
3976 : 3 : os_memcmp(iface_addr, wpa_s->pending_join_dev_addr, ETH_ALEN) != 0)
3977 : : {
3978 : 3 : wpa_printf(MSG_DEBUG, "P2P: Overwrite pending interface "
3979 : : "address for join from " MACSTR " to " MACSTR
3980 : : " based on newly discovered P2P peer entry",
3981 : 18 : MAC2STR(wpa_s->pending_join_iface_addr),
3982 : 18 : MAC2STR(iface_addr));
3983 : 3 : os_memcpy(wpa_s->pending_join_iface_addr, iface_addr,
3984 : : ETH_ALEN);
3985 : :
3986 : 3 : freq = p2p_get_oper_freq(wpa_s->global->p2p,
3987 : 3 : wpa_s->pending_join_iface_addr);
3988 : : }
3989 [ - + ]: 18 : if (freq >= 0) {
3990 : 0 : wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency "
3991 : : "from P2P peer table: %d MHz", freq);
3992 : : }
3993 : 18 : bss = wpa_bss_get_bssid_latest(wpa_s, wpa_s->pending_join_iface_addr);
3994 [ + - ]: 18 : if (bss) {
3995 : 18 : freq = bss->freq;
3996 : 18 : wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency "
3997 : : "from BSS table: %d MHz (SSID %s)", freq,
3998 : 18 : wpa_ssid_txt(bss->ssid, bss->ssid_len));
3999 : : }
4000 [ + - ]: 18 : if (freq > 0) {
4001 : : u16 method;
4002 : :
4003 [ - + ]: 18 : if (wpas_check_freq_conflict(wpa_s, freq) > 0) {
4004 : 0 : wpa_msg_global(wpa_s->parent, MSG_INFO,
4005 : : P2P_EVENT_GROUP_FORMATION_FAILURE
4006 : : "reason=FREQ_CONFLICT");
4007 : 0 : return;
4008 : : }
4009 : :
4010 : 18 : wpa_printf(MSG_DEBUG, "P2P: Send Provision Discovery Request "
4011 : : "prior to joining an existing group (GO " MACSTR
4012 : : " freq=%u MHz)",
4013 : 108 : MAC2STR(wpa_s->pending_join_dev_addr), freq);
4014 : 18 : wpa_s->pending_pd_before_join = 1;
4015 : :
4016 [ - + - - ]: 18 : switch (wpa_s->pending_join_wps_method) {
4017 : : case WPS_PIN_DISPLAY:
4018 : 0 : method = WPS_CONFIG_KEYPAD;
4019 : 0 : break;
4020 : : case WPS_PIN_KEYPAD:
4021 : 18 : method = WPS_CONFIG_DISPLAY;
4022 : 18 : break;
4023 : : case WPS_PBC:
4024 : 0 : method = WPS_CONFIG_PUSHBUTTON;
4025 : 0 : break;
4026 : : default:
4027 : 0 : method = 0;
4028 : 0 : break;
4029 : : }
4030 : :
4031 [ - + ]: 18 : if ((p2p_get_provisioning_info(wpa_s->global->p2p,
4032 : 18 : wpa_s->pending_join_dev_addr) ==
4033 : : method)) {
4034 : : /*
4035 : : * We have already performed provision discovery for
4036 : : * joining the group. Proceed directly to join
4037 : : * operation without duplicated provision discovery. */
4038 : 0 : wpa_printf(MSG_DEBUG, "P2P: Provision discovery "
4039 : : "with " MACSTR " already done - proceed to "
4040 : : "join",
4041 : 0 : MAC2STR(wpa_s->pending_join_dev_addr));
4042 : 0 : wpa_s->pending_pd_before_join = 0;
4043 : 0 : goto start;
4044 : : }
4045 : :
4046 [ - + ]: 18 : if (p2p_prov_disc_req(wpa_s->global->p2p,
4047 : 18 : wpa_s->pending_join_dev_addr, method, 1,
4048 : 18 : freq, wpa_s->user_initiated_pd) < 0) {
4049 : 0 : wpa_printf(MSG_DEBUG, "P2P: Failed to send Provision "
4050 : : "Discovery Request before joining an "
4051 : : "existing group");
4052 : 0 : wpa_s->pending_pd_before_join = 0;
4053 : 0 : goto start;
4054 : : }
4055 : 18 : return;
4056 : : }
4057 : :
4058 : 0 : wpa_printf(MSG_DEBUG, "P2P: Failed to find BSS/GO - try again later");
4059 : 0 : eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
4060 : 0 : eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL);
4061 : 0 : wpas_p2p_check_join_scan_limit(wpa_s);
4062 : 0 : return;
4063 : :
4064 : : start:
4065 : : /* Start join operation immediately */
4066 : 18 : wpas_p2p_join_start(wpa_s);
4067 : : }
4068 : :
4069 : :
4070 : 18 : static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq)
4071 : : {
4072 : : int ret;
4073 : : struct wpa_driver_scan_params params;
4074 : : struct wpabuf *wps_ie, *ies;
4075 : : size_t ielen;
4076 : 18 : int freqs[2] = { 0, 0 };
4077 : :
4078 : 18 : os_memset(¶ms, 0, sizeof(params));
4079 : :
4080 : : /* P2P Wildcard SSID */
4081 : 18 : params.num_ssids = 1;
4082 : 18 : params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID;
4083 : 18 : params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
4084 : :
4085 : 18 : wpa_s->wps->dev.p2p = 1;
4086 : 18 : wps_ie = wps_build_probe_req_ie(DEV_PW_DEFAULT, &wpa_s->wps->dev,
4087 : 18 : wpa_s->wps->uuid, WPS_REQ_ENROLLEE, 0,
4088 : : NULL);
4089 [ - + ]: 18 : if (wps_ie == NULL) {
4090 : 0 : wpas_p2p_scan_res_join(wpa_s, NULL);
4091 : 0 : return;
4092 : : }
4093 : :
4094 : 18 : ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
4095 : 18 : ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
4096 [ - + ]: 18 : if (ies == NULL) {
4097 : 0 : wpabuf_free(wps_ie);
4098 : 0 : wpas_p2p_scan_res_join(wpa_s, NULL);
4099 : 0 : return;
4100 : : }
4101 : 18 : wpabuf_put_buf(ies, wps_ie);
4102 : 18 : wpabuf_free(wps_ie);
4103 : :
4104 : 18 : p2p_scan_ie(wpa_s->global->p2p, ies, NULL);
4105 : :
4106 : 18 : params.p2p_probe = 1;
4107 : 18 : params.extra_ies = wpabuf_head(ies);
4108 : 18 : params.extra_ies_len = wpabuf_len(ies);
4109 [ - + ]: 18 : if (freq > 0) {
4110 : 0 : freqs[0] = freq;
4111 : 0 : params.freqs = freqs;
4112 : : }
4113 : :
4114 : : /*
4115 : : * Run a scan to update BSS table and start Provision Discovery once
4116 : : * the new scan results become available.
4117 : : */
4118 : 18 : ret = wpa_drv_scan(wpa_s, ¶ms);
4119 [ + - ]: 18 : if (!ret) {
4120 : 18 : os_get_reltime(&wpa_s->scan_trigger_time);
4121 : 18 : wpa_s->scan_res_handler = wpas_p2p_scan_res_join;
4122 : 18 : wpa_s->own_scan_requested = 1;
4123 : : }
4124 : :
4125 : 18 : wpabuf_free(ies);
4126 : :
4127 [ - + ]: 18 : if (ret) {
4128 : 0 : wpa_printf(MSG_DEBUG, "P2P: Failed to start scan for join - "
4129 : : "try again later");
4130 : 0 : eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
4131 : 0 : eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL);
4132 : 18 : wpas_p2p_check_join_scan_limit(wpa_s);
4133 : : }
4134 : : }
4135 : :
4136 : :
4137 : 18 : static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx)
4138 : : {
4139 : 18 : struct wpa_supplicant *wpa_s = eloop_ctx;
4140 : 18 : wpas_p2p_join_scan_req(wpa_s, 0);
4141 : 18 : }
4142 : :
4143 : :
4144 : 18 : static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
4145 : : const u8 *dev_addr, enum p2p_wps_method wps_method,
4146 : : int auto_join)
4147 : : {
4148 [ - + ]: 18 : wpa_printf(MSG_DEBUG, "P2P: Request to join existing group (iface "
4149 : : MACSTR " dev " MACSTR ")%s",
4150 : 216 : MAC2STR(iface_addr), MAC2STR(dev_addr),
4151 : : auto_join ? " (auto_join)" : "");
4152 : :
4153 : 18 : wpa_s->p2p_auto_pd = 0;
4154 : 18 : wpa_s->p2p_auto_join = !!auto_join;
4155 : 18 : os_memcpy(wpa_s->pending_join_iface_addr, iface_addr, ETH_ALEN);
4156 : 18 : os_memcpy(wpa_s->pending_join_dev_addr, dev_addr, ETH_ALEN);
4157 : 18 : wpa_s->pending_join_wps_method = wps_method;
4158 : :
4159 : : /* Make sure we are not running find during connection establishment */
4160 : 18 : wpas_p2p_stop_find(wpa_s);
4161 : :
4162 : 18 : wpa_s->p2p_join_scan_count = 0;
4163 : 18 : wpas_p2p_join_scan(wpa_s, NULL);
4164 : 18 : return 0;
4165 : : }
4166 : :
4167 : :
4168 : 18 : static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s)
4169 : : {
4170 : : struct wpa_supplicant *group;
4171 : : struct p2p_go_neg_results res;
4172 : : struct wpa_bss *bss;
4173 : :
4174 : 18 : group = wpas_p2p_get_group_iface(wpa_s, 0, 0);
4175 [ - + ]: 18 : if (group == NULL)
4176 : 0 : return -1;
4177 [ + + ]: 18 : if (group != wpa_s) {
4178 : 3 : os_memcpy(group->p2p_pin, wpa_s->p2p_pin,
4179 : : sizeof(group->p2p_pin));
4180 : 3 : group->p2p_wps_method = wpa_s->p2p_wps_method;
4181 : : } else {
4182 : : /*
4183 : : * Need to mark the current interface for p2p_group_formation
4184 : : * when a separate group interface is not used. This is needed
4185 : : * to allow p2p_cancel stop a pending p2p_connect-join.
4186 : : * wpas_p2p_init_group_interface() addresses this for the case
4187 : : * where a separate group interface is used.
4188 : : */
4189 : 15 : wpa_s->global->p2p_group_formation = wpa_s;
4190 : : }
4191 : :
4192 : 18 : group->p2p_in_provisioning = 1;
4193 : 18 : group->p2p_fallback_to_go_neg = wpa_s->p2p_fallback_to_go_neg;
4194 : :
4195 : 18 : os_memset(&res, 0, sizeof(res));
4196 : 18 : os_memcpy(res.peer_interface_addr, wpa_s->pending_join_iface_addr,
4197 : : ETH_ALEN);
4198 : 18 : res.wps_method = wpa_s->pending_join_wps_method;
4199 : 18 : bss = wpa_bss_get_bssid_latest(wpa_s, wpa_s->pending_join_iface_addr);
4200 [ + - ]: 18 : if (bss) {
4201 : 18 : res.freq = bss->freq;
4202 : 18 : res.ssid_len = bss->ssid_len;
4203 : 18 : os_memcpy(res.ssid, bss->ssid, bss->ssid_len);
4204 : 18 : wpa_printf(MSG_DEBUG, "P2P: Join target GO operating frequency "
4205 : : "from BSS table: %d MHz (SSID %s)", bss->freq,
4206 : 18 : wpa_ssid_txt(bss->ssid, bss->ssid_len));
4207 : : }
4208 : :
4209 [ + - ][ - + ]: 18 : if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
4210 : 0 : wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel prior to "
4211 : : "starting client");
4212 : 0 : wpa_drv_cancel_remain_on_channel(wpa_s);
4213 : 0 : wpa_s->off_channel_freq = 0;
4214 : 0 : wpa_s->roc_waiting_drv_freq = 0;
4215 : : }
4216 : 18 : wpas_start_wps_enrollee(group, &res);
4217 : :
4218 : : /*
4219 : : * Allow a longer timeout for join-a-running-group than normal 15
4220 : : * second group formation timeout since the GO may not have authorized
4221 : : * our connection yet.
4222 : : */
4223 : 18 : eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
4224 : 18 : eloop_register_timeout(60, 0, wpas_p2p_group_formation_timeout,
4225 : : wpa_s, NULL);
4226 : :
4227 : 18 : return 0;
4228 : : }
4229 : :
4230 : :
4231 : 92 : static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
4232 : : int *force_freq, int *pref_freq, int go)
4233 : : {
4234 : : int *freqs, res;
4235 : 92 : unsigned int freq_in_use = 0, num, i;
4236 : :
4237 : 92 : freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
4238 [ - + ]: 92 : if (!freqs)
4239 : 0 : return -1;
4240 : :
4241 : 92 : num = get_shared_radio_freqs(wpa_s, freqs,
4242 : : wpa_s->num_multichan_concurrent);
4243 : 92 : wpa_printf(MSG_DEBUG,
4244 : : "P2P: Setup freqs: freq=%d num_MCC=%d shared_freqs=%u",
4245 : : freq, wpa_s->num_multichan_concurrent, num);
4246 : :
4247 [ + + ]: 92 : if (freq > 0) {
4248 : : int ret;
4249 [ + + ]: 20 : if (go)
4250 : 9 : ret = p2p_supported_freq(wpa_s->global->p2p, freq);
4251 : : else
4252 : 11 : ret = p2p_supported_freq_cli(wpa_s->global->p2p, freq);
4253 [ - + ]: 20 : if (!ret) {
4254 : 0 : wpa_printf(MSG_DEBUG, "P2P: The forced channel "
4255 : : "(%u MHz) is not supported for P2P uses",
4256 : : freq);
4257 : 0 : res = -3;
4258 : 0 : goto exit_free;
4259 : : }
4260 : :
4261 [ + + ]: 28 : for (i = 0; i < num; i++) {
4262 [ + - ]: 8 : if (freqs[i] == freq)
4263 : 8 : freq_in_use = 1;
4264 : : }
4265 : :
4266 [ + + ][ - + ]: 20 : if (num == wpa_s->num_multichan_concurrent && !freq_in_use) {
4267 : 0 : wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group on %u MHz as there are no available channels",
4268 : : freq);
4269 : 0 : res = -2;
4270 : 0 : goto exit_free;
4271 : : }
4272 : 20 : wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the "
4273 : : "requested channel (%u MHz)", freq);
4274 : 20 : *force_freq = freq;
4275 : 20 : goto exit_ok;
4276 : : }
4277 : :
4278 [ + + ]: 72 : for (i = 0; i < num; i++) {
4279 [ - + ]: 2 : if (!p2p_supported_freq(wpa_s->global->p2p, freqs[i]))
4280 : 0 : continue;
4281 : :
4282 [ + - ][ - + ]: 2 : if (*pref_freq == 0 && num < wpa_s->num_multichan_concurrent) {
4283 : 0 : wpa_printf(MSG_DEBUG, "P2P: Try to prefer a frequency (%u MHz) we are already using",
4284 : 0 : freqs[i]);
4285 : 0 : *pref_freq = freqs[i];
4286 : : } else {
4287 : 2 : wpa_printf(MSG_DEBUG, "P2P: Try to force us to use frequency (%u MHz) which is already in use",
4288 : 2 : freqs[i]);
4289 : 2 : *force_freq = freqs[i];
4290 : : }
4291 : 2 : break;
4292 : : }
4293 : :
4294 [ + + ]: 72 : if (i == num) {
4295 [ + - ][ - + ]: 70 : if (num < wpa_s->num_multichan_concurrent && num > 0) {
4296 : 0 : wpa_printf(MSG_DEBUG, "P2P: Current operating channels are not available for P2P. Try to use another channel");
4297 : 0 : *force_freq = 0;
4298 [ + - ]: 70 : } else if (num < wpa_s->num_multichan_concurrent) {
4299 : 70 : wpa_printf(MSG_DEBUG, "P2P: No current operating channels - try to use a new channel");
4300 : 70 : *force_freq = 0;
4301 : : } else {
4302 : 0 : wpa_printf(MSG_DEBUG, "P2P: All channels are in use and none of them are P2P enabled. Cannot start P2P group");
4303 : 0 : res = -2;
4304 : 0 : goto exit_free;
4305 : : }
4306 : : }
4307 : :
4308 : : exit_ok:
4309 : 92 : res = 0;
4310 : : exit_free:
4311 : 92 : os_free(freqs);
4312 : 92 : return res;
4313 : : }
4314 : :
4315 : :
4316 : : /**
4317 : : * wpas_p2p_connect - Request P2P Group Formation to be started
4318 : : * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
4319 : : * @peer_addr: Address of the peer P2P Device
4320 : : * @pin: PIN to use during provisioning or %NULL to indicate PBC mode
4321 : : * @persistent_group: Whether to create a persistent group
4322 : : * @auto_join: Whether to select join vs. GO Negotiation automatically
4323 : : * @join: Whether to join an existing group (as a client) instead of starting
4324 : : * Group Owner negotiation; @peer_addr is BSSID in that case
4325 : : * @auth: Whether to only authorize the connection instead of doing that and
4326 : : * initiating Group Owner negotiation
4327 : : * @go_intent: GO Intent or -1 to use default
4328 : : * @freq: Frequency for the group or 0 for auto-selection
4329 : : * @persistent_id: Persistent group credentials to use for forcing GO
4330 : : * parameters or -1 to generate new values (SSID/passphrase)
4331 : : * @pd: Whether to send Provision Discovery prior to GO Negotiation as an
4332 : : * interoperability workaround when initiating group formation
4333 : : * @ht40: Start GO with 40 MHz channel width
4334 : : * @vht: Start GO with VHT support
4335 : : * Returns: 0 or new PIN (if pin was %NULL) on success, -1 on unspecified
4336 : : * failure, -2 on failure due to channel not currently available,
4337 : : * -3 if forced channel is not supported
4338 : : */
4339 : 99 : int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
4340 : : const char *pin, enum p2p_wps_method wps_method,
4341 : : int persistent_group, int auto_join, int join, int auth,
4342 : : int go_intent, int freq, int persistent_id, int pd,
4343 : : int ht40, int vht)
4344 : : {
4345 : 99 : int force_freq = 0, pref_freq = 0;
4346 : 99 : int ret = 0, res;
4347 : : enum wpa_driver_if_type iftype;
4348 : : const u8 *if_addr;
4349 : 99 : struct wpa_ssid *ssid = NULL;
4350 : :
4351 [ + - ][ - + ]: 99 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
4352 : 0 : return -1;
4353 : :
4354 [ - + ]: 99 : if (persistent_id >= 0) {
4355 : 0 : ssid = wpa_config_get_network(wpa_s->conf, persistent_id);
4356 [ # # ][ # # ]: 0 : if (ssid == NULL || ssid->disabled != 2 ||
[ # # ]
4357 : 0 : ssid->mode != WPAS_MODE_P2P_GO)
4358 : 0 : return -1;
4359 : : }
4360 : :
4361 : 99 : os_free(wpa_s->global->add_psk);
4362 : 99 : wpa_s->global->add_psk = NULL;
4363 : :
4364 [ + + ]: 99 : if (go_intent < 0)
4365 : 62 : go_intent = wpa_s->conf->p2p_go_intent;
4366 : :
4367 [ + + ]: 99 : if (!auth)
4368 : 63 : wpa_s->p2p_long_listen = 0;
4369 : :
4370 : 99 : wpa_s->p2p_wps_method = wps_method;
4371 : 99 : wpa_s->p2p_persistent_group = !!persistent_group;
4372 : 99 : wpa_s->p2p_persistent_id = persistent_id;
4373 : 99 : wpa_s->p2p_go_intent = go_intent;
4374 : 99 : wpa_s->p2p_connect_freq = freq;
4375 : 99 : wpa_s->p2p_fallback_to_go_neg = 0;
4376 : 99 : wpa_s->p2p_pd_before_go_neg = !!pd;
4377 : 99 : wpa_s->p2p_go_ht40 = !!ht40;
4378 : 99 : wpa_s->p2p_go_vht = !!vht;
4379 : :
4380 [ + + ]: 99 : if (pin)
4381 : 93 : os_strlcpy(wpa_s->p2p_pin, pin, sizeof(wpa_s->p2p_pin));
4382 [ - + ]: 6 : else if (wps_method == WPS_PIN_DISPLAY) {
4383 : 0 : ret = wps_generate_pin();
4384 : 0 : os_snprintf(wpa_s->p2p_pin, sizeof(wpa_s->p2p_pin), "%08d",
4385 : : ret);
4386 : 0 : wpa_printf(MSG_DEBUG, "P2P: Randomly generated PIN: %s",
4387 : 0 : wpa_s->p2p_pin);
4388 : : } else
4389 : 6 : wpa_s->p2p_pin[0] = '\0';
4390 : :
4391 [ + + ][ - + ]: 99 : if (join || auto_join) {
4392 : : u8 iface_addr[ETH_ALEN], dev_addr[ETH_ALEN];
4393 [ + + ]: 18 : if (auth) {
4394 : 1 : wpa_printf(MSG_DEBUG, "P2P: Authorize invitation to "
4395 : : "connect a running group from " MACSTR,
4396 : 6 : MAC2STR(peer_addr));
4397 : 1 : os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
4398 : 1 : return ret;
4399 : : }
4400 : 17 : os_memcpy(dev_addr, peer_addr, ETH_ALEN);
4401 [ + + ]: 17 : if (p2p_get_interface_addr(wpa_s->global->p2p, peer_addr,
4402 : : iface_addr) < 0) {
4403 : 14 : os_memcpy(iface_addr, peer_addr, ETH_ALEN);
4404 : 14 : p2p_get_dev_addr(wpa_s->global->p2p, peer_addr,
4405 : : dev_addr);
4406 : : }
4407 [ - + ]: 17 : if (auto_join) {
4408 : 0 : os_get_reltime(&wpa_s->p2p_auto_started);
4409 : 0 : wpa_printf(MSG_DEBUG, "P2P: Auto join started at "
4410 : : "%ld.%06ld",
4411 : : wpa_s->p2p_auto_started.sec,
4412 : : wpa_s->p2p_auto_started.usec);
4413 : : }
4414 : 17 : wpa_s->user_initiated_pd = 1;
4415 [ - + ]: 17 : if (wpas_p2p_join(wpa_s, iface_addr, dev_addr, wps_method,
4416 : : auto_join) < 0)
4417 : 0 : return -1;
4418 : 17 : return ret;
4419 : : }
4420 : :
4421 : 81 : res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
4422 : : go_intent == 15);
4423 [ - + ]: 81 : if (res)
4424 : 0 : return res;
4425 [ + + ]: 81 : wpas_p2p_set_own_freq_preference(wpa_s,
4426 : 81 : force_freq ? force_freq : pref_freq);
4427 : :
4428 : 81 : wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s);
4429 : :
4430 [ + + ]: 81 : if (wpa_s->create_p2p_iface) {
4431 : : /* Prepare to add a new interface for the group */
4432 : 16 : iftype = WPA_IF_P2P_GROUP;
4433 [ + + ]: 16 : if (go_intent == 15)
4434 : 7 : iftype = WPA_IF_P2P_GO;
4435 [ - + ]: 16 : if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) {
4436 : 0 : wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
4437 : : "interface for the group");
4438 : 0 : return -1;
4439 : : }
4440 : :
4441 : 16 : if_addr = wpa_s->pending_interface_addr;
4442 : : } else
4443 : 65 : if_addr = wpa_s->own_addr;
4444 : :
4445 [ + + ]: 81 : if (auth) {
4446 [ - + ]: 35 : if (wpas_p2p_auth_go_neg(wpa_s, peer_addr, wps_method,
4447 : : go_intent, if_addr,
4448 : : force_freq, persistent_group, ssid,
4449 : : pref_freq) < 0)
4450 : 0 : return -1;
4451 : 35 : return ret;
4452 : : }
4453 : :
4454 [ - + ]: 46 : if (wpas_p2p_start_go_neg(wpa_s, peer_addr, wps_method,
4455 : : go_intent, if_addr, force_freq,
4456 : : persistent_group, ssid, pref_freq) < 0) {
4457 [ # # ]: 0 : if (wpa_s->create_p2p_iface)
4458 : 0 : wpas_p2p_remove_pending_group_interface(wpa_s);
4459 : 0 : return -1;
4460 : : }
4461 : 99 : return ret;
4462 : : }
4463 : :
4464 : :
4465 : : /**
4466 : : * wpas_p2p_remain_on_channel_cb - Indication of remain-on-channel start
4467 : : * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
4468 : : * @freq: Frequency of the channel in MHz
4469 : : * @duration: Duration of the stay on the channel in milliseconds
4470 : : *
4471 : : * This callback is called when the driver indicates that it has started the
4472 : : * requested remain-on-channel duration.
4473 : : */
4474 : 519 : void wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
4475 : : unsigned int freq, unsigned int duration)
4476 : : {
4477 [ + - ][ - + ]: 519 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
4478 : 519 : return;
4479 [ + - ]: 519 : if (wpa_s->off_channel_freq == wpa_s->pending_listen_freq) {
4480 : 519 : p2p_listen_cb(wpa_s->global->p2p, wpa_s->pending_listen_freq,
4481 : : wpa_s->pending_listen_duration);
4482 : 519 : wpa_s->pending_listen_freq = 0;
4483 : : }
4484 : : }
4485 : :
4486 : :
4487 : 99 : static int wpas_p2p_listen_start(struct wpa_supplicant *wpa_s,
4488 : : unsigned int timeout)
4489 : : {
4490 : : /* Limit maximum Listen state time based on driver limitation. */
4491 [ + - ]: 99 : if (timeout > wpa_s->max_remain_on_chan)
4492 : 99 : timeout = wpa_s->max_remain_on_chan;
4493 : :
4494 : 99 : return p2p_listen(wpa_s->global->p2p, timeout);
4495 : : }
4496 : :
4497 : :
4498 : : /**
4499 : : * wpas_p2p_cancel_remain_on_channel_cb - Remain-on-channel timeout
4500 : : * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
4501 : : * @freq: Frequency of the channel in MHz
4502 : : *
4503 : : * This callback is called when the driver indicates that a remain-on-channel
4504 : : * operation has been completed, i.e., the duration on the requested channel
4505 : : * has timed out.
4506 : : */
4507 : 518 : void wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
4508 : : unsigned int freq)
4509 : : {
4510 : 518 : wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel callback "
4511 : : "(p2p_long_listen=%d ms pending_action_tx=%p)",
4512 : : wpa_s->p2p_long_listen, offchannel_pending_action_tx(wpa_s));
4513 : 518 : wpas_p2p_listen_work_done(wpa_s);
4514 [ + - ][ - + ]: 518 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
4515 : 0 : return;
4516 [ + + ]: 518 : if (p2p_listen_end(wpa_s->global->p2p, freq) > 0)
4517 : 4 : return; /* P2P module started a new operation */
4518 [ + + ]: 514 : if (offchannel_pending_action_tx(wpa_s))
4519 : 24 : return;
4520 [ + + ]: 490 : if (wpa_s->p2p_long_listen > 0)
4521 : 4 : wpa_s->p2p_long_listen -= wpa_s->max_remain_on_chan;
4522 [ + + ]: 490 : if (wpa_s->p2p_long_listen > 0) {
4523 : 4 : wpa_printf(MSG_DEBUG, "P2P: Continuing long Listen state");
4524 : 4 : wpas_p2p_listen_start(wpa_s, wpa_s->p2p_long_listen);
4525 : : } else {
4526 : : /*
4527 : : * When listen duration is over, stop listen & update p2p_state
4528 : : * to IDLE.
4529 : : */
4530 : 518 : p2p_stop_listen(wpa_s->global->p2p);
4531 : : }
4532 : : }
4533 : :
4534 : :
4535 : : /**
4536 : : * wpas_p2p_group_remove - Remove a P2P group
4537 : : * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
4538 : : * @ifname: Network interface name of the group interface or "*" to remove all
4539 : : * groups
4540 : : * Returns: 0 on success, -1 on failure
4541 : : *
4542 : : * This function is used to remove a P2P group. This can be used to disconnect
4543 : : * from a group in which the local end is a P2P Client or to end a P2P Group in
4544 : : * case the local end is the Group Owner. If a virtual network interface was
4545 : : * created for this group, that interface will be removed. Otherwise, only the
4546 : : * configured P2P group network will be removed from the interface.
4547 : : */
4548 : 812 : int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname)
4549 : : {
4550 : 812 : struct wpa_global *global = wpa_s->global;
4551 : :
4552 [ + + ]: 812 : if (os_strcmp(ifname, "*") == 0) {
4553 : : struct wpa_supplicant *prev;
4554 : 727 : wpa_s = global->ifaces;
4555 [ + + ]: 1454 : while (wpa_s) {
4556 : 727 : prev = wpa_s;
4557 : 727 : wpa_s = wpa_s->next;
4558 [ + - ]: 727 : if (prev->p2p_group_interface !=
4559 [ + + ]: 727 : NOT_P2P_GROUP_INTERFACE ||
4560 [ + + ]: 159 : (prev->current_ssid &&
4561 : 159 : prev->current_ssid->p2p_group))
4562 : 4 : wpas_p2p_disconnect(prev);
4563 : : }
4564 : 727 : return 0;
4565 : : }
4566 : :
4567 [ + + ]: 87 : for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
4568 [ + + ]: 85 : if (os_strcmp(wpa_s->ifname, ifname) == 0)
4569 : 83 : break;
4570 : : }
4571 : :
4572 : 812 : return wpas_p2p_disconnect(wpa_s);
4573 : : }
4574 : :
4575 : :
4576 : 23 : static int wpas_p2p_select_go_freq(struct wpa_supplicant *wpa_s, int freq)
4577 : : {
4578 : : unsigned int r;
4579 : :
4580 [ - + ]: 23 : if (freq == 2) {
4581 : 0 : wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 2.4 GHz "
4582 : : "band");
4583 [ # # # # ]: 0 : if (wpa_s->best_24_freq > 0 &&
4584 : 0 : p2p_supported_freq_go(wpa_s->global->p2p,
4585 : 0 : wpa_s->best_24_freq)) {
4586 : 0 : freq = wpa_s->best_24_freq;
4587 : 0 : wpa_printf(MSG_DEBUG, "P2P: Use best 2.4 GHz band "
4588 : : "channel: %d MHz", freq);
4589 : : } else {
4590 : 0 : os_get_random((u8 *) &r, sizeof(r));
4591 : 0 : freq = 2412 + (r % 3) * 25;
4592 : 0 : wpa_printf(MSG_DEBUG, "P2P: Use random 2.4 GHz band "
4593 : : "channel: %d MHz", freq);
4594 : : }
4595 : : }
4596 : :
4597 [ - + ]: 23 : if (freq == 5) {
4598 : 0 : wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 5 GHz "
4599 : : "band");
4600 [ # # # # ]: 0 : if (wpa_s->best_5_freq > 0 &&
4601 : 0 : p2p_supported_freq_go(wpa_s->global->p2p,
4602 : 0 : wpa_s->best_5_freq)) {
4603 : 0 : freq = wpa_s->best_5_freq;
4604 : 0 : wpa_printf(MSG_DEBUG, "P2P: Use best 5 GHz band "
4605 : : "channel: %d MHz", freq);
4606 : : } else {
4607 : 0 : os_get_random((u8 *) &r, sizeof(r));
4608 : 0 : freq = 5180 + (r % 4) * 20;
4609 [ # # ]: 0 : if (!p2p_supported_freq_go(wpa_s->global->p2p, freq)) {
4610 : 0 : wpa_printf(MSG_DEBUG, "P2P: Could not select "
4611 : : "5 GHz channel for P2P group");
4612 : 0 : return -1;
4613 : : }
4614 : 0 : wpa_printf(MSG_DEBUG, "P2P: Use random 5 GHz band "
4615 : : "channel: %d MHz", freq);
4616 : : }
4617 : : }
4618 : :
4619 [ + + ][ - + ]: 23 : if (freq > 0 && !p2p_supported_freq_go(wpa_s->global->p2p, freq)) {
4620 : 0 : wpa_printf(MSG_DEBUG, "P2P: The forced channel for GO "
4621 : : "(%u MHz) is not supported for P2P uses",
4622 : : freq);
4623 : 0 : return -1;
4624 : : }
4625 : :
4626 : 23 : return freq;
4627 : : }
4628 : :
4629 : :
4630 : 23 : static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
4631 : : struct p2p_go_neg_results *params,
4632 : : int freq, int ht40, int vht,
4633 : : const struct p2p_channels *channels)
4634 : : {
4635 : : int res, *freqs;
4636 : : unsigned int pref_freq;
4637 : : unsigned int num, i;
4638 : :
4639 : 23 : os_memset(params, 0, sizeof(*params));
4640 : 23 : params->role_go = 1;
4641 : 23 : params->ht40 = ht40;
4642 : 23 : params->vht = vht;
4643 [ + + ]: 23 : if (freq) {
4644 [ - + ]: 14 : if (!freq_included(channels, freq)) {
4645 : 0 : wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not "
4646 : : "accepted", freq);
4647 : 0 : return -1;
4648 : : }
4649 : 14 : wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on forced "
4650 : : "frequency %d MHz", freq);
4651 : 14 : params->freq = freq;
4652 [ - + ][ # # ]: 9 : } else if (wpa_s->conf->p2p_oper_reg_class == 81 &&
4653 [ # # ]: 0 : wpa_s->conf->p2p_oper_channel >= 1 &&
4654 [ # # ]: 0 : wpa_s->conf->p2p_oper_channel <= 11 &&
4655 : 0 : freq_included(channels,
4656 : 0 : 2407 + 5 * wpa_s->conf->p2p_oper_channel)) {
4657 : 0 : params->freq = 2407 + 5 * wpa_s->conf->p2p_oper_channel;
4658 : 0 : wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured "
4659 : : "frequency %d MHz", params->freq);
4660 [ + - ][ + - ]: 9 : } else if ((wpa_s->conf->p2p_oper_reg_class == 115 ||
4661 [ + - ]: 9 : wpa_s->conf->p2p_oper_reg_class == 116 ||
4662 [ + - ]: 9 : wpa_s->conf->p2p_oper_reg_class == 117 ||
4663 [ + - ]: 9 : wpa_s->conf->p2p_oper_reg_class == 124 ||
4664 [ - + ]: 9 : wpa_s->conf->p2p_oper_reg_class == 126 ||
4665 [ # # ]: 0 : wpa_s->conf->p2p_oper_reg_class == 127) &&
4666 : 0 : freq_included(channels,
4667 : 0 : 5000 + 5 * wpa_s->conf->p2p_oper_channel)) {
4668 : 0 : params->freq = 5000 + 5 * wpa_s->conf->p2p_oper_channel;
4669 : 0 : wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured "
4670 : : "frequency %d MHz", params->freq);
4671 [ + - ][ - + ]: 9 : } else if (wpa_s->conf->p2p_oper_channel == 0 &&
4672 [ # # ]: 0 : wpa_s->best_overall_freq > 0 &&
4673 : 0 : p2p_supported_freq_go(wpa_s->global->p2p,
4674 [ # # ]: 0 : wpa_s->best_overall_freq) &&
4675 : 0 : freq_included(channels, wpa_s->best_overall_freq)) {
4676 : 0 : params->freq = wpa_s->best_overall_freq;
4677 : 0 : wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best overall "
4678 : : "channel %d MHz", params->freq);
4679 [ + - ][ - + ]: 9 : } else if (wpa_s->conf->p2p_oper_channel == 0 &&
4680 [ # # ]: 0 : wpa_s->best_24_freq > 0 &&
4681 : 0 : p2p_supported_freq_go(wpa_s->global->p2p,
4682 [ # # ]: 0 : wpa_s->best_24_freq) &&
4683 : 0 : freq_included(channels, wpa_s->best_24_freq)) {
4684 : 0 : params->freq = wpa_s->best_24_freq;
4685 : 0 : wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 2.4 GHz "
4686 : : "channel %d MHz", params->freq);
4687 [ + - ][ - + ]: 9 : } else if (wpa_s->conf->p2p_oper_channel == 0 &&
4688 [ # # ]: 0 : wpa_s->best_5_freq > 0 &&
4689 : 0 : p2p_supported_freq_go(wpa_s->global->p2p,
4690 [ # # ]: 0 : wpa_s->best_5_freq) &&
4691 : 0 : freq_included(channels, wpa_s->best_5_freq)) {
4692 : 0 : params->freq = wpa_s->best_5_freq;
4693 : 0 : wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 5 GHz "
4694 : : "channel %d MHz", params->freq);
4695 [ - + ]: 9 : } else if ((pref_freq = p2p_get_pref_freq(wpa_s->global->p2p,
4696 : : channels))) {
4697 : 0 : params->freq = pref_freq;
4698 : 0 : wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz from preferred "
4699 : : "channels", params->freq);
4700 : : } else {
4701 : : int chan;
4702 [ + - ]: 9 : for (chan = 0; chan < 11; chan++) {
4703 : 9 : params->freq = 2412 + chan * 5;
4704 [ + - ]: 9 : if (!wpas_p2p_disallowed_freq(wpa_s->global,
4705 [ + - ]: 9 : params->freq) &&
4706 : 9 : freq_included(channels, params->freq))
4707 : 9 : break;
4708 : : }
4709 [ - + ]: 9 : if (chan == 11) {
4710 : 0 : wpa_printf(MSG_DEBUG, "P2P: No 2.4 GHz channel "
4711 : : "allowed");
4712 : 0 : return -1;
4713 : : }
4714 : 9 : wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference "
4715 : : "known)", params->freq);
4716 : : }
4717 : :
4718 : 23 : freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
4719 [ - + ]: 23 : if (!freqs)
4720 : 0 : return -1;
4721 : :
4722 : 23 : res = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
4723 : : wpa_s->num_multichan_concurrent);
4724 [ - + ]: 23 : if (res < 0) {
4725 : 0 : os_free(freqs);
4726 : 0 : return -1;
4727 : : }
4728 : 23 : num = res;
4729 : :
4730 [ + + ]: 23 : for (i = 0; i < num; i++) {
4731 [ - + ][ # # ]: 1 : if (freq && freqs[i] == freq)
4732 : 0 : break;
4733 [ + - ][ + - ]: 1 : if (!freq && freq_included(channels, freqs[i])) {
4734 : 1 : wpa_printf(MSG_DEBUG, "P2P: Force GO on a channel we are already using (%u MHz)",
4735 : 1 : freqs[i]);
4736 : 1 : params->freq = freqs[i];
4737 : 1 : break;
4738 : : }
4739 : : }
4740 : :
4741 [ + + ]: 23 : if (i == num) {
4742 [ - + ]: 22 : if (wpas_p2p_num_unused_channels(wpa_s) <= 0) {
4743 [ # # ]: 0 : if (freq)
4744 : 0 : wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on freq (%u MHz) as all the channels are in use", freq);
4745 : : else
4746 : 0 : wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using");
4747 : 0 : os_free(freqs);
4748 : 0 : return -1;
4749 [ + - ]: 22 : } else if (num == 0) {
4750 : 22 : wpa_printf(MSG_DEBUG, "P2P: Use one of the free channels");
4751 : : } else {
4752 : 0 : wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using. Use one of the free channels");
4753 : : }
4754 : : }
4755 : :
4756 : 23 : os_free(freqs);
4757 : 23 : return 0;
4758 : : }
4759 : :
4760 : :
4761 : : static struct wpa_supplicant *
4762 : 51 : wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
4763 : : int go)
4764 : : {
4765 : : struct wpa_supplicant *group_wpa_s;
4766 : :
4767 [ + + ]: 51 : if (!wpas_p2p_create_iface(wpa_s)) {
4768 : 45 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use same interface for group "
4769 : : "operations");
4770 : 45 : wpa_s->p2p_first_connection_timeout = 0;
4771 : 45 : return wpa_s;
4772 : : }
4773 : :
4774 [ + + ][ - + ]: 6 : if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO :
4775 : : WPA_IF_P2P_CLIENT) < 0) {
4776 : 0 : wpa_msg_global(wpa_s, MSG_ERROR,
4777 : : "P2P: Failed to add group interface");
4778 : 0 : return NULL;
4779 : : }
4780 : 6 : group_wpa_s = wpas_p2p_init_group_interface(wpa_s, go);
4781 [ - + ]: 6 : if (group_wpa_s == NULL) {
4782 : 0 : wpa_msg_global(wpa_s, MSG_ERROR,
4783 : : "P2P: Failed to initialize group interface");
4784 : 0 : wpas_p2p_remove_pending_group_interface(wpa_s);
4785 : 0 : return NULL;
4786 : : }
4787 : :
4788 : 6 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use separate group interface %s",
4789 : : group_wpa_s->ifname);
4790 : 6 : group_wpa_s->p2p_first_connection_timeout = 0;
4791 : 51 : return group_wpa_s;
4792 : : }
4793 : :
4794 : :
4795 : : /**
4796 : : * wpas_p2p_group_add - Add a new P2P group with local end as Group Owner
4797 : : * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
4798 : : * @persistent_group: Whether to create a persistent group
4799 : : * @freq: Frequency for the group or 0 to indicate no hardcoding
4800 : : * @ht40: Start GO with 40 MHz channel width
4801 : : * @vht: Start GO with VHT support
4802 : : * Returns: 0 on success, -1 on failure
4803 : : *
4804 : : * This function creates a new P2P group with the local end as the Group Owner,
4805 : : * i.e., without using Group Owner Negotiation.
4806 : : */
4807 : 15 : int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
4808 : : int freq, int ht40, int vht)
4809 : : {
4810 : : struct p2p_go_neg_results params;
4811 : :
4812 [ + - ][ - + ]: 15 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
4813 : 0 : return -1;
4814 : :
4815 : 15 : os_free(wpa_s->global->add_psk);
4816 : 15 : wpa_s->global->add_psk = NULL;
4817 : :
4818 : : /* Make sure we are not running find during connection establishment */
4819 : 15 : wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND");
4820 : 15 : wpas_p2p_stop_find_oper(wpa_s);
4821 : :
4822 : 15 : freq = wpas_p2p_select_go_freq(wpa_s, freq);
4823 [ - + ]: 15 : if (freq < 0)
4824 : 0 : return -1;
4825 : :
4826 [ - + ]: 15 : if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40, vht, NULL))
4827 : 0 : return -1;
4828 [ + - - + ]: 30 : if (params.freq &&
4829 : 15 : !p2p_supported_freq_go(wpa_s->global->p2p, params.freq)) {
4830 : 0 : wpa_printf(MSG_DEBUG, "P2P: The selected channel for GO "
4831 : : "(%u MHz) is not supported for P2P uses",
4832 : : params.freq);
4833 : 0 : return -1;
4834 : : }
4835 : 15 : p2p_go_params(wpa_s->global->p2p, ¶ms);
4836 : 15 : params.persistent_group = persistent_group;
4837 : :
4838 : 15 : wpa_s = wpas_p2p_get_group_iface(wpa_s, 0, 1);
4839 [ - + ]: 15 : if (wpa_s == NULL)
4840 : 0 : return -1;
4841 : 15 : wpas_start_wps_go(wpa_s, ¶ms, 0);
4842 : :
4843 : 15 : return 0;
4844 : : }
4845 : :
4846 : :
4847 : 10 : static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
4848 : : struct wpa_ssid *params, int addr_allocated)
4849 : : {
4850 : : struct wpa_ssid *ssid;
4851 : :
4852 : 10 : wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 0);
4853 [ - + ]: 10 : if (wpa_s == NULL)
4854 : 0 : return -1;
4855 : 10 : wpa_s->p2p_last_4way_hs_fail = NULL;
4856 : :
4857 : 10 : wpa_supplicant_ap_deinit(wpa_s);
4858 : :
4859 : 10 : ssid = wpa_config_add_network(wpa_s->conf);
4860 [ - + ]: 10 : if (ssid == NULL)
4861 : 0 : return -1;
4862 : 10 : wpa_config_set_network_defaults(ssid);
4863 : 10 : ssid->temporary = 1;
4864 : 10 : ssid->proto = WPA_PROTO_RSN;
4865 : 10 : ssid->pairwise_cipher = WPA_CIPHER_CCMP;
4866 : 10 : ssid->group_cipher = WPA_CIPHER_CCMP;
4867 : 10 : ssid->key_mgmt = WPA_KEY_MGMT_PSK;
4868 : 10 : ssid->ssid = os_malloc(params->ssid_len);
4869 [ - + ]: 10 : if (ssid->ssid == NULL) {
4870 : 0 : wpa_config_remove_network(wpa_s->conf, ssid->id);
4871 : 0 : return -1;
4872 : : }
4873 : 10 : os_memcpy(ssid->ssid, params->ssid, params->ssid_len);
4874 : 10 : ssid->ssid_len = params->ssid_len;
4875 : 10 : ssid->p2p_group = 1;
4876 : 10 : ssid->export_keys = 1;
4877 [ + - ]: 10 : if (params->psk_set) {
4878 : 10 : os_memcpy(ssid->psk, params->psk, 32);
4879 : 10 : ssid->psk_set = 1;
4880 : : }
4881 [ - + ]: 10 : if (params->passphrase)
4882 : 0 : ssid->passphrase = os_strdup(params->passphrase);
4883 : :
4884 : 10 : wpa_s->show_group_started = 1;
4885 : :
4886 : 10 : wpa_supplicant_select_network(wpa_s, ssid);
4887 : :
4888 : 10 : return 0;
4889 : : }
4890 : :
4891 : :
4892 : 18 : int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
4893 : : struct wpa_ssid *ssid, int addr_allocated,
4894 : : int freq, int ht40, int vht,
4895 : : const struct p2p_channels *channels,
4896 : : int connection_timeout)
4897 : : {
4898 : : struct p2p_go_neg_results params;
4899 : 18 : int go = 0;
4900 : :
4901 [ + - ][ - + ]: 18 : if (ssid->disabled != 2 || ssid->ssid == NULL)
4902 : 0 : return -1;
4903 : :
4904 [ - + ][ # # ]: 18 : if (wpas_get_p2p_group(wpa_s, ssid->ssid, ssid->ssid_len, &go) &&
4905 : 0 : go == (ssid->mode == WPAS_MODE_P2P_GO)) {
4906 : 0 : wpa_printf(MSG_DEBUG, "P2P: Requested persistent group is "
4907 : : "already running");
4908 : 0 : return 0;
4909 : : }
4910 : :
4911 : 18 : os_free(wpa_s->global->add_psk);
4912 : 18 : wpa_s->global->add_psk = NULL;
4913 : :
4914 : : /* Make sure we are not running find during connection establishment */
4915 : 18 : wpas_p2p_stop_find_oper(wpa_s);
4916 : :
4917 : 18 : wpa_s->p2p_fallback_to_go_neg = 0;
4918 : :
4919 [ + + ]: 18 : if (ssid->mode == WPAS_MODE_INFRA)
4920 : 10 : return wpas_start_p2p_client(wpa_s, ssid, addr_allocated);
4921 : :
4922 [ - + ]: 8 : if (ssid->mode != WPAS_MODE_P2P_GO)
4923 : 0 : return -1;
4924 : :
4925 : 8 : freq = wpas_p2p_select_go_freq(wpa_s, freq);
4926 [ - + ]: 8 : if (freq < 0)
4927 : 0 : return -1;
4928 : :
4929 [ - + ]: 8 : if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40, vht, channels))
4930 : 0 : return -1;
4931 : :
4932 : 8 : params.role_go = 1;
4933 : 8 : params.psk_set = ssid->psk_set;
4934 [ + - ]: 8 : if (params.psk_set)
4935 : 8 : os_memcpy(params.psk, ssid->psk, sizeof(params.psk));
4936 [ + - ]: 8 : if (ssid->passphrase) {
4937 [ - + ]: 8 : if (os_strlen(ssid->passphrase) >= sizeof(params.passphrase)) {
4938 : 0 : wpa_printf(MSG_ERROR, "P2P: Invalid passphrase in "
4939 : : "persistent group");
4940 : 0 : return -1;
4941 : : }
4942 : 8 : os_strlcpy(params.passphrase, ssid->passphrase,
4943 : : sizeof(params.passphrase));
4944 : : }
4945 : 8 : os_memcpy(params.ssid, ssid->ssid, ssid->ssid_len);
4946 : 8 : params.ssid_len = ssid->ssid_len;
4947 : 8 : params.persistent_group = 1;
4948 : :
4949 : 8 : wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 1);
4950 [ - + ]: 8 : if (wpa_s == NULL)
4951 : 0 : return -1;
4952 : :
4953 : 8 : wpa_s->p2p_first_connection_timeout = connection_timeout;
4954 : 8 : wpas_start_wps_go(wpa_s, ¶ms, 0);
4955 : :
4956 : 18 : return 0;
4957 : : }
4958 : :
4959 : :
4960 : 321 : static void wpas_p2p_ie_update(void *ctx, struct wpabuf *beacon_ies,
4961 : : struct wpabuf *proberesp_ies)
4962 : : {
4963 : 321 : struct wpa_supplicant *wpa_s = ctx;
4964 [ + - ]: 321 : if (wpa_s->ap_iface) {
4965 : 321 : struct hostapd_data *hapd = wpa_s->ap_iface->bss[0];
4966 [ + + ]: 321 : if (!(hapd->conf->p2p & P2P_GROUP_OWNER)) {
4967 : 8 : wpabuf_free(beacon_ies);
4968 : 8 : wpabuf_free(proberesp_ies);
4969 : 321 : return;
4970 : : }
4971 [ + + ]: 313 : if (beacon_ies) {
4972 : 116 : wpabuf_free(hapd->p2p_beacon_ie);
4973 : 116 : hapd->p2p_beacon_ie = beacon_ies;
4974 : : }
4975 : 313 : wpabuf_free(hapd->p2p_probe_resp_ie);
4976 : 313 : hapd->p2p_probe_resp_ie = proberesp_ies;
4977 : : } else {
4978 : 0 : wpabuf_free(beacon_ies);
4979 : 0 : wpabuf_free(proberesp_ies);
4980 : : }
4981 : 313 : wpa_supplicant_ap_update_beacon(wpa_s);
4982 : : }
4983 : :
4984 : :
4985 : 235 : static void wpas_p2p_idle_update(void *ctx, int idle)
4986 : : {
4987 : 235 : struct wpa_supplicant *wpa_s = ctx;
4988 [ - + ]: 235 : if (!wpa_s->ap_iface)
4989 : 235 : return;
4990 [ + + ]: 235 : wpa_printf(MSG_DEBUG, "P2P: GO - group %sidle", idle ? "" : "not ");
4991 [ + + ]: 235 : if (idle)
4992 : 125 : wpas_p2p_set_group_idle_timeout(wpa_s);
4993 : : else
4994 : 110 : eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
4995 : : }
4996 : :
4997 : :
4998 : 60 : struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
4999 : : struct wpa_ssid *ssid)
5000 : : {
5001 : : struct p2p_group *group;
5002 : : struct p2p_group_config *cfg;
5003 : :
5004 [ + - ][ - + ]: 60 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
5005 : 0 : return NULL;
5006 : :
5007 : 60 : cfg = os_zalloc(sizeof(*cfg));
5008 [ - + ]: 60 : if (cfg == NULL)
5009 : 0 : return NULL;
5010 : :
5011 [ + + ][ + + ]: 60 : if (ssid->p2p_persistent_group && wpa_s->conf->persistent_reconnect)
5012 : 12 : cfg->persistent_group = 2;
5013 [ + + ]: 48 : else if (ssid->p2p_persistent_group)
5014 : 1 : cfg->persistent_group = 1;
5015 : 60 : os_memcpy(cfg->interface_addr, wpa_s->own_addr, ETH_ALEN);
5016 [ - + ][ # # ]: 60 : if (wpa_s->max_stations &&
5017 : 0 : wpa_s->max_stations < wpa_s->conf->max_num_sta)
5018 : 0 : cfg->max_clients = wpa_s->max_stations;
5019 : : else
5020 : 60 : cfg->max_clients = wpa_s->conf->max_num_sta;
5021 : 60 : os_memcpy(cfg->ssid, ssid->ssid, ssid->ssid_len);
5022 : 60 : cfg->ssid_len = ssid->ssid_len;
5023 : 60 : cfg->cb_ctx = wpa_s;
5024 : 60 : cfg->ie_update = wpas_p2p_ie_update;
5025 : 60 : cfg->idle_update = wpas_p2p_idle_update;
5026 : :
5027 : 60 : group = p2p_group_init(wpa_s->global->p2p, cfg);
5028 [ - + ]: 60 : if (group == NULL)
5029 : 0 : os_free(cfg);
5030 [ + + ]: 60 : if (ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION)
5031 : 25 : p2p_group_notif_formation_done(group);
5032 : 60 : wpa_s->p2p_group = group;
5033 : 60 : return group;
5034 : : }
5035 : :
5036 : :
5037 : 134 : void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
5038 : : int registrar)
5039 : : {
5040 : 134 : struct wpa_ssid *ssid = wpa_s->current_ssid;
5041 : :
5042 [ + + ]: 134 : if (!wpa_s->p2p_in_provisioning) {
5043 : 46 : wpa_printf(MSG_DEBUG, "P2P: Ignore WPS success event - P2P "
5044 : : "provisioning not in progress");
5045 : 134 : return;
5046 : : }
5047 : :
5048 [ + - ][ + + ]: 88 : if (ssid && ssid->mode == WPAS_MODE_INFRA) {
5049 : : u8 go_dev_addr[ETH_ALEN];
5050 : 53 : os_memcpy(go_dev_addr, wpa_s->bssid, ETH_ALEN);
5051 : 53 : wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid,
5052 : : ssid->ssid_len);
5053 : : /* Clear any stored provisioning info */
5054 : 53 : p2p_clear_provisioning_info(wpa_s->global->p2p, go_dev_addr);
5055 : : }
5056 : :
5057 : 88 : eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->parent,
5058 : : NULL);
5059 : 88 : wpa_s->p2p_go_group_formation_completed = 1;
5060 [ + - ][ + + ]: 88 : if (ssid && ssid->mode == WPAS_MODE_INFRA) {
5061 : : /*
5062 : : * Use a separate timeout for initial data connection to
5063 : : * complete to allow the group to be removed automatically if
5064 : : * something goes wrong in this step before the P2P group idle
5065 : : * timeout mechanism is taken into use.
5066 : : */
5067 : 53 : wpa_dbg(wpa_s, MSG_DEBUG,
5068 : : "P2P: Re-start group formation timeout (%d seconds) as client for initial connection",
5069 : : P2P_MAX_INITIAL_CONN_WAIT);
5070 : 53 : eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0,
5071 : : wpas_p2p_group_formation_timeout,
5072 : 53 : wpa_s->parent, NULL);
5073 [ + - ]: 35 : } else if (ssid) {
5074 : : /*
5075 : : * Use a separate timeout for initial data connection to
5076 : : * complete to allow the group to be removed automatically if
5077 : : * the client does not complete data connection successfully.
5078 : : */
5079 : 35 : wpa_dbg(wpa_s, MSG_DEBUG,
5080 : : "P2P: Re-start group formation timeout (%d seconds) as GO for initial connection",
5081 : : P2P_MAX_INITIAL_CONN_WAIT_GO);
5082 : 35 : eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT_GO, 0,
5083 : : wpas_p2p_group_formation_timeout,
5084 : 35 : wpa_s->parent, NULL);
5085 : : /*
5086 : : * Complete group formation on first successful data connection
5087 : : */
5088 : 35 : wpa_s->p2p_go_group_formation_completed = 0;
5089 : : }
5090 [ + - ]: 88 : if (wpa_s->global->p2p)
5091 : 88 : p2p_wps_success_cb(wpa_s->global->p2p, peer_addr);
5092 : 88 : wpas_group_formation_completed(wpa_s, 1);
5093 : : }
5094 : :
5095 : :
5096 : 15 : void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
5097 : : struct wps_event_fail *fail)
5098 : : {
5099 [ + - ]: 15 : if (!wpa_s->p2p_in_provisioning) {
5100 : 15 : wpa_printf(MSG_DEBUG, "P2P: Ignore WPS fail event - P2P "
5101 : : "provisioning not in progress");
5102 : 15 : return;
5103 : : }
5104 : :
5105 [ # # ]: 0 : if (wpa_s->go_params) {
5106 : 0 : p2p_clear_provisioning_info(
5107 : 0 : wpa_s->global->p2p,
5108 : 0 : wpa_s->go_params->peer_device_addr);
5109 : : }
5110 : :
5111 : 0 : wpas_notify_p2p_wps_failed(wpa_s, fail);
5112 : : }
5113 : :
5114 : :
5115 : 3 : int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
5116 : : const char *config_method,
5117 : : enum wpas_p2p_prov_disc_use use)
5118 : : {
5119 : : u16 config_methods;
5120 : :
5121 : 3 : wpa_s->p2p_fallback_to_go_neg = 0;
5122 : 3 : wpa_s->pending_pd_use = NORMAL_PD;
5123 [ + + ]: 3 : if (os_strncmp(config_method, "display", 7) == 0)
5124 : 1 : config_methods = WPS_CONFIG_DISPLAY;
5125 [ + + ]: 2 : else if (os_strncmp(config_method, "keypad", 6) == 0)
5126 : 1 : config_methods = WPS_CONFIG_KEYPAD;
5127 [ - + ][ # # ]: 1 : else if (os_strncmp(config_method, "pbc", 3) == 0 ||
5128 : 0 : os_strncmp(config_method, "pushbutton", 10) == 0)
5129 : 1 : config_methods = WPS_CONFIG_PUSHBUTTON;
5130 : : else {
5131 : 0 : wpa_printf(MSG_DEBUG, "P2P: Unknown config method");
5132 : 0 : return -1;
5133 : : }
5134 : :
5135 [ - + ]: 3 : if (use == WPAS_P2P_PD_AUTO) {
5136 : 0 : os_memcpy(wpa_s->pending_join_dev_addr, peer_addr, ETH_ALEN);
5137 : 0 : wpa_s->pending_pd_config_methods = config_methods;
5138 : 0 : wpa_s->p2p_auto_pd = 1;
5139 : 0 : wpa_s->p2p_auto_join = 0;
5140 : 0 : wpa_s->pending_pd_before_join = 0;
5141 : 0 : wpa_s->auto_pd_scan_retry = 0;
5142 : 0 : wpas_p2p_stop_find(wpa_s);
5143 : 0 : wpa_s->p2p_join_scan_count = 0;
5144 : 0 : os_get_reltime(&wpa_s->p2p_auto_started);
5145 : 0 : wpa_printf(MSG_DEBUG, "P2P: Auto PD started at %ld.%06ld",
5146 : : wpa_s->p2p_auto_started.sec,
5147 : : wpa_s->p2p_auto_started.usec);
5148 : 0 : wpas_p2p_join_scan(wpa_s, NULL);
5149 : 0 : return 0;
5150 : : }
5151 : :
5152 [ + - ][ - + ]: 3 : if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled)
5153 : 0 : return -1;
5154 : :
5155 : 3 : return p2p_prov_disc_req(wpa_s->global->p2p, peer_addr,
5156 : : config_methods, use == WPAS_P2P_PD_FOR_JOIN,
5157 : : 0, 1);
5158 : : }
5159 : :
5160 : :
5161 : 30 : int wpas_p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
5162 : : char *end)
5163 : : {
5164 : 30 : return p2p_scan_result_text(ies, ies_len, buf, end);
5165 : : }
5166 : :
5167 : :
5168 : 985 : static void wpas_p2p_clear_pending_action_tx(struct wpa_supplicant *wpa_s)
5169 : : {
5170 [ + - ]: 985 : if (!offchannel_pending_action_tx(wpa_s))
5171 : 985 : return;
5172 : :
5173 : 0 : wpa_printf(MSG_DEBUG, "P2P: Drop pending Action TX due to new "
5174 : : "operation request");
5175 : 0 : offchannel_clear_pending_action_tx(wpa_s);
5176 : : }
5177 : :
5178 : :
5179 : 110 : int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
5180 : : enum p2p_discovery_type type,
5181 : : unsigned int num_req_dev_types, const u8 *req_dev_types,
5182 : : const u8 *dev_id, unsigned int search_delay)
5183 : : {
5184 : 110 : wpas_p2p_clear_pending_action_tx(wpa_s);
5185 : 110 : wpa_s->p2p_long_listen = 0;
5186 : :
5187 [ + - ][ + - ]: 110 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL ||
[ - + ]
5188 : 110 : wpa_s->p2p_in_provisioning)
5189 : 0 : return -1;
5190 : :
5191 : 110 : wpa_supplicant_cancel_sched_scan(wpa_s);
5192 : :
5193 : 110 : return p2p_find(wpa_s->global->p2p, timeout, type,
5194 : : num_req_dev_types, req_dev_types, dev_id,
5195 : : search_delay);
5196 : : }
5197 : :
5198 : :
5199 : 780 : static int wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s)
5200 : : {
5201 : 780 : wpas_p2p_clear_pending_action_tx(wpa_s);
5202 : 780 : wpa_s->p2p_long_listen = 0;
5203 : 780 : eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
5204 : 780 : eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
5205 : :
5206 [ + - ]: 780 : if (wpa_s->global->p2p)
5207 : 780 : p2p_stop_find(wpa_s->global->p2p);
5208 : :
5209 : 780 : return 0;
5210 : : }
5211 : :
5212 : :
5213 : 747 : void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s)
5214 : : {
5215 [ - + ]: 747 : if (wpas_p2p_stop_find_oper(wpa_s) > 0)
5216 : 747 : return;
5217 : 747 : wpas_p2p_remove_pending_group_interface(wpa_s);
5218 : : }
5219 : :
5220 : :
5221 : 0 : static void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx)
5222 : : {
5223 : 0 : struct wpa_supplicant *wpa_s = eloop_ctx;
5224 : 0 : wpa_s->p2p_long_listen = 0;
5225 : 0 : }
5226 : :
5227 : :
5228 : 95 : int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout)
5229 : : {
5230 : : int res;
5231 : :
5232 [ + - ][ - + ]: 95 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
5233 : 0 : return -1;
5234 : :
5235 : 95 : wpa_supplicant_cancel_sched_scan(wpa_s);
5236 : 95 : wpas_p2p_clear_pending_action_tx(wpa_s);
5237 : :
5238 [ + - ]: 95 : if (timeout == 0) {
5239 : : /*
5240 : : * This is a request for unlimited Listen state. However, at
5241 : : * least for now, this is mapped to a Listen state for one
5242 : : * hour.
5243 : : */
5244 : 95 : timeout = 3600;
5245 : : }
5246 : 95 : eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
5247 : 95 : wpa_s->p2p_long_listen = 0;
5248 : :
5249 : : /*
5250 : : * Stop previous find/listen operation to avoid trying to request a new
5251 : : * remain-on-channel operation while the driver is still running the
5252 : : * previous one.
5253 : : */
5254 [ + - ]: 95 : if (wpa_s->global->p2p)
5255 : 95 : p2p_stop_find(wpa_s->global->p2p);
5256 : :
5257 : 95 : res = wpas_p2p_listen_start(wpa_s, timeout * 1000);
5258 [ + - ][ + - ]: 95 : if (res == 0 && timeout * 1000 > wpa_s->max_remain_on_chan) {
5259 : 95 : wpa_s->p2p_long_listen = timeout * 1000;
5260 : 95 : eloop_register_timeout(timeout, 0,
5261 : : wpas_p2p_long_listen_timeout,
5262 : : wpa_s, NULL);
5263 : : }
5264 : :
5265 : 95 : return res;
5266 : : }
5267 : :
5268 : :
5269 : 484 : int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
5270 : : u8 *buf, size_t len, int p2p_group)
5271 : : {
5272 : : struct wpabuf *p2p_ie;
5273 : : int ret;
5274 : :
5275 [ + + ]: 484 : if (wpa_s->global->p2p_disabled)
5276 : 3 : return -1;
5277 [ - + ]: 481 : if (wpa_s->global->p2p == NULL)
5278 : 0 : return -1;
5279 [ + + ]: 481 : if (bss == NULL)
5280 : 6 : return -1;
5281 : :
5282 : 475 : p2p_ie = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
5283 : 475 : ret = p2p_assoc_req_ie(wpa_s->global->p2p, bss->bssid, buf, len,
5284 : : p2p_group, p2p_ie);
5285 : 475 : wpabuf_free(p2p_ie);
5286 : :
5287 : 484 : return ret;
5288 : : }
5289 : :
5290 : :
5291 : 375 : int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr,
5292 : : const u8 *dst, const u8 *bssid,
5293 : : const u8 *ie, size_t ie_len, int ssi_signal)
5294 : : {
5295 [ - + ]: 375 : if (wpa_s->global->p2p_disabled)
5296 : 0 : return 0;
5297 [ - + ]: 375 : if (wpa_s->global->p2p == NULL)
5298 : 0 : return 0;
5299 : :
5300 [ - + + ]: 375 : switch (p2p_probe_req_rx(wpa_s->global->p2p, addr, dst, bssid,
5301 : : ie, ie_len)) {
5302 : : case P2P_PREQ_NOT_P2P:
5303 : 0 : wpas_notify_preq(wpa_s, addr, dst, bssid, ie, ie_len,
5304 : : ssi_signal);
5305 : : /* fall through */
5306 : : case P2P_PREQ_MALFORMED:
5307 : : case P2P_PREQ_NOT_LISTEN:
5308 : : case P2P_PREQ_NOT_PROCESSED:
5309 : : default: /* make gcc happy */
5310 : 373 : return 0;
5311 : : case P2P_PREQ_PROCESSED:
5312 : 375 : return 1;
5313 : : }
5314 : : }
5315 : :
5316 : :
5317 : 246 : void wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da,
5318 : : const u8 *sa, const u8 *bssid,
5319 : : u8 category, const u8 *data, size_t len, int freq)
5320 : : {
5321 [ - + ]: 246 : if (wpa_s->global->p2p_disabled)
5322 : 0 : return;
5323 [ - + ]: 246 : if (wpa_s->global->p2p == NULL)
5324 : 0 : return;
5325 : :
5326 : 246 : p2p_rx_action(wpa_s->global->p2p, da, sa, bssid, category, data, len,
5327 : : freq);
5328 : : }
5329 : :
5330 : :
5331 : 451 : void wpas_p2p_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ies)
5332 : : {
5333 [ + + ]: 451 : if (wpa_s->global->p2p_disabled)
5334 : 1 : return;
5335 [ - + ]: 450 : if (wpa_s->global->p2p == NULL)
5336 : 0 : return;
5337 : :
5338 : 451 : p2p_scan_ie(wpa_s->global->p2p, ies, NULL);
5339 : : }
5340 : :
5341 : :
5342 : 60 : void wpas_p2p_group_deinit(struct wpa_supplicant *wpa_s)
5343 : : {
5344 : 60 : p2p_group_deinit(wpa_s->p2p_group);
5345 : 60 : wpa_s->p2p_group = NULL;
5346 : :
5347 : 60 : wpa_s->ap_configured_cb = NULL;
5348 : 60 : wpa_s->ap_configured_cb_ctx = NULL;
5349 : 60 : wpa_s->ap_configured_cb_data = NULL;
5350 : 60 : wpa_s->connect_without_scan = NULL;
5351 : 60 : }
5352 : :
5353 : :
5354 : 0 : int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr)
5355 : : {
5356 : 0 : wpa_s->p2p_long_listen = 0;
5357 : :
5358 [ # # ][ # # ]: 0 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
5359 : 0 : return -1;
5360 : :
5361 : 0 : return p2p_reject(wpa_s->global->p2p, addr);
5362 : : }
5363 : :
5364 : :
5365 : : /* Invite to reinvoke a persistent group */
5366 : 7 : int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
5367 : : struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
5368 : : int ht40, int vht, int pref_freq)
5369 : : {
5370 : : enum p2p_invite_role role;
5371 : 7 : u8 *bssid = NULL;
5372 : 7 : int force_freq = 0;
5373 : : int res;
5374 : 7 : int no_pref_freq_given = pref_freq == 0;
5375 : :
5376 : 7 : wpa_s->global->p2p_invite_group = NULL;
5377 [ + - ]: 7 : if (peer_addr)
5378 : 7 : os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
5379 : : else
5380 : 0 : os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
5381 : :
5382 : 7 : wpa_s->p2p_persistent_go_freq = freq;
5383 : 7 : wpa_s->p2p_go_ht40 = !!ht40;
5384 [ + + ]: 7 : if (ssid->mode == WPAS_MODE_P2P_GO) {
5385 : 3 : role = P2P_INVITE_ROLE_GO;
5386 [ - + ]: 3 : if (peer_addr == NULL) {
5387 : 0 : wpa_printf(MSG_DEBUG, "P2P: Missing peer "
5388 : : "address in invitation command");
5389 : 0 : return -1;
5390 : : }
5391 [ - + ]: 3 : if (wpas_p2p_create_iface(wpa_s)) {
5392 [ # # ]: 0 : if (wpas_p2p_add_group_interface(wpa_s,
5393 : : WPA_IF_P2P_GO) < 0) {
5394 : 0 : wpa_printf(MSG_ERROR, "P2P: Failed to "
5395 : : "allocate a new interface for the "
5396 : : "group");
5397 : 0 : return -1;
5398 : : }
5399 : 0 : bssid = wpa_s->pending_interface_addr;
5400 : : } else
5401 : 3 : bssid = wpa_s->own_addr;
5402 : : } else {
5403 : 4 : role = P2P_INVITE_ROLE_CLIENT;
5404 : 4 : peer_addr = ssid->bssid;
5405 : : }
5406 : 7 : wpa_s->pending_invite_ssid_id = ssid->id;
5407 : :
5408 : 7 : res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
5409 : : role == P2P_INVITE_ROLE_GO);
5410 [ - + ]: 7 : if (res)
5411 : 0 : return res;
5412 : :
5413 [ + - ][ - + ]: 7 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
5414 : 0 : return -1;
5415 : :
5416 [ - + ][ # # ]: 7 : if (wpa_s->parent->conf->p2p_ignore_shared_freq &&
5417 [ # # ][ # # ]: 0 : no_pref_freq_given && pref_freq > 0 &&
5418 [ # # ]: 0 : wpa_s->num_multichan_concurrent > 1 &&
5419 : 0 : wpas_p2p_num_unused_channels(wpa_s) > 0) {
5420 : 0 : wpa_printf(MSG_DEBUG, "P2P: Ignore own channel preference %d MHz for invitation due to p2p_ignore_shared_freq=1 configuration",
5421 : : pref_freq);
5422 : 0 : pref_freq = 0;
5423 : : }
5424 : :
5425 : 7 : return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
5426 : 7 : ssid->ssid, ssid->ssid_len, force_freq, go_dev_addr,
5427 : : 1, pref_freq);
5428 : : }
5429 : :
5430 : :
5431 : : /* Invite to join an active group */
5432 : 4 : int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
5433 : : const u8 *peer_addr, const u8 *go_dev_addr)
5434 : : {
5435 : 4 : struct wpa_global *global = wpa_s->global;
5436 : : enum p2p_invite_role role;
5437 : 4 : u8 *bssid = NULL;
5438 : : struct wpa_ssid *ssid;
5439 : : int persistent;
5440 : 4 : int freq = 0, force_freq = 0, pref_freq = 0;
5441 : : int res;
5442 : :
5443 : 4 : wpa_s->p2p_persistent_go_freq = 0;
5444 : 4 : wpa_s->p2p_go_ht40 = 0;
5445 : 4 : wpa_s->p2p_go_vht = 0;
5446 : :
5447 [ + - ]: 4 : for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
5448 [ + - ]: 4 : if (os_strcmp(wpa_s->ifname, ifname) == 0)
5449 : 4 : break;
5450 : : }
5451 [ - + ]: 4 : if (wpa_s == NULL) {
5452 : 0 : wpa_printf(MSG_DEBUG, "P2P: Interface '%s' not found", ifname);
5453 : 0 : return -1;
5454 : : }
5455 : :
5456 : 4 : ssid = wpa_s->current_ssid;
5457 [ - + ]: 4 : if (ssid == NULL) {
5458 : 0 : wpa_printf(MSG_DEBUG, "P2P: No current SSID to use for "
5459 : : "invitation");
5460 : 0 : return -1;
5461 : : }
5462 : :
5463 : 4 : wpa_s->global->p2p_invite_group = wpa_s;
5464 [ + + - + ]: 6 : persistent = ssid->p2p_persistent_group &&
5465 : 2 : wpas_p2p_get_persistent(wpa_s->parent, peer_addr,
5466 : 2 : ssid->ssid, ssid->ssid_len);
5467 : :
5468 [ + - ]: 4 : if (ssid->mode == WPAS_MODE_P2P_GO) {
5469 : 4 : role = P2P_INVITE_ROLE_ACTIVE_GO;
5470 : 4 : bssid = wpa_s->own_addr;
5471 [ + - ]: 4 : if (go_dev_addr == NULL)
5472 : 4 : go_dev_addr = wpa_s->global->p2p_dev_addr;
5473 : 4 : freq = ssid->frequency;
5474 : : } else {
5475 : 0 : role = P2P_INVITE_ROLE_CLIENT;
5476 [ # # ]: 0 : if (wpa_s->wpa_state < WPA_ASSOCIATED) {
5477 : 0 : wpa_printf(MSG_DEBUG, "P2P: Not associated - cannot "
5478 : : "invite to current group");
5479 : 0 : return -1;
5480 : : }
5481 : 0 : bssid = wpa_s->bssid;
5482 [ # # # # ]: 0 : if (go_dev_addr == NULL &&
5483 : 0 : !is_zero_ether_addr(wpa_s->go_dev_addr))
5484 : 0 : go_dev_addr = wpa_s->go_dev_addr;
5485 [ # # ]: 0 : freq = wpa_s->current_bss ? wpa_s->current_bss->freq :
5486 : 0 : (int) wpa_s->assoc_freq;
5487 : : }
5488 : 4 : wpa_s->parent->pending_invite_ssid_id = -1;
5489 : :
5490 [ + - ][ - + ]: 4 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
5491 : 0 : return -1;
5492 : :
5493 : 4 : res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
5494 : : role == P2P_INVITE_ROLE_ACTIVE_GO);
5495 [ - + ]: 4 : if (res)
5496 : 0 : return res;
5497 : 4 : wpas_p2p_set_own_freq_preference(wpa_s, force_freq);
5498 : :
5499 : 4 : return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
5500 : 4 : ssid->ssid, ssid->ssid_len, force_freq,
5501 : : go_dev_addr, persistent, pref_freq);
5502 : : }
5503 : :
5504 : :
5505 : 415 : void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
5506 : : {
5507 : 415 : struct wpa_ssid *ssid = wpa_s->current_ssid;
5508 : : const char *ssid_txt;
5509 : : u8 go_dev_addr[ETH_ALEN];
5510 : 415 : int network_id = -1;
5511 : : int persistent;
5512 : : int freq;
5513 : :
5514 [ + - ][ + + ]: 415 : if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) {
5515 : 380 : eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
5516 : 380 : wpa_s->parent, NULL);
5517 : : }
5518 : :
5519 [ + + ][ - + ]: 415 : if (!wpa_s->show_group_started || !ssid)
5520 : 415 : return;
5521 : :
5522 : 61 : wpa_s->show_group_started = 0;
5523 : :
5524 : 61 : ssid_txt = wpa_ssid_txt(ssid->ssid, ssid->ssid_len);
5525 : 61 : os_memset(go_dev_addr, 0, ETH_ALEN);
5526 [ + + ]: 61 : if (ssid->bssid_set)
5527 : 53 : os_memcpy(go_dev_addr, ssid->bssid, ETH_ALEN);
5528 : 61 : persistent = wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid,
5529 : : ssid->ssid_len);
5530 : 61 : os_memcpy(wpa_s->go_dev_addr, go_dev_addr, ETH_ALEN);
5531 : :
5532 [ - + ]: 61 : if (wpa_s->global->p2p_group_formation == wpa_s)
5533 : 0 : wpa_s->global->p2p_group_formation = NULL;
5534 : :
5535 [ + - ]: 61 : freq = wpa_s->current_bss ? wpa_s->current_bss->freq :
5536 : 0 : (int) wpa_s->assoc_freq;
5537 [ + - ][ + + ]: 121 : if (ssid->passphrase == NULL && ssid->psk_set) {
5538 : : char psk[65];
5539 : 60 : wpa_snprintf_hex(psk, sizeof(psk), ssid->psk, 32);
5540 [ + + ]: 60 : wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
5541 : : "%s client ssid=\"%s\" freq=%d psk=%s "
5542 : : "go_dev_addr=" MACSTR "%s",
5543 : 60 : wpa_s->ifname, ssid_txt, freq, psk,
5544 : 360 : MAC2STR(go_dev_addr),
5545 : : persistent ? " [PERSISTENT]" : "");
5546 : : } else {
5547 [ - + ][ - + ]: 1 : wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
5548 : : "%s client ssid=\"%s\" freq=%d "
5549 : : "passphrase=\"%s\" go_dev_addr=" MACSTR "%s",
5550 : 1 : wpa_s->ifname, ssid_txt, freq,
5551 : 1 : ssid->passphrase ? ssid->passphrase : "",
5552 : 6 : MAC2STR(go_dev_addr),
5553 : : persistent ? " [PERSISTENT]" : "");
5554 : : }
5555 : :
5556 [ + + ]: 61 : if (persistent)
5557 : 16 : network_id = wpas_p2p_store_persistent_group(wpa_s->parent,
5558 : : ssid, go_dev_addr);
5559 [ + + ]: 61 : if (network_id < 0)
5560 : 45 : network_id = ssid->id;
5561 : 61 : wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 1);
5562 : : }
5563 : :
5564 : :
5565 : 1 : int wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1,
5566 : : u32 interval1, u32 duration2, u32 interval2)
5567 : : {
5568 : : int ret;
5569 : :
5570 [ + - ][ - + ]: 1 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
5571 : 0 : return -1;
5572 : :
5573 [ + - ][ + - ]: 1 : if (wpa_s->wpa_state < WPA_ASSOCIATED ||
5574 [ - + ]: 1 : wpa_s->current_ssid == NULL ||
5575 : 1 : wpa_s->current_ssid->mode != WPAS_MODE_INFRA)
5576 : 0 : return -1;
5577 : :
5578 : 1 : ret = p2p_presence_req(wpa_s->global->p2p, wpa_s->bssid,
5579 : 1 : wpa_s->own_addr, wpa_s->assoc_freq,
5580 : : duration1, interval1, duration2, interval2);
5581 [ + - ]: 1 : if (ret == 0)
5582 : 1 : wpa_s->waiting_presence_resp = 1;
5583 : :
5584 : 1 : return ret;
5585 : : }
5586 : :
5587 : :
5588 : 0 : int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period,
5589 : : unsigned int interval)
5590 : : {
5591 [ # # ][ # # ]: 0 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
5592 : 0 : return -1;
5593 : :
5594 : 0 : return p2p_ext_listen(wpa_s->global->p2p, period, interval);
5595 : : }
5596 : :
5597 : :
5598 : 0 : static int wpas_p2p_is_client(struct wpa_supplicant *wpa_s)
5599 : : {
5600 [ # # ]: 0 : if (wpa_s->current_ssid == NULL) {
5601 : : /*
5602 : : * current_ssid can be cleared when P2P client interface gets
5603 : : * disconnected, so assume this interface was used as P2P
5604 : : * client.
5605 : : */
5606 : 0 : return 1;
5607 : : }
5608 [ # # ][ # # ]: 0 : return wpa_s->current_ssid->p2p_group &&
5609 : 0 : wpa_s->current_ssid->mode == WPAS_MODE_INFRA;
5610 : : }
5611 : :
5612 : :
5613 : 0 : static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx)
5614 : : {
5615 : 0 : struct wpa_supplicant *wpa_s = eloop_ctx;
5616 : :
5617 [ # # ][ # # ]: 0 : if (wpa_s->conf->p2p_group_idle == 0 && !wpas_p2p_is_client(wpa_s)) {
5618 : 0 : wpa_printf(MSG_DEBUG, "P2P: Ignore group idle timeout - "
5619 : : "disabled");
5620 : 0 : return;
5621 : : }
5622 : :
5623 : 0 : wpa_printf(MSG_DEBUG, "P2P: Group idle timeout reached - terminate "
5624 : : "group");
5625 : 0 : wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_IDLE_TIMEOUT);
5626 : : }
5627 : :
5628 : :
5629 : 662 : static void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s)
5630 : : {
5631 : : int timeout;
5632 : :
5633 [ - + ]: 662 : if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
5634 : 0 : wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");
5635 : :
5636 [ + + ][ + + ]: 662 : if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group)
5637 : 422 : return;
5638 : :
5639 : 240 : timeout = wpa_s->conf->p2p_group_idle;
5640 [ + + ][ - + ]: 240 : if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
5641 [ # # ]: 0 : (timeout == 0 || timeout > P2P_MAX_CLIENT_IDLE))
5642 : 119 : timeout = P2P_MAX_CLIENT_IDLE;
5643 : :
5644 [ + + ]: 240 : if (timeout == 0)
5645 : 121 : return;
5646 : :
5647 [ - + ]: 119 : if (timeout < 0) {
5648 [ # # ]: 0 : if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA)
5649 : 0 : timeout = 0; /* special client mode no-timeout */
5650 : : else
5651 : 0 : return;
5652 : : }
5653 : :
5654 [ - + ]: 119 : if (wpa_s->p2p_in_provisioning) {
5655 : : /*
5656 : : * Use the normal group formation timeout during the
5657 : : * provisioning phase to avoid terminating this process too
5658 : : * early due to group idle timeout.
5659 : : */
5660 : 0 : wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout "
5661 : : "during provisioning");
5662 : 0 : return;
5663 : : }
5664 : :
5665 [ + + ]: 119 : if (wpa_s->show_group_started) {
5666 : : /*
5667 : : * Use the normal group formation timeout between the end of
5668 : : * the provisioning phase and completion of 4-way handshake to
5669 : : * avoid terminating this process too early due to group idle
5670 : : * timeout.
5671 : : */
5672 : 58 : wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout "
5673 : : "while waiting for initial 4-way handshake to "
5674 : : "complete");
5675 : 58 : return;
5676 : : }
5677 : :
5678 : 61 : wpa_printf(MSG_DEBUG, "P2P: Set P2P group idle timeout to %u seconds",
5679 : : timeout);
5680 : 662 : eloop_register_timeout(timeout, 0, wpas_p2p_group_idle_timeout,
5681 : : wpa_s, NULL);
5682 : : }
5683 : :
5684 : :
5685 : : /* Returns 1 if the interface was removed */
5686 : 847 : int wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
5687 : : u16 reason_code, const u8 *ie, size_t ie_len,
5688 : : int locally_generated)
5689 : : {
5690 [ + + ][ - + ]: 847 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
5691 : 6 : return 0;
5692 : :
5693 [ + + ]: 841 : if (!locally_generated)
5694 : 65 : p2p_deauth_notif(wpa_s->global->p2p, bssid, reason_code, ie,
5695 : : ie_len);
5696 : :
5697 [ + + ][ + + ]: 841 : if (reason_code == WLAN_REASON_DEAUTH_LEAVING && !locally_generated &&
[ + - ]
5698 [ + + ]: 43 : wpa_s->current_ssid &&
5699 [ + - ]: 42 : wpa_s->current_ssid->p2p_group &&
5700 : 42 : wpa_s->current_ssid->mode == WPAS_MODE_INFRA) {
5701 : 42 : wpa_printf(MSG_DEBUG, "P2P: GO indicated that the P2P Group "
5702 : : "session is ending");
5703 [ + + ]: 42 : if (wpas_p2p_group_delete(wpa_s,
5704 : : P2P_GROUP_REMOVAL_GO_ENDING_SESSION)
5705 : : > 0)
5706 : 5 : return 1;
5707 : : }
5708 : :
5709 : 847 : return 0;
5710 : : }
5711 : :
5712 : :
5713 : 0 : void wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
5714 : : u16 reason_code, const u8 *ie, size_t ie_len,
5715 : : int locally_generated)
5716 : : {
5717 [ # # ][ # # ]: 0 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
5718 : 0 : return;
5719 : :
5720 [ # # ]: 0 : if (!locally_generated)
5721 : 0 : p2p_disassoc_notif(wpa_s->global->p2p, bssid, reason_code, ie,
5722 : : ie_len);
5723 : : }
5724 : :
5725 : :
5726 : 5208 : void wpas_p2p_update_config(struct wpa_supplicant *wpa_s)
5727 : : {
5728 : 5208 : struct p2p_data *p2p = wpa_s->global->p2p;
5729 : :
5730 [ - + ]: 5208 : if (p2p == NULL)
5731 : 0 : return;
5732 : :
5733 [ - + ]: 5208 : if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
5734 : 0 : return;
5735 : :
5736 [ + + ]: 5208 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_NAME)
5737 : 3 : p2p_set_dev_name(p2p, wpa_s->conf->device_name);
5738 : :
5739 [ - + ]: 5208 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
5740 : 0 : p2p_set_pri_dev_type(p2p, wpa_s->conf->device_type);
5741 : :
5742 [ + - ][ - + ]: 5208 : if (wpa_s->wps &&
5743 : 5208 : (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS))
5744 : 0 : p2p_set_config_methods(p2p, wpa_s->wps->config_methods);
5745 : :
5746 [ + - ][ - + ]: 5208 : if (wpa_s->wps && (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID))
5747 : 0 : p2p_set_uuid(p2p, wpa_s->wps->uuid);
5748 : :
5749 [ - + ]: 5208 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_WPS_STRING) {
5750 : 0 : p2p_set_manufacturer(p2p, wpa_s->conf->manufacturer);
5751 : 0 : p2p_set_model_name(p2p, wpa_s->conf->model_name);
5752 : 0 : p2p_set_model_number(p2p, wpa_s->conf->model_number);
5753 : 0 : p2p_set_serial_number(p2p, wpa_s->conf->serial_number);
5754 : : }
5755 : :
5756 [ - + ]: 5208 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE)
5757 : 0 : p2p_set_sec_dev_types(p2p,
5758 : 0 : (void *) wpa_s->conf->sec_device_type,
5759 : 0 : wpa_s->conf->num_sec_device_types);
5760 : :
5761 [ - + ]: 5208 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_VENDOR_EXTENSION) {
5762 : : int i;
5763 : 0 : p2p_remove_wps_vendor_extensions(p2p);
5764 [ # # ]: 0 : for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) {
5765 [ # # ]: 0 : if (wpa_s->conf->wps_vendor_ext[i] == NULL)
5766 : 0 : continue;
5767 : 0 : p2p_add_wps_vendor_extension(
5768 : 0 : p2p, wpa_s->conf->wps_vendor_ext[i]);
5769 : : }
5770 : : }
5771 : :
5772 [ - + ][ # # ]: 5208 : if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
5773 [ # # ]: 0 : wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
5774 : : char country[3];
5775 : 0 : country[0] = wpa_s->conf->country[0];
5776 : 0 : country[1] = wpa_s->conf->country[1];
5777 : 0 : country[2] = 0x04;
5778 : 0 : p2p_set_country(p2p, country);
5779 : : }
5780 : :
5781 [ - + ]: 5208 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_SSID_POSTFIX) {
5782 [ # # ]: 0 : p2p_set_ssid_postfix(p2p, (u8 *) wpa_s->conf->p2p_ssid_postfix,
5783 : 0 : wpa_s->conf->p2p_ssid_postfix ?
5784 : 0 : os_strlen(wpa_s->conf->p2p_ssid_postfix) :
5785 : : 0);
5786 : : }
5787 : :
5788 [ - + ]: 5208 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_INTRA_BSS)
5789 : 0 : p2p_set_intra_bss_dist(p2p, wpa_s->conf->p2p_intra_bss);
5790 : :
5791 [ - + ]: 5208 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_LISTEN_CHANNEL) {
5792 : : u8 reg_class, channel;
5793 : : int ret;
5794 : : unsigned int r;
5795 [ # # ][ # # ]: 0 : if (wpa_s->conf->p2p_listen_reg_class &&
5796 : 0 : wpa_s->conf->p2p_listen_channel) {
5797 : 0 : reg_class = wpa_s->conf->p2p_listen_reg_class;
5798 : 0 : channel = wpa_s->conf->p2p_listen_channel;
5799 : : } else {
5800 : 0 : reg_class = 81;
5801 : : /*
5802 : : * Pick one of the social channels randomly as the
5803 : : * listen channel.
5804 : : */
5805 : 0 : os_get_random((u8 *) &r, sizeof(r));
5806 : 0 : channel = 1 + (r % 3) * 5;
5807 : : }
5808 : 0 : ret = p2p_set_listen_channel(p2p, reg_class, channel);
5809 [ # # ]: 0 : if (ret)
5810 : 0 : wpa_printf(MSG_ERROR, "P2P: Own listen channel update "
5811 : : "failed: %d", ret);
5812 : : }
5813 [ - + ]: 5208 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_OPER_CHANNEL) {
5814 : : u8 op_reg_class, op_channel, cfg_op_channel;
5815 : 0 : int ret = 0;
5816 : : unsigned int r;
5817 [ # # ][ # # ]: 0 : if (wpa_s->conf->p2p_oper_reg_class &&
5818 : 0 : wpa_s->conf->p2p_oper_channel) {
5819 : 0 : op_reg_class = wpa_s->conf->p2p_oper_reg_class;
5820 : 0 : op_channel = wpa_s->conf->p2p_oper_channel;
5821 : 0 : cfg_op_channel = 1;
5822 : : } else {
5823 : 0 : op_reg_class = 81;
5824 : : /*
5825 : : * Use random operation channel from (1, 6, 11)
5826 : : *if no other preference is indicated.
5827 : : */
5828 : 0 : os_get_random((u8 *) &r, sizeof(r));
5829 : 0 : op_channel = 1 + (r % 3) * 5;
5830 : 0 : cfg_op_channel = 0;
5831 : : }
5832 : 0 : ret = p2p_set_oper_channel(p2p, op_reg_class, op_channel,
5833 : : cfg_op_channel);
5834 [ # # ]: 0 : if (ret)
5835 : 0 : wpa_printf(MSG_ERROR, "P2P: Own oper channel update "
5836 : : "failed: %d", ret);
5837 : : }
5838 : :
5839 [ + + ]: 5208 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_PREF_CHAN) {
5840 [ - + ]: 1456 : if (p2p_set_pref_chan(p2p, wpa_s->conf->num_p2p_pref_chan,
5841 : 1456 : wpa_s->conf->p2p_pref_chan) < 0) {
5842 : 0 : wpa_printf(MSG_ERROR, "P2P: Preferred channel list "
5843 : : "update failed");
5844 : : }
5845 : :
5846 [ - + ]: 1456 : if (p2p_set_no_go_freq(p2p, &wpa_s->conf->p2p_no_go_freq) < 0) {
5847 : 5208 : wpa_printf(MSG_ERROR, "P2P: No GO channel list "
5848 : : "update failed");
5849 : : }
5850 : : }
5851 : : }
5852 : :
5853 : :
5854 : 0 : int wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start,
5855 : : int duration)
5856 : : {
5857 [ # # ]: 0 : if (!wpa_s->ap_iface)
5858 : 0 : return -1;
5859 : 0 : return hostapd_p2p_set_noa(wpa_s->ap_iface->bss[0], count, start,
5860 : : duration);
5861 : : }
5862 : :
5863 : :
5864 : 0 : int wpas_p2p_set_cross_connect(struct wpa_supplicant *wpa_s, int enabled)
5865 : : {
5866 [ # # ][ # # ]: 0 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
5867 : 0 : return -1;
5868 : :
5869 : 0 : wpa_s->global->cross_connection = enabled;
5870 : 0 : p2p_set_cross_connect(wpa_s->global->p2p, enabled);
5871 : :
5872 [ # # ]: 0 : if (!enabled) {
5873 : : struct wpa_supplicant *iface;
5874 : :
5875 [ # # ]: 0 : for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
5876 : : {
5877 [ # # ]: 0 : if (iface->cross_connect_enabled == 0)
5878 : 0 : continue;
5879 : :
5880 : 0 : iface->cross_connect_enabled = 0;
5881 : 0 : iface->cross_connect_in_use = 0;
5882 : 0 : wpa_msg_global(iface->parent, MSG_INFO,
5883 : : P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
5884 : 0 : iface->ifname,
5885 : 0 : iface->cross_connect_uplink);
5886 : : }
5887 : : }
5888 : :
5889 : 0 : return 0;
5890 : : }
5891 : :
5892 : :
5893 : 371 : static void wpas_p2p_enable_cross_connect(struct wpa_supplicant *uplink)
5894 : : {
5895 : : struct wpa_supplicant *iface;
5896 : :
5897 [ + - ]: 371 : if (!uplink->global->cross_connection)
5898 : 371 : return;
5899 : :
5900 [ # # ]: 0 : for (iface = uplink->global->ifaces; iface; iface = iface->next) {
5901 [ # # ]: 0 : if (!iface->cross_connect_enabled)
5902 : 0 : continue;
5903 [ # # ]: 0 : if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) !=
5904 : : 0)
5905 : 0 : continue;
5906 [ # # ]: 0 : if (iface->ap_iface == NULL)
5907 : 0 : continue;
5908 [ # # ]: 0 : if (iface->cross_connect_in_use)
5909 : 0 : continue;
5910 : :
5911 : 0 : iface->cross_connect_in_use = 1;
5912 : 0 : wpa_msg_global(iface->parent, MSG_INFO,
5913 : : P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s",
5914 : 0 : iface->ifname, iface->cross_connect_uplink);
5915 : : }
5916 : : }
5917 : :
5918 : :
5919 : 644 : static void wpas_p2p_disable_cross_connect(struct wpa_supplicant *uplink)
5920 : : {
5921 : : struct wpa_supplicant *iface;
5922 : :
5923 [ + + ]: 1318 : for (iface = uplink->global->ifaces; iface; iface = iface->next) {
5924 [ + - ]: 674 : if (!iface->cross_connect_enabled)
5925 : 674 : continue;
5926 [ # # ]: 0 : if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) !=
5927 : : 0)
5928 : 0 : continue;
5929 [ # # ]: 0 : if (!iface->cross_connect_in_use)
5930 : 0 : continue;
5931 : :
5932 : 0 : wpa_msg_global(iface->parent, MSG_INFO,
5933 : : P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
5934 : 0 : iface->ifname, iface->cross_connect_uplink);
5935 : 0 : iface->cross_connect_in_use = 0;
5936 : : }
5937 : 644 : }
5938 : :
5939 : :
5940 : 440 : void wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s)
5941 : : {
5942 [ + + ][ + - ]: 440 : if (wpa_s->ap_iface || wpa_s->current_ssid == NULL ||
[ + + ]
5943 [ - + ]: 371 : wpa_s->current_ssid->mode != WPAS_MODE_INFRA ||
5944 : 371 : wpa_s->cross_connect_disallowed)
5945 : 69 : wpas_p2p_disable_cross_connect(wpa_s);
5946 : : else
5947 : 371 : wpas_p2p_enable_cross_connect(wpa_s);
5948 [ + + + + ]: 820 : if (!wpa_s->ap_iface &&
5949 : 380 : eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
5950 : 1 : wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");
5951 : 440 : }
5952 : :
5953 : :
5954 : 575 : void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s)
5955 : : {
5956 : 575 : wpas_p2p_disable_cross_connect(wpa_s);
5957 [ + + + - ]: 1054 : if (!wpa_s->ap_iface &&
5958 : 479 : !eloop_is_timeout_registered(wpas_p2p_group_idle_timeout,
5959 : : wpa_s, NULL))
5960 : 479 : wpas_p2p_set_group_idle_timeout(wpa_s);
5961 : 575 : }
5962 : :
5963 : :
5964 : 58 : static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s)
5965 : : {
5966 : : struct wpa_supplicant *iface;
5967 : :
5968 [ + - ]: 58 : if (!wpa_s->global->cross_connection)
5969 : 58 : return;
5970 : :
5971 [ # # ]: 0 : for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
5972 [ # # ]: 0 : if (iface == wpa_s)
5973 : 0 : continue;
5974 [ # # ]: 0 : if (iface->drv_flags &
5975 : : WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)
5976 : 0 : continue;
5977 [ # # ]: 0 : if (iface->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE)
5978 : 0 : continue;
5979 : :
5980 : 0 : wpa_s->cross_connect_enabled = 1;
5981 : 0 : os_strlcpy(wpa_s->cross_connect_uplink, iface->ifname,
5982 : : sizeof(wpa_s->cross_connect_uplink));
5983 : 0 : wpa_printf(MSG_DEBUG, "P2P: Enable cross connection from "
5984 : : "%s to %s whenever uplink is available",
5985 : 0 : wpa_s->ifname, wpa_s->cross_connect_uplink);
5986 : :
5987 [ # # ][ # # ]: 0 : if (iface->ap_iface || iface->current_ssid == NULL ||
[ # # ]
5988 [ # # ]: 0 : iface->current_ssid->mode != WPAS_MODE_INFRA ||
5989 [ # # ]: 0 : iface->cross_connect_disallowed ||
5990 : 0 : iface->wpa_state != WPA_COMPLETED)
5991 : : break;
5992 : :
5993 : 0 : wpa_s->cross_connect_in_use = 1;
5994 : 0 : wpa_msg_global(wpa_s->parent, MSG_INFO,
5995 : : P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s",
5996 : 0 : wpa_s->ifname, wpa_s->cross_connect_uplink);
5997 : 0 : break;
5998 : : }
5999 : : }
6000 : :
6001 : :
6002 : 3 : int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s)
6003 : : {
6004 [ + - ][ + - ]: 3 : if (wpa_s->p2p_group_interface != P2P_GROUP_INTERFACE_CLIENT &&
6005 : 3 : !wpa_s->p2p_in_provisioning)
6006 : 3 : return 0; /* not P2P client operation */
6007 : :
6008 : 0 : wpa_printf(MSG_DEBUG, "P2P: Terminate connection due to WPS PBC "
6009 : : "session overlap");
6010 [ # # ]: 0 : if (wpa_s != wpa_s->parent)
6011 : 0 : wpa_msg_ctrl(wpa_s->parent, MSG_INFO, WPS_EVENT_OVERLAP);
6012 : 0 : wpas_p2p_group_formation_failed(wpa_s);
6013 : 3 : return 1;
6014 : : }
6015 : :
6016 : :
6017 : 1130 : void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s)
6018 : : {
6019 : : struct p2p_channels chan, cli_chan;
6020 : :
6021 [ + - ][ - + ]: 1130 : if (wpa_s->global == NULL || wpa_s->global->p2p == NULL)
6022 : 0 : return;
6023 : :
6024 : 1130 : os_memset(&chan, 0, sizeof(chan));
6025 : 1130 : os_memset(&cli_chan, 0, sizeof(cli_chan));
6026 [ - + ]: 1130 : if (wpas_p2p_setup_channels(wpa_s, &chan, &cli_chan)) {
6027 : 0 : wpa_printf(MSG_ERROR, "P2P: Failed to update supported "
6028 : : "channel list");
6029 : 0 : return;
6030 : : }
6031 : :
6032 : 1130 : p2p_update_channel_list(wpa_s->global->p2p, &chan, &cli_chan);
6033 : : }
6034 : :
6035 : :
6036 : 0 : static void wpas_p2p_scan_res_ignore(struct wpa_supplicant *wpa_s,
6037 : : struct wpa_scan_results *scan_res)
6038 : : {
6039 : 0 : wpa_printf(MSG_DEBUG, "P2P: Ignore scan results");
6040 : 0 : }
6041 : :
6042 : :
6043 : 0 : int wpas_p2p_cancel(struct wpa_supplicant *wpa_s)
6044 : : {
6045 : 0 : struct wpa_global *global = wpa_s->global;
6046 : 0 : int found = 0;
6047 : : const u8 *peer;
6048 : :
6049 [ # # ]: 0 : if (global->p2p == NULL)
6050 : 0 : return -1;
6051 : :
6052 : 0 : wpa_printf(MSG_DEBUG, "P2P: Request to cancel group formation");
6053 : :
6054 [ # # # # ]: 0 : if (wpa_s->pending_interface_name[0] &&
6055 : 0 : !is_zero_ether_addr(wpa_s->pending_interface_addr))
6056 : 0 : found = 1;
6057 : :
6058 : 0 : peer = p2p_get_go_neg_peer(global->p2p);
6059 [ # # ]: 0 : if (peer) {
6060 : 0 : wpa_printf(MSG_DEBUG, "P2P: Unauthorize pending GO Neg peer "
6061 : 0 : MACSTR, MAC2STR(peer));
6062 : 0 : p2p_unauthorize(global->p2p, peer);
6063 : 0 : found = 1;
6064 : : }
6065 : :
6066 [ # # ]: 0 : if (wpa_s->scan_res_handler == wpas_p2p_scan_res_join) {
6067 : 0 : wpa_printf(MSG_DEBUG, "P2P: Stop pending scan for join");
6068 : 0 : wpa_s->scan_res_handler = wpas_p2p_scan_res_ignore;
6069 : 0 : found = 1;
6070 : : }
6071 : :
6072 [ # # ]: 0 : if (wpa_s->pending_pd_before_join) {
6073 : 0 : wpa_printf(MSG_DEBUG, "P2P: Stop pending PD before join");
6074 : 0 : wpa_s->pending_pd_before_join = 0;
6075 : 0 : found = 1;
6076 : : }
6077 : :
6078 : 0 : wpas_p2p_stop_find(wpa_s);
6079 : :
6080 [ # # ]: 0 : for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
6081 [ # # ][ # # ]: 0 : if (wpa_s == global->p2p_group_formation &&
6082 [ # # ]: 0 : (wpa_s->p2p_in_provisioning ||
6083 : 0 : wpa_s->parent->pending_interface_type ==
6084 : : WPA_IF_P2P_CLIENT)) {
6085 : 0 : wpa_printf(MSG_DEBUG, "P2P: Interface %s in group "
6086 : : "formation found - cancelling",
6087 : 0 : wpa_s->ifname);
6088 : 0 : found = 1;
6089 : 0 : eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
6090 : 0 : wpa_s->parent, NULL);
6091 [ # # ]: 0 : if (wpa_s->p2p_in_provisioning) {
6092 : 0 : wpas_group_formation_completed(wpa_s, 0);
6093 : 0 : break;
6094 : : }
6095 : 0 : wpas_p2p_group_delete(wpa_s,
6096 : : P2P_GROUP_REMOVAL_REQUESTED);
6097 : 0 : break;
6098 : : }
6099 : : }
6100 : :
6101 [ # # ]: 0 : if (!found) {
6102 : 0 : wpa_printf(MSG_DEBUG, "P2P: No ongoing group formation found");
6103 : 0 : return -1;
6104 : : }
6105 : :
6106 : 0 : return 0;
6107 : : }
6108 : :
6109 : :
6110 : 0 : void wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s)
6111 : : {
6112 [ # # ][ # # ]: 0 : if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group)
6113 : 0 : return;
6114 : :
6115 : 0 : wpa_printf(MSG_DEBUG, "P2P: Remove group due to driver resource not "
6116 : : "being available anymore");
6117 : 0 : wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_UNAVAILABLE);
6118 : : }
6119 : :
6120 : :
6121 : 0 : void wpas_p2p_update_best_channels(struct wpa_supplicant *wpa_s,
6122 : : int freq_24, int freq_5, int freq_overall)
6123 : : {
6124 : 0 : struct p2p_data *p2p = wpa_s->global->p2p;
6125 [ # # ]: 0 : if (p2p == NULL)
6126 : 0 : return;
6127 : 0 : p2p_set_best_channels(p2p, freq_24, freq_5, freq_overall);
6128 : : }
6129 : :
6130 : :
6131 : 0 : int wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr)
6132 : : {
6133 : : u8 peer[ETH_ALEN];
6134 : 0 : struct p2p_data *p2p = wpa_s->global->p2p;
6135 : :
6136 [ # # ]: 0 : if (p2p == NULL)
6137 : 0 : return -1;
6138 : :
6139 [ # # ]: 0 : if (hwaddr_aton(addr, peer))
6140 : 0 : return -1;
6141 : :
6142 : 0 : return p2p_unauthorize(p2p, peer);
6143 : : }
6144 : :
6145 : :
6146 : : /**
6147 : : * wpas_p2p_disconnect - Disconnect from a P2P Group
6148 : : * @wpa_s: Pointer to wpa_supplicant data
6149 : : * Returns: 0 on success, -1 on failure
6150 : : *
6151 : : * This can be used to disconnect from a group in which the local end is a P2P
6152 : : * Client or to end a P2P Group in case the local end is the Group Owner. If a
6153 : : * virtual network interface was created for this group, that interface will be
6154 : : * removed. Otherwise, only the configured P2P group network will be removed
6155 : : * from the interface.
6156 : : */
6157 : 89 : int wpas_p2p_disconnect(struct wpa_supplicant *wpa_s)
6158 : : {
6159 : :
6160 [ + + ]: 89 : if (wpa_s == NULL)
6161 : 2 : return -1;
6162 : :
6163 : 176 : return wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_REQUESTED) < 0 ?
6164 [ + + ]: 87 : -1 : 0;
6165 : : }
6166 : :
6167 : :
6168 : 510 : int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s)
6169 : : {
6170 : : int ret;
6171 : :
6172 [ + + ][ - + ]: 510 : if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
6173 : 2 : return 0;
6174 : :
6175 : 508 : ret = p2p_in_progress(wpa_s->global->p2p);
6176 [ + - ]: 508 : if (ret == 0) {
6177 : : /*
6178 : : * Check whether there is an ongoing WPS provisioning step (or
6179 : : * other parts of group formation) on another interface since
6180 : : * p2p_in_progress() does not report this to avoid issues for
6181 : : * scans during such provisioning step.
6182 : : */
6183 [ + + ][ - + ]: 508 : if (wpa_s->global->p2p_group_formation &&
6184 : 102 : wpa_s->global->p2p_group_formation != wpa_s) {
6185 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Another interface (%s) "
6186 : : "in group formation",
6187 : : wpa_s->global->p2p_group_formation->ifname);
6188 : 0 : ret = 1;
6189 : : }
6190 : : }
6191 : :
6192 [ + - ][ - + ]: 508 : if (!ret && wpa_s->global->p2p_go_wait_client.sec) {
6193 : : struct os_reltime now;
6194 : 0 : os_get_reltime(&now);
6195 [ # # ]: 0 : if (os_reltime_expired(&now, &wpa_s->global->p2p_go_wait_client,
6196 : : P2P_MAX_INITIAL_CONN_WAIT_GO)) {
6197 : : /* Wait for the first client has expired */
6198 : 0 : wpa_s->global->p2p_go_wait_client.sec = 0;
6199 : : } else {
6200 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Waiting for initial client connection during group formation");
6201 : 0 : ret = 1;
6202 : : }
6203 : : }
6204 : :
6205 : 510 : return ret;
6206 : : }
6207 : :
6208 : :
6209 : 358 : void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
6210 : : struct wpa_ssid *ssid)
6211 : : {
6212 [ - + ]: 358 : if (wpa_s->p2p_in_provisioning && ssid->p2p_group &&
[ # # # # ]
6213 : 0 : eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
6214 : 0 : wpa_s->parent, NULL) > 0) {
6215 : : /**
6216 : : * Remove the network by scheduling the group formation
6217 : : * timeout to happen immediately. The teardown code
6218 : : * needs to be scheduled to run asynch later so that we
6219 : : * don't delete data from under ourselves unexpectedly.
6220 : : * Calling wpas_p2p_group_formation_timeout directly
6221 : : * causes a series of crashes in WPS failure scenarios.
6222 : : */
6223 : 0 : wpa_printf(MSG_DEBUG, "P2P: Canceled group formation due to "
6224 : : "P2P group network getting removed");
6225 : 0 : eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
6226 : 0 : wpa_s->parent, NULL);
6227 : : }
6228 : 358 : }
6229 : :
6230 : :
6231 : 196 : struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
6232 : : const u8 *addr, const u8 *ssid,
6233 : : size_t ssid_len)
6234 : : {
6235 : : struct wpa_ssid *s;
6236 : : size_t i;
6237 : :
6238 [ + + ]: 219 : for (s = wpa_s->conf->ssid; s; s = s->next) {
6239 [ + + ]: 53 : if (s->disabled != 2)
6240 : 19 : continue;
6241 [ + + ][ + - ]: 34 : if (ssid &&
6242 [ - + ]: 14 : (ssid_len != s->ssid_len ||
6243 : 14 : os_memcmp(ssid, s->ssid, ssid_len) != 0))
6244 : 0 : continue;
6245 [ + + ]: 34 : if (addr == NULL) {
6246 [ + - ]: 10 : if (s->mode == WPAS_MODE_P2P_GO)
6247 : 10 : return s;
6248 : 0 : continue;
6249 : : }
6250 [ + + ]: 24 : if (os_memcmp(s->bssid, addr, ETH_ALEN) == 0)
6251 : 14 : return s; /* peer is GO in the persistent group */
6252 [ + - ][ - + ]: 10 : if (s->mode != WPAS_MODE_P2P_GO || s->p2p_client_list == NULL)
6253 : 0 : continue;
6254 [ + + ]: 10 : for (i = 0; i < s->num_p2p_clients; i++) {
6255 [ + - ]: 6 : if (os_memcmp(s->p2p_client_list + i * ETH_ALEN,
6256 : : addr, ETH_ALEN) == 0)
6257 : 6 : return s; /* peer is P2P client in persistent
6258 : : * group */
6259 : : }
6260 : : }
6261 : :
6262 : 196 : return NULL;
6263 : : }
6264 : :
6265 : :
6266 : 66 : void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
6267 : : const u8 *addr)
6268 : : {
6269 [ + + ]: 66 : if (eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
6270 : 66 : wpa_s->parent, NULL) > 0) {
6271 : : /*
6272 : : * This can happen if WPS provisioning step is not terminated
6273 : : * cleanly (e.g., P2P Client does not send WSC_Done). Since the
6274 : : * peer was able to connect, there is no need to time out group
6275 : : * formation after this, though. In addition, this is used with
6276 : : * the initial connection wait on the GO as a separate formation
6277 : : * timeout and as such, expected to be hit after the initial WPS
6278 : : * provisioning step.
6279 : : */
6280 : 41 : wpa_printf(MSG_DEBUG, "P2P: Canceled P2P group formation timeout on data connection");
6281 : : }
6282 [ + + ]: 66 : if (!wpa_s->p2p_go_group_formation_completed) {
6283 : 47 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Marking group formation completed on GO on first data connection");
6284 : 47 : wpa_s->p2p_go_group_formation_completed = 1;
6285 : 47 : wpa_s->global->p2p_group_formation = NULL;
6286 : 47 : wpa_s->p2p_in_provisioning = 0;
6287 : : }
6288 : 66 : wpa_s->global->p2p_go_wait_client.sec = 0;
6289 [ + + ]: 66 : if (addr == NULL)
6290 : 66 : return;
6291 : 61 : wpas_p2p_add_persistent_group_client(wpa_s, addr);
6292 : : }
6293 : :
6294 : :
6295 : 0 : static void wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s,
6296 : : int group_added)
6297 : : {
6298 : 0 : struct wpa_supplicant *group = wpa_s;
6299 [ # # ]: 0 : if (wpa_s->global->p2p_group_formation)
6300 : 0 : group = wpa_s->global->p2p_group_formation;
6301 : 0 : wpa_s = wpa_s->parent;
6302 : 0 : offchannel_send_action_done(wpa_s);
6303 [ # # ]: 0 : if (group_added)
6304 : 0 : wpas_p2p_group_delete(group, P2P_GROUP_REMOVAL_SILENT);
6305 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Fall back to GO Negotiation");
6306 : 0 : wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr, wpa_s->p2p_pin,
6307 : 0 : wpa_s->p2p_wps_method, wpa_s->p2p_persistent_group, 0,
6308 : : 0, 0, wpa_s->p2p_go_intent, wpa_s->p2p_connect_freq,
6309 : : wpa_s->p2p_persistent_id,
6310 : 0 : wpa_s->p2p_pd_before_go_neg,
6311 : 0 : wpa_s->p2p_go_ht40,
6312 : 0 : wpa_s->p2p_go_vht);
6313 : 0 : }
6314 : :
6315 : :
6316 : 96 : int wpas_p2p_scan_no_go_seen(struct wpa_supplicant *wpa_s)
6317 : : {
6318 [ - + ][ # # ]: 96 : if (!wpa_s->p2p_fallback_to_go_neg ||
6319 : 0 : wpa_s->p2p_in_provisioning <= 5)
6320 : 96 : return 0;
6321 : :
6322 [ # # ]: 0 : if (wpas_p2p_peer_go(wpa_s, wpa_s->pending_join_dev_addr) > 0)
6323 : 0 : return 0; /* peer operating as a GO */
6324 : :
6325 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: GO not found for p2p_connect-auto - "
6326 : : "fallback to GO Negotiation");
6327 : 0 : wpas_p2p_fallback_to_go_neg(wpa_s, 1);
6328 : :
6329 : 96 : return 1;
6330 : : }
6331 : :
6332 : :
6333 : 110 : unsigned int wpas_p2p_search_delay(struct wpa_supplicant *wpa_s)
6334 : : {
6335 : : struct wpa_supplicant *ifs;
6336 : :
6337 [ + + ]: 110 : if (wpa_s->wpa_state > WPA_SCANNING) {
6338 : 4 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search delay due to "
6339 : : "concurrent operation",
6340 : : P2P_CONCURRENT_SEARCH_DELAY);
6341 : 4 : return P2P_CONCURRENT_SEARCH_DELAY;
6342 : : }
6343 : :
6344 [ + + ]: 212 : dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
6345 : : radio_list) {
6346 [ - + ][ # # ]: 106 : if (ifs != wpa_s && ifs->wpa_state > WPA_SCANNING) {
6347 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search "
6348 : : "delay due to concurrent operation on "
6349 : : "interface %s",
6350 : : P2P_CONCURRENT_SEARCH_DELAY, ifs->ifname);
6351 : 0 : return P2P_CONCURRENT_SEARCH_DELAY;
6352 : : }
6353 : : }
6354 : :
6355 : 110 : return 0;
6356 : : }
6357 : :
6358 : :
6359 : 5 : static int wpas_p2p_remove_psk_entry(struct wpa_supplicant *wpa_s,
6360 : : struct wpa_ssid *s, const u8 *addr,
6361 : : int iface_addr)
6362 : : {
6363 : : struct psk_list_entry *psk, *tmp;
6364 : 5 : int changed = 0;
6365 : :
6366 [ + + ]: 10 : dl_list_for_each_safe(psk, tmp, &s->psk_list, struct psk_list_entry,
6367 : : list) {
6368 [ - + ][ # # ]: 5 : if ((iface_addr && !psk->p2p &&
[ # # ]
6369 [ + - ]: 5 : os_memcmp(addr, psk->addr, ETH_ALEN) == 0) ||
6370 [ + - ][ + + ]: 5 : (!iface_addr && psk->p2p &&
6371 : 5 : os_memcmp(addr, psk->addr, ETH_ALEN) == 0)) {
6372 : 3 : wpa_dbg(wpa_s, MSG_DEBUG,
6373 : : "P2P: Remove persistent group PSK list entry for "
6374 : : MACSTR " p2p=%u",
6375 : : MAC2STR(psk->addr), psk->p2p);
6376 : 3 : dl_list_del(&psk->list);
6377 : 3 : os_free(psk);
6378 : 3 : changed++;
6379 : : }
6380 : : }
6381 : :
6382 : 5 : return changed;
6383 : : }
6384 : :
6385 : :
6386 : 8 : void wpas_p2p_new_psk_cb(struct wpa_supplicant *wpa_s, const u8 *mac_addr,
6387 : : const u8 *p2p_dev_addr,
6388 : : const u8 *psk, size_t psk_len)
6389 : : {
6390 : 8 : struct wpa_ssid *ssid = wpa_s->current_ssid;
6391 : : struct wpa_ssid *persistent;
6392 : : struct psk_list_entry *p;
6393 : :
6394 [ - + ]: 8 : if (psk_len != sizeof(p->psk))
6395 : 0 : return;
6396 : :
6397 [ + - ]: 8 : if (p2p_dev_addr) {
6398 : 8 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New PSK for addr=" MACSTR
6399 : : " p2p_dev_addr=" MACSTR,
6400 : : MAC2STR(mac_addr), MAC2STR(p2p_dev_addr));
6401 [ + + ]: 8 : if (is_zero_ether_addr(p2p_dev_addr))
6402 : 1 : p2p_dev_addr = NULL;
6403 : : } else {
6404 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New PSK for addr=" MACSTR,
6405 : : MAC2STR(mac_addr));
6406 : : }
6407 : :
6408 [ + + ]: 8 : if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
6409 : 4 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: new_psk_cb during group formation");
6410 : : /* To be added to persistent group once created */
6411 [ + - ]: 4 : if (wpa_s->global->add_psk == NULL) {
6412 : 4 : wpa_s->global->add_psk = os_zalloc(sizeof(*p));
6413 [ - + ]: 4 : if (wpa_s->global->add_psk == NULL)
6414 : 0 : return;
6415 : : }
6416 : 4 : p = wpa_s->global->add_psk;
6417 [ + - ]: 4 : if (p2p_dev_addr) {
6418 : 4 : p->p2p = 1;
6419 : 4 : os_memcpy(p->addr, p2p_dev_addr, ETH_ALEN);
6420 : : } else {
6421 : 0 : p->p2p = 0;
6422 : 0 : os_memcpy(p->addr, mac_addr, ETH_ALEN);
6423 : : }
6424 : 4 : os_memcpy(p->psk, psk, psk_len);
6425 : 4 : return;
6426 : : }
6427 : :
6428 [ + - ][ + + ]: 4 : if (ssid->mode != WPAS_MODE_P2P_GO || !ssid->p2p_persistent_group) {
6429 : 2 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Ignore new_psk_cb on not-persistent GO");
6430 : 2 : return;
6431 : : }
6432 : :
6433 : 2 : persistent = wpas_p2p_get_persistent(wpa_s->parent, NULL, ssid->ssid,
6434 : : ssid->ssid_len);
6435 [ - + ]: 2 : if (!persistent) {
6436 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not find persistent group information to store the new PSK");
6437 : 0 : return;
6438 : : }
6439 : :
6440 : 2 : p = os_zalloc(sizeof(*p));
6441 [ - + ]: 2 : if (p == NULL)
6442 : 0 : return;
6443 [ + - ]: 2 : if (p2p_dev_addr) {
6444 : 2 : p->p2p = 1;
6445 : 2 : os_memcpy(p->addr, p2p_dev_addr, ETH_ALEN);
6446 : : } else {
6447 : 0 : p->p2p = 0;
6448 : 0 : os_memcpy(p->addr, mac_addr, ETH_ALEN);
6449 : : }
6450 : 2 : os_memcpy(p->psk, psk, psk_len);
6451 : :
6452 [ - + ]: 2 : if (dl_list_len(&persistent->psk_list) > P2P_MAX_STORED_CLIENTS) {
6453 : : struct psk_list_entry *last;
6454 [ # # ]: 0 : last = dl_list_last(&persistent->psk_list,
6455 : : struct psk_list_entry, list);
6456 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove oldest PSK entry for "
6457 : : MACSTR " (p2p=%u) to make room for a new one",
6458 : : MAC2STR(last->addr), last->p2p);
6459 : 0 : dl_list_del(&last->list);
6460 : 0 : os_free(last);
6461 : : }
6462 : :
6463 [ + - ]: 2 : wpas_p2p_remove_psk_entry(wpa_s->parent, persistent,
6464 : : p2p_dev_addr ? p2p_dev_addr : mac_addr,
6465 : : p2p_dev_addr == NULL);
6466 [ + - ]: 2 : if (p2p_dev_addr) {
6467 : 2 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add new PSK for p2p_dev_addr="
6468 : : MACSTR, MAC2STR(p2p_dev_addr));
6469 : : } else {
6470 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add new PSK for addr=" MACSTR,
6471 : : MAC2STR(mac_addr));
6472 : : }
6473 : 2 : dl_list_add(&persistent->psk_list, &p->list);
6474 : :
6475 : : #ifndef CONFIG_NO_CONFIG_WRITE
6476 [ - + # # ]: 2 : if (wpa_s->parent->conf->update_config &&
6477 : 0 : wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
6478 : 8 : wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
6479 : : #endif /* CONFIG_NO_CONFIG_WRITE */
6480 : : }
6481 : :
6482 : :
6483 : 3 : static void wpas_p2p_remove_psk(struct wpa_supplicant *wpa_s,
6484 : : struct wpa_ssid *s, const u8 *addr,
6485 : : int iface_addr)
6486 : : {
6487 : : int res;
6488 : :
6489 : 3 : res = wpas_p2p_remove_psk_entry(wpa_s, s, addr, iface_addr);
6490 [ + - ]: 3 : if (res > 0) {
6491 : : #ifndef CONFIG_NO_CONFIG_WRITE
6492 [ - + # # ]: 3 : if (wpa_s->conf->update_config &&
6493 : 0 : wpa_config_write(wpa_s->confname, wpa_s->conf))
6494 : 0 : wpa_dbg(wpa_s, MSG_DEBUG,
6495 : : "P2P: Failed to update configuration");
6496 : : #endif /* CONFIG_NO_CONFIG_WRITE */
6497 : : }
6498 : 3 : }
6499 : :
6500 : :
6501 : 4 : static void wpas_p2p_remove_client_go(struct wpa_supplicant *wpa_s,
6502 : : const u8 *peer, int iface_addr)
6503 : : {
6504 : : struct hostapd_data *hapd;
6505 : : struct hostapd_wpa_psk *psk, *prev, *rem;
6506 : : struct sta_info *sta;
6507 : :
6508 [ + - ][ + - ]: 4 : if (wpa_s->ap_iface == NULL || wpa_s->current_ssid == NULL ||
[ - + ]
6509 : 4 : wpa_s->current_ssid->mode != WPAS_MODE_P2P_GO)
6510 : 4 : return;
6511 : :
6512 : : /* Remove per-station PSK entry */
6513 : 4 : hapd = wpa_s->ap_iface->bss[0];
6514 : 4 : prev = NULL;
6515 : 4 : psk = hapd->conf->ssid.wpa_psk;
6516 [ + + ]: 12 : while (psk) {
6517 [ - + ][ # # ]: 8 : if ((iface_addr && os_memcmp(peer, psk->addr, ETH_ALEN) == 0) ||
[ + - ]
6518 [ + + ]: 8 : (!iface_addr &&
6519 : 8 : os_memcmp(peer, psk->p2p_dev_addr, ETH_ALEN) == 0)) {
6520 : 3 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove operating group PSK entry for "
6521 : : MACSTR " iface_addr=%d",
6522 : : MAC2STR(peer), iface_addr);
6523 [ - + ]: 3 : if (prev)
6524 : 0 : prev->next = psk->next;
6525 : : else
6526 : 3 : hapd->conf->ssid.wpa_psk = psk->next;
6527 : 3 : rem = psk;
6528 : 3 : psk = psk->next;
6529 : 3 : os_free(rem);
6530 : : } else {
6531 : 5 : prev = psk;
6532 : 5 : psk = psk->next;
6533 : : }
6534 : : }
6535 : :
6536 : : /* Disconnect from group */
6537 [ - + ]: 4 : if (iface_addr)
6538 : 0 : sta = ap_get_sta(hapd, peer);
6539 : : else
6540 : 4 : sta = ap_get_sta_p2p(hapd, peer);
6541 [ + - ]: 4 : if (sta) {
6542 : 4 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disconnect peer " MACSTR
6543 : : " (iface_addr=%d) from group",
6544 : : MAC2STR(peer), iface_addr);
6545 : 4 : hostapd_drv_sta_deauth(hapd, sta->addr,
6546 : : WLAN_REASON_DEAUTH_LEAVING);
6547 : 4 : ap_sta_deauthenticate(hapd, sta, WLAN_REASON_DEAUTH_LEAVING);
6548 : : }
6549 : : }
6550 : :
6551 : :
6552 : 4 : void wpas_p2p_remove_client(struct wpa_supplicant *wpa_s, const u8 *peer,
6553 : : int iface_addr)
6554 : : {
6555 : : struct wpa_ssid *s;
6556 : : struct wpa_supplicant *w;
6557 : :
6558 : 4 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove client " MACSTR, MAC2STR(peer));
6559 : :
6560 : : /* Remove from any persistent group */
6561 [ + + ]: 11 : for (s = wpa_s->parent->conf->ssid; s; s = s->next) {
6562 [ + + ][ - + ]: 7 : if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO)
6563 : 4 : continue;
6564 [ + - ]: 3 : if (!iface_addr)
6565 : 3 : wpas_remove_persistent_peer(wpa_s, s, peer, 0);
6566 : 3 : wpas_p2p_remove_psk(wpa_s->parent, s, peer, iface_addr);
6567 : : }
6568 : :
6569 : : /* Remove from any operating group */
6570 [ + + ]: 8 : for (w = wpa_s->global->ifaces; w; w = w->next)
6571 : 4 : wpas_p2p_remove_client_go(w, peer, iface_addr);
6572 : 4 : }
6573 : :
6574 : :
6575 : 2 : static void wpas_p2p_psk_failure_removal(void *eloop_ctx, void *timeout_ctx)
6576 : : {
6577 : 2 : struct wpa_supplicant *wpa_s = eloop_ctx;
6578 : 2 : wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_PSK_FAILURE);
6579 : 2 : }
6580 : :
6581 : :
6582 : 0 : static void wpas_p2p_group_freq_conflict(void *eloop_ctx, void *timeout_ctx)
6583 : : {
6584 : 0 : struct wpa_supplicant *wpa_s = eloop_ctx;
6585 : :
6586 : 0 : wpa_printf(MSG_DEBUG, "P2P: Frequency conflict - terminate group");
6587 : 0 : wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_FREQ_CONFLICT);
6588 : 0 : }
6589 : :
6590 : :
6591 : 0 : int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq,
6592 : : struct wpa_ssid *ssid)
6593 : : {
6594 : : struct wpa_supplicant *iface;
6595 : :
6596 [ # # ]: 0 : for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
6597 [ # # ][ # # ]: 0 : if (!iface->current_ssid ||
6598 [ # # ]: 0 : iface->current_ssid->frequency == freq ||
6599 [ # # ]: 0 : (iface->p2p_group_interface == NOT_P2P_GROUP_INTERFACE &&
6600 : 0 : !iface->current_ssid->p2p_group))
6601 : 0 : continue;
6602 : :
6603 : : /* Remove the connection with least priority */
6604 [ # # ]: 0 : if (!wpas_is_p2p_prioritized(iface)) {
6605 : : /* STA connection has priority over existing
6606 : : * P2P connection, so remove the interface. */
6607 : 0 : wpa_printf(MSG_DEBUG, "P2P: Removing P2P connection due to single channel concurrent mode frequency conflict");
6608 : 0 : eloop_register_timeout(0, 0,
6609 : : wpas_p2p_group_freq_conflict,
6610 : : iface, NULL);
6611 : : /* If connection in progress is P2P connection, do not
6612 : : * proceed for the connection. */
6613 [ # # ]: 0 : if (wpa_s == iface)
6614 : 0 : return -1;
6615 : : else
6616 : 0 : return 0;
6617 : : } else {
6618 : : /* P2P connection has priority, disable the STA network
6619 : : */
6620 : 0 : wpa_supplicant_disable_network(wpa_s->global->ifaces,
6621 : : ssid);
6622 : 0 : wpa_msg(wpa_s->global->ifaces, MSG_INFO,
6623 : : WPA_EVENT_FREQ_CONFLICT " id=%d", ssid->id);
6624 : 0 : os_memset(wpa_s->global->ifaces->pending_bssid, 0,
6625 : : ETH_ALEN);
6626 : : /* If P2P connection is in progress, continue
6627 : : * connecting...*/
6628 [ # # ]: 0 : if (wpa_s == iface)
6629 : 0 : return 0;
6630 : : else
6631 : 0 : return -1;
6632 : : }
6633 : : }
6634 : :
6635 : 0 : return 0;
6636 : : }
6637 : :
6638 : :
6639 : 8 : int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s)
6640 : : {
6641 : 8 : struct wpa_ssid *ssid = wpa_s->current_ssid;
6642 : :
6643 [ + - ][ + + ]: 8 : if (ssid == NULL || !ssid->p2p_group)
6644 : 1 : return 0;
6645 : :
6646 [ + + ][ + - ]: 7 : if (wpa_s->p2p_last_4way_hs_fail &&
6647 : 2 : wpa_s->p2p_last_4way_hs_fail == ssid) {
6648 : : u8 go_dev_addr[ETH_ALEN];
6649 : : struct wpa_ssid *persistent;
6650 : :
6651 [ - + ]: 2 : if (wpas_p2p_persistent_group(wpa_s, go_dev_addr,
6652 : 2 : ssid->ssid,
6653 : : ssid->ssid_len) <= 0) {
6654 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not determine whether 4-way handshake failures were for a persistent group");
6655 : 0 : goto disconnect;
6656 : : }
6657 : :
6658 : 2 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Two 4-way handshake failures for a P2P group - go_dev_addr="
6659 : : MACSTR, MAC2STR(go_dev_addr));
6660 : 2 : persistent = wpas_p2p_get_persistent(wpa_s->parent, go_dev_addr,
6661 : 2 : ssid->ssid,
6662 : : ssid->ssid_len);
6663 [ + - ][ - + ]: 2 : if (persistent == NULL || persistent->mode != WPAS_MODE_INFRA) {
6664 : 0 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No matching persistent group stored");
6665 : 0 : goto disconnect;
6666 : : }
6667 : 2 : wpa_msg_global(wpa_s->parent, MSG_INFO,
6668 : : P2P_EVENT_PERSISTENT_PSK_FAIL "%d",
6669 : : persistent->id);
6670 : : disconnect:
6671 : 2 : wpa_s->p2p_last_4way_hs_fail = NULL;
6672 : : /*
6673 : : * Remove the group from a timeout to avoid issues with caller
6674 : : * continuing to use the interface if this is on a P2P group
6675 : : * interface.
6676 : : */
6677 : 2 : eloop_register_timeout(0, 0, wpas_p2p_psk_failure_removal,
6678 : : wpa_s, NULL);
6679 : 2 : return 1;
6680 : : }
6681 : :
6682 : 5 : wpa_s->p2p_last_4way_hs_fail = ssid;
6683 : 8 : return 0;
6684 : : }
|