Branch data Line data Source code
1 : : /*
2 : : * Wi-Fi Direct - P2P Group Owner Negotiation
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 "common/ieee802_11_defs.h"
13 : : #include "wps/wps_defs.h"
14 : : #include "p2p_i.h"
15 : : #include "p2p.h"
16 : :
17 : :
18 : 98 : static int p2p_go_det(u8 own_intent, u8 peer_value)
19 : : {
20 : 98 : u8 peer_intent = peer_value >> 1;
21 [ + + ]: 98 : if (own_intent == peer_intent) {
22 [ + + ]: 13 : if (own_intent == P2P_MAX_GO_INTENT)
23 : 1 : return -1; /* both devices want to become GO */
24 : :
25 : : /* Use tie breaker bit to determine GO */
26 [ + + ]: 12 : return (peer_value & 0x01) ? 0 : 1;
27 : : }
28 : :
29 : 98 : return own_intent > peer_intent;
30 : : }
31 : :
32 : :
33 : 128 : int p2p_peer_channels_check(struct p2p_data *p2p, struct p2p_channels *own,
34 : : struct p2p_device *dev,
35 : : const u8 *channel_list, size_t channel_list_len)
36 : : {
37 : : const u8 *pos, *end;
38 : : struct p2p_channels *ch;
39 : : size_t channels;
40 : : struct p2p_channels intersection;
41 : :
42 : 128 : ch = &dev->channels;
43 : 128 : os_memset(ch, 0, sizeof(*ch));
44 : 128 : pos = channel_list;
45 : 128 : end = channel_list + channel_list_len;
46 : :
47 [ - + ]: 128 : if (end - pos < 3)
48 : 0 : return -1;
49 : 128 : os_memcpy(dev->country, pos, 3);
50 : 128 : wpa_hexdump_ascii(MSG_DEBUG, "P2P: Peer country", pos, 3);
51 [ - + ][ # # ]: 128 : if (pos[2] != 0x04 && os_memcmp(pos, p2p->cfg->country, 2) != 0) {
52 : 0 : p2p_info(p2p, "Mismatching country (ours=%c%c peer's=%c%c)",
53 : 0 : p2p->cfg->country[0], p2p->cfg->country[1],
54 : 0 : pos[0], pos[1]);
55 : 0 : return -1;
56 : : }
57 : 128 : pos += 3;
58 : :
59 [ + + ]: 261 : while (pos + 2 < end) {
60 : 133 : struct p2p_reg_class *cl = &ch->reg_class[ch->reg_classes];
61 : 133 : cl->reg_class = *pos++;
62 [ - + ]: 133 : if (pos + 1 + pos[0] > end) {
63 : 0 : p2p_info(p2p, "Invalid peer Channel List");
64 : 0 : return -1;
65 : : }
66 : 133 : channels = *pos++;
67 : 133 : cl->channels = channels > P2P_MAX_REG_CLASS_CHANNELS ?
68 : 133 : P2P_MAX_REG_CLASS_CHANNELS : channels;
69 : 133 : os_memcpy(cl->channel, pos, cl->channels);
70 : 133 : pos += channels;
71 : 133 : ch->reg_classes++;
72 [ - + ]: 133 : if (ch->reg_classes == P2P_MAX_REG_CLASSES)
73 : 0 : break;
74 : : }
75 : :
76 : 128 : p2p_channels_intersect(own, &dev->channels, &intersection);
77 : 128 : p2p_dbg(p2p, "Own reg_classes %d peer reg_classes %d intersection reg_classes %d",
78 : 128 : (int) own->reg_classes,
79 : 128 : (int) dev->channels.reg_classes,
80 : 128 : (int) intersection.reg_classes);
81 [ + + ]: 128 : if (intersection.reg_classes == 0) {
82 : 2 : p2p_info(p2p, "No common channels found");
83 : 2 : return -1;
84 : : }
85 : 128 : return 0;
86 : : }
87 : :
88 : :
89 : 97 : static int p2p_peer_channels(struct p2p_data *p2p, struct p2p_device *dev,
90 : : const u8 *channel_list, size_t channel_list_len)
91 : : {
92 : 97 : return p2p_peer_channels_check(p2p, &p2p->channels, dev,
93 : : channel_list, channel_list_len);
94 : : }
95 : :
96 : :
97 : 238 : u16 p2p_wps_method_pw_id(enum p2p_wps_method wps_method)
98 : : {
99 [ + + + + : 238 : switch (wps_method) {
+ ]
100 : : case WPS_PIN_DISPLAY:
101 : 55 : return DEV_PW_REGISTRAR_SPECIFIED;
102 : : case WPS_PIN_KEYPAD:
103 : 114 : return DEV_PW_USER_SPECIFIED;
104 : : case WPS_PBC:
105 : 40 : return DEV_PW_PUSHBUTTON;
106 : : case WPS_NFC:
107 : 12 : return DEV_PW_NFC_CONNECTION_HANDOVER;
108 : : default:
109 : 238 : return DEV_PW_DEFAULT;
110 : : }
111 : : }
112 : :
113 : :
114 : 2 : static const char * p2p_wps_method_str(enum p2p_wps_method wps_method)
115 : : {
116 [ + + - - : 2 : switch (wps_method) {
- ]
117 : : case WPS_PIN_DISPLAY:
118 : 1 : return "Display";
119 : : case WPS_PIN_KEYPAD:
120 : 1 : return "Keypad";
121 : : case WPS_PBC:
122 : 0 : return "PBC";
123 : : case WPS_NFC:
124 : 0 : return "NFC";
125 : : default:
126 : 2 : return "??";
127 : : }
128 : : }
129 : :
130 : :
131 : 106 : static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p,
132 : : struct p2p_device *peer)
133 : : {
134 : : struct wpabuf *buf;
135 : : u8 *len;
136 : : u8 group_capab;
137 : 106 : size_t extra = 0;
138 : : u16 pw_id;
139 : :
140 : : #ifdef CONFIG_WIFI_DISPLAY
141 [ + + ]: 106 : if (p2p->wfd_ie_go_neg)
142 : 89 : extra = wpabuf_len(p2p->wfd_ie_go_neg);
143 : : #endif /* CONFIG_WIFI_DISPLAY */
144 : :
145 : 106 : buf = wpabuf_alloc(1000 + extra);
146 [ - + ]: 106 : if (buf == NULL)
147 : 0 : return NULL;
148 : :
149 : 106 : p2p_buf_add_public_action_hdr(buf, P2P_GO_NEG_REQ, peer->dialog_token);
150 : :
151 : 106 : len = p2p_buf_add_ie_hdr(buf);
152 : 106 : group_capab = 0;
153 [ + + ]: 106 : if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) {
154 : 5 : group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
155 [ + + ]: 5 : if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN)
156 : 4 : group_capab |= P2P_GROUP_CAPAB_PERSISTENT_RECONN;
157 : : }
158 [ - + ]: 106 : if (p2p->cross_connect)
159 : 0 : group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
160 [ + - ]: 106 : if (p2p->cfg->p2p_intra_bss)
161 : 106 : group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
162 : 106 : p2p_buf_add_capability(buf, p2p->dev_capab &
163 : : ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
164 : : group_capab);
165 : 106 : p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | peer->tie_breaker);
166 : 106 : p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout);
167 : 106 : p2p_buf_add_listen_channel(buf, p2p->cfg->country, p2p->cfg->reg_class,
168 : 106 : p2p->cfg->channel);
169 [ - + ]: 106 : if (p2p->ext_listen_interval)
170 : 0 : p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period,
171 : 0 : p2p->ext_listen_interval);
172 : 106 : p2p_buf_add_intended_addr(buf, p2p->intended_addr);
173 : 106 : p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels);
174 : 106 : p2p_buf_add_device_info(buf, p2p, peer);
175 : 106 : p2p_buf_add_operating_channel(buf, p2p->cfg->country,
176 : 212 : p2p->op_reg_class, p2p->op_channel);
177 : 106 : p2p_buf_update_ie_hdr(buf, len);
178 : :
179 : : /* WPS IE with Device Password ID attribute */
180 : 106 : pw_id = p2p_wps_method_pw_id(peer->wps_method);
181 [ + + ]: 106 : if (peer->oob_pw_id)
182 : 6 : pw_id = peer->oob_pw_id;
183 [ - + ]: 106 : if (p2p_build_wps_ie(p2p, buf, pw_id, 0) < 0) {
184 : 0 : p2p_dbg(p2p, "Failed to build WPS IE for GO Negotiation Request");
185 : 0 : wpabuf_free(buf);
186 : 0 : return NULL;
187 : : }
188 : :
189 : : #ifdef CONFIG_WIFI_DISPLAY
190 [ + + ]: 106 : if (p2p->wfd_ie_go_neg)
191 : 89 : wpabuf_put_buf(buf, p2p->wfd_ie_go_neg);
192 : : #endif /* CONFIG_WIFI_DISPLAY */
193 : :
194 : 106 : return buf;
195 : : }
196 : :
197 : :
198 : 106 : int p2p_connect_send(struct p2p_data *p2p, struct p2p_device *dev)
199 : : {
200 : : struct wpabuf *req;
201 : : int freq;
202 : :
203 [ - + ]: 106 : if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) {
204 : : u16 config_method;
205 : 0 : p2p_dbg(p2p, "Use PD-before-GO-Neg workaround for " MACSTR,
206 : 0 : MAC2STR(dev->info.p2p_device_addr));
207 [ # # ]: 0 : if (dev->wps_method == WPS_PIN_DISPLAY)
208 : 0 : config_method = WPS_CONFIG_KEYPAD;
209 [ # # ]: 0 : else if (dev->wps_method == WPS_PIN_KEYPAD)
210 : 0 : config_method = WPS_CONFIG_DISPLAY;
211 [ # # ]: 0 : else if (dev->wps_method == WPS_PBC)
212 : 0 : config_method = WPS_CONFIG_PUSHBUTTON;
213 : : else
214 : 0 : return -1;
215 : 0 : return p2p_prov_disc_req(p2p, dev->info.p2p_device_addr,
216 : : config_method, 0, 0, 1);
217 : : }
218 : :
219 [ + + ]: 106 : freq = dev->listen_freq > 0 ? dev->listen_freq : dev->oper_freq;
220 [ + + ]: 106 : if (dev->oob_go_neg_freq > 0)
221 : 6 : freq = dev->oob_go_neg_freq;
222 [ - + ]: 106 : if (freq <= 0) {
223 : 0 : p2p_dbg(p2p, "No Listen/Operating frequency known for the peer "
224 : : MACSTR " to send GO Negotiation Request",
225 : 0 : MAC2STR(dev->info.p2p_device_addr));
226 : 0 : return -1;
227 : : }
228 : :
229 : 106 : req = p2p_build_go_neg_req(p2p, dev);
230 [ - + ]: 106 : if (req == NULL)
231 : 0 : return -1;
232 : 106 : p2p_dbg(p2p, "Sending GO Negotiation Request");
233 : 106 : p2p_set_state(p2p, P2P_CONNECT);
234 : 106 : p2p->pending_action_state = P2P_PENDING_GO_NEG_REQUEST;
235 : 106 : p2p->go_neg_peer = dev;
236 : 106 : dev->flags |= P2P_DEV_WAIT_GO_NEG_RESPONSE;
237 : 106 : dev->connect_reqs++;
238 [ - + ]: 212 : if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
239 : 106 : p2p->cfg->dev_addr, dev->info.p2p_device_addr,
240 : 106 : wpabuf_head(req), wpabuf_len(req), 500) < 0) {
241 : 0 : p2p_dbg(p2p, "Failed to send Action frame");
242 : : /* Use P2P find to recover and retry */
243 : 0 : p2p_set_timeout(p2p, 0, 0);
244 : : } else
245 : 106 : dev->go_neg_req_sent++;
246 : :
247 : 106 : wpabuf_free(req);
248 : :
249 : 106 : return 0;
250 : : }
251 : :
252 : :
253 : 72 : static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p,
254 : : struct p2p_device *peer,
255 : : u8 dialog_token, u8 status,
256 : : u8 tie_breaker)
257 : : {
258 : : struct wpabuf *buf;
259 : : u8 *len;
260 : : u8 group_capab;
261 : 72 : size_t extra = 0;
262 : : u16 pw_id;
263 : :
264 : 72 : p2p_dbg(p2p, "Building GO Negotiation Response");
265 : :
266 : : #ifdef CONFIG_WIFI_DISPLAY
267 [ + + ]: 72 : if (p2p->wfd_ie_go_neg)
268 : 62 : extra = wpabuf_len(p2p->wfd_ie_go_neg);
269 : : #endif /* CONFIG_WIFI_DISPLAY */
270 : :
271 : 72 : buf = wpabuf_alloc(1000 + extra);
272 [ - + ]: 72 : if (buf == NULL)
273 : 0 : return NULL;
274 : :
275 : 72 : p2p_buf_add_public_action_hdr(buf, P2P_GO_NEG_RESP, dialog_token);
276 : :
277 : 72 : len = p2p_buf_add_ie_hdr(buf);
278 : 72 : p2p_buf_add_status(buf, status);
279 : 72 : group_capab = 0;
280 [ + + ][ + + ]: 72 : if (peer && peer->go_state == LOCAL_GO) {
281 [ - + ]: 18 : if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) {
282 : 0 : group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
283 [ # # ]: 0 : if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN)
284 : 0 : group_capab |=
285 : : P2P_GROUP_CAPAB_PERSISTENT_RECONN;
286 : : }
287 [ - + ]: 18 : if (p2p->cross_connect)
288 : 0 : group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
289 [ + - ]: 18 : if (p2p->cfg->p2p_intra_bss)
290 : 18 : group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
291 : : }
292 : 72 : p2p_buf_add_capability(buf, p2p->dev_capab &
293 : : ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
294 : : group_capab);
295 : 72 : p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | tie_breaker);
296 : 72 : p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout);
297 [ + + ][ + + ]: 72 : if (peer && peer->go_state == REMOTE_GO) {
298 : 29 : p2p_dbg(p2p, "Omit Operating Channel attribute");
299 : : } else {
300 : 43 : p2p_buf_add_operating_channel(buf, p2p->cfg->country,
301 : 43 : p2p->op_reg_class,
302 : 43 : p2p->op_channel);
303 : : }
304 : 72 : p2p_buf_add_intended_addr(buf, p2p->intended_addr);
305 [ + + ][ - + ]: 72 : if (status || peer == NULL) {
306 : 25 : p2p_buf_add_channel_list(buf, p2p->cfg->country,
307 : : &p2p->channels);
308 [ + + ]: 47 : } else if (peer->go_state == REMOTE_GO) {
309 : 29 : p2p_buf_add_channel_list(buf, p2p->cfg->country,
310 : : &p2p->channels);
311 : : } else {
312 : : struct p2p_channels res;
313 : 18 : p2p_channels_intersect(&p2p->channels, &peer->channels,
314 : : &res);
315 : 18 : p2p_buf_add_channel_list(buf, p2p->cfg->country, &res);
316 : : }
317 : 72 : p2p_buf_add_device_info(buf, p2p, peer);
318 [ + + ][ + + ]: 72 : if (peer && peer->go_state == LOCAL_GO) {
319 : 18 : p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, p2p->ssid,
320 : : p2p->ssid_len);
321 : : }
322 : 72 : p2p_buf_update_ie_hdr(buf, len);
323 : :
324 : : /* WPS IE with Device Password ID attribute */
325 [ + + ]: 72 : pw_id = p2p_wps_method_pw_id(peer ? peer->wps_method : WPS_NOT_READY);
326 [ + + ][ + + ]: 72 : if (peer && peer->oob_pw_id)
327 : 6 : pw_id = peer->oob_pw_id;
328 [ - + ]: 72 : if (p2p_build_wps_ie(p2p, buf, pw_id, 0) < 0) {
329 : 0 : p2p_dbg(p2p, "Failed to build WPS IE for GO Negotiation Response");
330 : 0 : wpabuf_free(buf);
331 : 0 : return NULL;
332 : : }
333 : :
334 : : #ifdef CONFIG_WIFI_DISPLAY
335 [ + + ]: 72 : if (p2p->wfd_ie_go_neg)
336 : 62 : wpabuf_put_buf(buf, p2p->wfd_ie_go_neg);
337 : : #endif /* CONFIG_WIFI_DISPLAY */
338 : :
339 : :
340 : 72 : return buf;
341 : : }
342 : :
343 : :
344 : : /**
345 : : * p2p_reselect_channel - Re-select operating channel based on peer information
346 : : * @p2p: P2P module context from p2p_init()
347 : : * @intersection: Support channel list intersection from local and peer
348 : : *
349 : : * This function is used to re-select the best channel after having received
350 : : * information from the peer to allow supported channel lists to be intersected.
351 : : * This can be used to improve initial channel selection done in
352 : : * p2p_prepare_channel() prior to the start of GO Negotiation. In addition, this
353 : : * can be used for Invitation case.
354 : : */
355 : 55 : void p2p_reselect_channel(struct p2p_data *p2p,
356 : : struct p2p_channels *intersection)
357 : : {
358 : : struct p2p_reg_class *cl;
359 : : int freq;
360 : : u8 op_reg_class, op_channel;
361 : : unsigned int i;
362 : 55 : const int op_classes_5ghz[] = { 124, 115, 0 };
363 : 55 : const int op_classes_ht40[] = { 126, 127, 116, 117, 0 };
364 : 55 : const int op_classes_vht[] = { 128, 0 };
365 : :
366 [ - + # # ]: 55 : if (p2p->own_freq_preference > 0 &&
367 : 0 : p2p_freq_to_channel(p2p->own_freq_preference,
368 [ # # ]: 0 : &op_reg_class, &op_channel) == 0 &&
369 : 0 : p2p_channels_includes(intersection, op_reg_class, op_channel)) {
370 : 0 : p2p_dbg(p2p, "Pick own channel preference (reg_class %u channel %u) from intersection",
371 : : op_reg_class, op_channel);
372 : 0 : p2p->op_reg_class = op_reg_class;
373 : 0 : p2p->op_channel = op_channel;
374 : 0 : return;
375 : : }
376 : :
377 [ - + # # ]: 55 : if (p2p->best_freq_overall > 0 &&
378 : 0 : p2p_freq_to_channel(p2p->best_freq_overall,
379 [ # # ]: 0 : &op_reg_class, &op_channel) == 0 &&
380 : 0 : p2p_channels_includes(intersection, op_reg_class, op_channel)) {
381 : 0 : p2p_dbg(p2p, "Pick best overall channel (reg_class %u channel %u) from intersection",
382 : : op_reg_class, op_channel);
383 : 0 : p2p->op_reg_class = op_reg_class;
384 : 0 : p2p->op_channel = op_channel;
385 : 0 : return;
386 : : }
387 : :
388 : : /* First, try to pick the best channel from another band */
389 : 55 : freq = p2p_channel_to_freq(p2p->op_reg_class, p2p->op_channel);
390 [ + - ][ + - ]: 55 : if (freq >= 2400 && freq < 2500 && p2p->best_freq_5 > 0 &&
[ - + # # ]
391 : 0 : !p2p_channels_includes(intersection, p2p->op_reg_class,
392 [ # # ]: 0 : p2p->op_channel) &&
393 : 0 : p2p_freq_to_channel(p2p->best_freq_5,
394 [ # # ]: 0 : &op_reg_class, &op_channel) == 0 &&
395 : 0 : p2p_channels_includes(intersection, op_reg_class, op_channel)) {
396 : 0 : p2p_dbg(p2p, "Pick best 5 GHz channel (reg_class %u channel %u) from intersection",
397 : : op_reg_class, op_channel);
398 : 0 : p2p->op_reg_class = op_reg_class;
399 : 0 : p2p->op_channel = op_channel;
400 : 0 : return;
401 : : }
402 : :
403 [ - + ][ # # ]: 55 : if (freq >= 4900 && freq < 6000 && p2p->best_freq_24 > 0 &&
[ # # # # ]
404 : 0 : !p2p_channels_includes(intersection, p2p->op_reg_class,
405 [ # # ]: 0 : p2p->op_channel) &&
406 : 0 : p2p_freq_to_channel(p2p->best_freq_24,
407 [ # # ]: 0 : &op_reg_class, &op_channel) == 0 &&
408 : 0 : p2p_channels_includes(intersection, op_reg_class, op_channel)) {
409 : 0 : p2p_dbg(p2p, "Pick best 2.4 GHz channel (reg_class %u channel %u) from intersection",
410 : : op_reg_class, op_channel);
411 : 0 : p2p->op_reg_class = op_reg_class;
412 : 0 : p2p->op_channel = op_channel;
413 : 0 : return;
414 : : }
415 : :
416 : : /* Select channel with highest preference if the peer supports it */
417 [ + + ][ + + ]: 56 : for (i = 0; p2p->cfg->pref_chan && i < p2p->cfg->num_pref_chan; i++) {
418 [ + + ]: 2 : if (p2p_channels_includes(intersection,
419 : 2 : p2p->cfg->pref_chan[i].op_class,
420 : 2 : p2p->cfg->pref_chan[i].chan)) {
421 : 1 : p2p->op_reg_class = p2p->cfg->pref_chan[i].op_class;
422 : 1 : p2p->op_channel = p2p->cfg->pref_chan[i].chan;
423 : 1 : p2p_dbg(p2p, "Pick highest preferred channel (op_class %u channel %u) from intersection",
424 : 2 : p2p->op_reg_class, p2p->op_channel);
425 : 1 : return;
426 : : }
427 : : }
428 : :
429 : : /* Try a channel where we might be able to use VHT */
430 [ - + ]: 54 : if (p2p_channel_select(intersection, op_classes_vht,
431 : : &p2p->op_reg_class, &p2p->op_channel) == 0) {
432 : 0 : p2p_dbg(p2p, "Pick possible VHT channel (op_class %u channel %u) from intersection",
433 : 0 : p2p->op_reg_class, p2p->op_channel);
434 : 0 : return;
435 : : }
436 : :
437 : : /* Try a channel where we might be able to use HT40 */
438 [ - + ]: 54 : if (p2p_channel_select(intersection, op_classes_ht40,
439 : : &p2p->op_reg_class, &p2p->op_channel) == 0) {
440 : 0 : p2p_dbg(p2p, "Pick possible HT40 channel (op_class %u channel %u) from intersection",
441 : 0 : p2p->op_reg_class, p2p->op_channel);
442 : 0 : return;
443 : : }
444 : :
445 : : /* Prefer a 5 GHz channel */
446 [ - + ]: 54 : if (p2p_channel_select(intersection, op_classes_5ghz,
447 : : &p2p->op_reg_class, &p2p->op_channel) == 0) {
448 : 0 : p2p_dbg(p2p, "Pick possible 5 GHz channel (op_class %u channel %u) from intersection",
449 : 0 : p2p->op_reg_class, p2p->op_channel);
450 : 0 : return;
451 : : }
452 : :
453 : : /*
454 : : * Try to see if the original channel is in the intersection. If
455 : : * so, no need to change anything, as it already contains some
456 : : * randomness.
457 : : */
458 [ + + ]: 54 : if (p2p_channels_includes(intersection, p2p->op_reg_class,
459 : 54 : p2p->op_channel)) {
460 : 52 : p2p_dbg(p2p, "Using original operating class and channel (op_class %u channel %u) from intersection",
461 : 104 : p2p->op_reg_class, p2p->op_channel);
462 : 52 : return;
463 : : }
464 : :
465 : : /*
466 : : * Fall back to whatever is included in the channel intersection since
467 : : * no better options seems to be available.
468 : : */
469 : 2 : cl = &intersection->reg_class[0];
470 : 2 : p2p_dbg(p2p, "Pick another channel (reg_class %u channel %u) from intersection",
471 : 4 : cl->reg_class, cl->channel[0]);
472 : 2 : p2p->op_reg_class = cl->reg_class;
473 : 55 : p2p->op_channel = cl->channel[0];
474 : : }
475 : :
476 : :
477 : 46 : static int p2p_go_select_channel(struct p2p_data *p2p, struct p2p_device *dev,
478 : : u8 *status)
479 : : {
480 : : struct p2p_channels tmp, intersection;
481 : :
482 : 46 : p2p_channels_dump(p2p, "own channels", &p2p->channels);
483 : 46 : p2p_channels_dump(p2p, "peer channels", &dev->channels);
484 : 46 : p2p_channels_intersect(&p2p->channels, &dev->channels, &tmp);
485 : 46 : p2p_channels_dump(p2p, "intersection", &tmp);
486 : 46 : p2p_channels_remove_freqs(&tmp, &p2p->no_go_freq);
487 : 46 : p2p_channels_dump(p2p, "intersection after no-GO removal", &tmp);
488 : 46 : p2p_channels_intersect(&tmp, &p2p->cfg->channels, &intersection);
489 : 46 : p2p_channels_dump(p2p, "intersection with local channel list",
490 : : &intersection);
491 [ + + ][ - + ]: 46 : if (intersection.reg_classes == 0 ||
492 : 45 : intersection.reg_class[0].channels == 0) {
493 : 1 : *status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
494 : 1 : p2p_dbg(p2p, "No common channels found");
495 : 1 : return -1;
496 : : }
497 : :
498 [ + + ]: 45 : if (!p2p_channels_includes(&intersection, p2p->op_reg_class,
499 : 45 : p2p->op_channel)) {
500 [ - + ]: 2 : if (dev->flags & P2P_DEV_FORCE_FREQ) {
501 : 0 : *status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
502 : 0 : p2p_dbg(p2p, "Peer does not support the forced channel");
503 : 0 : return -1;
504 : : }
505 : :
506 : 2 : p2p_dbg(p2p, "Selected operating channel (op_class %u channel %u) not acceptable to the peer",
507 : 4 : p2p->op_reg_class, p2p->op_channel);
508 : 2 : p2p_reselect_channel(p2p, &intersection);
509 [ + + ][ + - ]: 43 : } else if (!(dev->flags & P2P_DEV_FORCE_FREQ) &&
510 : 35 : !p2p->cfg->cfg_op_channel) {
511 : 35 : p2p_dbg(p2p, "Try to optimize channel selection with peer information received; previously selected op_class %u channel %u",
512 : 70 : p2p->op_reg_class, p2p->op_channel);
513 : 35 : p2p_reselect_channel(p2p, &intersection);
514 : : }
515 : :
516 [ + - ]: 45 : if (!p2p->ssid_set) {
517 : 45 : p2p_build_ssid(p2p, p2p->ssid, &p2p->ssid_len);
518 : 45 : p2p->ssid_set = 1;
519 : : }
520 : :
521 : 46 : return 0;
522 : : }
523 : :
524 : :
525 : 74 : void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa,
526 : : const u8 *data, size_t len, int rx_freq)
527 : : {
528 : 74 : struct p2p_device *dev = NULL;
529 : : struct wpabuf *resp;
530 : : struct p2p_message msg;
531 : 74 : u8 status = P2P_SC_FAIL_INVALID_PARAMS;
532 : 74 : int tie_breaker = 0;
533 : : int freq;
534 : :
535 : 74 : p2p_dbg(p2p, "Received GO Negotiation Request from " MACSTR "(freq=%d)",
536 : 444 : MAC2STR(sa), rx_freq);
537 : :
538 [ + + ]: 74 : if (p2p_parse(data, len, &msg))
539 : 1 : return;
540 : :
541 [ + + ]: 73 : if (!msg.capability) {
542 : 3 : p2p_dbg(p2p, "Mandatory Capability attribute missing from GO Negotiation Request");
543 : : #ifdef CONFIG_P2P_STRICT
544 : : goto fail;
545 : : #endif /* CONFIG_P2P_STRICT */
546 : : }
547 : :
548 [ + + ]: 73 : if (msg.go_intent)
549 : 71 : tie_breaker = *msg.go_intent & 0x01;
550 : : else {
551 : 2 : p2p_dbg(p2p, "Mandatory GO Intent attribute missing from GO Negotiation Request");
552 : : #ifdef CONFIG_P2P_STRICT
553 : : goto fail;
554 : : #endif /* CONFIG_P2P_STRICT */
555 : : }
556 : :
557 [ + + ]: 73 : if (!msg.config_timeout) {
558 : 3 : p2p_dbg(p2p, "Mandatory Configuration Timeout attribute missing from GO Negotiation Request");
559 : : #ifdef CONFIG_P2P_STRICT
560 : : goto fail;
561 : : #endif /* CONFIG_P2P_STRICT */
562 : : }
563 : :
564 [ + + ]: 73 : if (!msg.listen_channel) {
565 : 1 : p2p_dbg(p2p, "No Listen Channel attribute received");
566 : 1 : goto fail;
567 : : }
568 [ + + ]: 72 : if (!msg.operating_channel) {
569 : 1 : p2p_dbg(p2p, "No Operating Channel attribute received");
570 : 1 : goto fail;
571 : : }
572 [ + + ]: 71 : if (!msg.channel_list) {
573 : 1 : p2p_dbg(p2p, "No Channel List attribute received");
574 : 1 : goto fail;
575 : : }
576 [ + + ]: 70 : if (!msg.intended_addr) {
577 : 1 : p2p_dbg(p2p, "No Intended P2P Interface Address attribute received");
578 : 1 : goto fail;
579 : : }
580 [ + + ]: 69 : if (!msg.p2p_device_info) {
581 : 1 : p2p_dbg(p2p, "No P2P Device Info attribute received");
582 : 1 : goto fail;
583 : : }
584 : :
585 [ + + ]: 68 : if (os_memcmp(msg.p2p_device_addr, sa, ETH_ALEN) != 0) {
586 : 1 : p2p_dbg(p2p, "Unexpected GO Negotiation Request SA=" MACSTR
587 : : " != dev_addr=" MACSTR,
588 : 12 : MAC2STR(sa), MAC2STR(msg.p2p_device_addr));
589 : 1 : goto fail;
590 : : }
591 : :
592 : 67 : dev = p2p_get_device(p2p, sa);
593 : :
594 [ + + ][ + - ]: 67 : if (msg.status && *msg.status) {
595 : 1 : p2p_dbg(p2p, "Unexpected Status attribute (%d) in GO Negotiation Request",
596 : 1 : *msg.status);
597 [ - + ][ # # ]: 1 : if (dev && p2p->go_neg_peer == dev &&
[ # # ]
598 : 0 : *msg.status == P2P_SC_FAIL_REJECTED_BY_USER) {
599 : : /*
600 : : * This mechanism for using Status attribute in GO
601 : : * Negotiation Request is not compliant with the P2P
602 : : * specification, but some deployed devices use it to
603 : : * indicate rejection of GO Negotiation in a case where
604 : : * they have sent out GO Negotiation Response with
605 : : * status 1. The P2P specification explicitly disallows
606 : : * this. To avoid unnecessary interoperability issues
607 : : * and extra frames, mark the pending negotiation as
608 : : * failed and do not reply to this GO Negotiation
609 : : * Request frame.
610 : : */
611 : 0 : p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
612 : 0 : p2p_go_neg_failed(p2p, dev, *msg.status);
613 : 0 : p2p_parse_free(&msg);
614 : 0 : return;
615 : : }
616 : 1 : goto fail;
617 : : }
618 : :
619 [ + + ]: 66 : if (dev == NULL)
620 : 4 : dev = p2p_add_dev_from_go_neg_req(p2p, sa, &msg);
621 [ + + ]: 62 : else if (dev->flags & P2P_DEV_PROBE_REQ_ONLY)
622 : 5 : p2p_add_dev_info(p2p, sa, dev, &msg);
623 [ + + ][ + - ]: 57 : else if (!dev->listen_freq && !dev->oper_freq) {
624 : : /*
625 : : * This may happen if the peer entry was added based on PD
626 : : * Request and no Probe Request/Response frame has been received
627 : : * from this peer (or that information has timed out).
628 : : */
629 : 5 : p2p_dbg(p2p, "Update peer " MACSTR
630 : : " based on GO Neg Req since listen/oper freq not known",
631 : 30 : MAC2STR(dev->info.p2p_device_addr));
632 : 5 : p2p_add_dev_info(p2p, sa, dev, &msg);
633 : : }
634 : :
635 [ + - ][ + + ]: 66 : if (dev && dev->flags & P2P_DEV_USER_REJECTED) {
636 : 1 : p2p_dbg(p2p, "User has rejected this peer");
637 : 1 : status = P2P_SC_FAIL_REJECTED_BY_USER;
638 [ + - ][ + + ]: 65 : } else if (dev == NULL ||
639 [ + + ]: 11 : (dev->wps_method == WPS_NOT_READY &&
640 [ + + ]: 3 : (p2p->authorized_oob_dev_pw_id == 0 ||
641 : 3 : p2p->authorized_oob_dev_pw_id !=
642 : 3 : msg.dev_password_id))) {
643 : 9 : p2p_dbg(p2p, "Not ready for GO negotiation with " MACSTR,
644 : 54 : MAC2STR(sa));
645 : 9 : status = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
646 : 9 : p2p->cfg->go_neg_req_rx(p2p->cfg->cb_ctx, sa,
647 : 9 : msg.dev_password_id);
648 [ + + ][ - + ]: 56 : } else if (p2p->go_neg_peer && p2p->go_neg_peer != dev) {
649 : 0 : p2p_dbg(p2p, "Already in Group Formation with another peer");
650 : 0 : status = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
651 : : } else {
652 : : int go;
653 : :
654 [ + + ]: 56 : if (!p2p->go_neg_peer) {
655 : 47 : p2p_dbg(p2p, "Starting GO Negotiation with previously authorized peer");
656 [ + + ]: 47 : if (!(dev->flags & P2P_DEV_FORCE_FREQ)) {
657 : 42 : p2p_dbg(p2p, "Use default channel settings");
658 : 42 : p2p->op_reg_class = p2p->cfg->op_reg_class;
659 : 42 : p2p->op_channel = p2p->cfg->op_channel;
660 : 42 : os_memcpy(&p2p->channels, &p2p->cfg->channels,
661 : : sizeof(struct p2p_channels));
662 : : } else {
663 : 5 : p2p_dbg(p2p, "Use previously configured forced channel settings");
664 : : }
665 : : }
666 : :
667 : 56 : dev->flags &= ~P2P_DEV_NOT_YET_READY;
668 : :
669 [ + + ]: 56 : if (!msg.go_intent) {
670 : 1 : p2p_dbg(p2p, "No GO Intent attribute received");
671 : 1 : goto fail;
672 : : }
673 [ + + ]: 55 : if ((*msg.go_intent >> 1) > P2P_MAX_GO_INTENT) {
674 : 1 : p2p_dbg(p2p, "Invalid GO Intent value (%u) received",
675 : 1 : *msg.go_intent >> 1);
676 : 1 : goto fail;
677 : : }
678 : :
679 [ + + ][ + + ]: 54 : if (dev->go_neg_req_sent &&
680 : 2 : os_memcmp(sa, p2p->cfg->dev_addr, ETH_ALEN) > 0) {
681 : 1 : p2p_dbg(p2p, "Do not reply since peer has higher address and GO Neg Request already sent");
682 : 1 : p2p_parse_free(&msg);
683 : 1 : return;
684 : : }
685 : :
686 : 53 : go = p2p_go_det(p2p->go_intent, *msg.go_intent);
687 [ + + ]: 53 : if (go < 0) {
688 : 1 : p2p_dbg(p2p, "Incompatible GO Intent");
689 : 1 : status = P2P_SC_FAIL_BOTH_GO_INTENT_15;
690 : 1 : goto fail;
691 : : }
692 : :
693 [ + + ]: 52 : if (p2p_peer_channels(p2p, dev, msg.channel_list,
694 : 52 : msg.channel_list_len) < 0) {
695 : 1 : p2p_dbg(p2p, "No common channels found");
696 : 1 : status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
697 : 1 : goto fail;
698 : : }
699 : :
700 [ + + + + ]: 51 : switch (msg.dev_password_id) {
701 : : case DEV_PW_REGISTRAR_SPECIFIED:
702 : 4 : p2p_dbg(p2p, "PIN from peer Display");
703 [ + + ]: 4 : if (dev->wps_method != WPS_PIN_KEYPAD) {
704 : 1 : p2p_dbg(p2p, "We have wps_method=%s -> incompatible",
705 : : p2p_wps_method_str(dev->wps_method));
706 : 1 : status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
707 : 1 : goto fail;
708 : : }
709 : 3 : break;
710 : : case DEV_PW_USER_SPECIFIED:
711 : 37 : p2p_dbg(p2p, "Peer entered PIN on Keypad");
712 [ + + ]: 37 : if (dev->wps_method != WPS_PIN_DISPLAY) {
713 : 1 : p2p_dbg(p2p, "We have wps_method=%s -> incompatible",
714 : : p2p_wps_method_str(dev->wps_method));
715 : 1 : status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
716 : 1 : goto fail;
717 : : }
718 : 36 : break;
719 : : case DEV_PW_PUSHBUTTON:
720 : 3 : p2p_dbg(p2p, "Peer using pushbutton");
721 [ - + ]: 3 : if (dev->wps_method != WPS_PBC) {
722 : 0 : p2p_dbg(p2p, "We have wps_method=%s -> incompatible",
723 : : p2p_wps_method_str(dev->wps_method));
724 : 0 : status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
725 : 0 : goto fail;
726 : : }
727 : 3 : break;
728 : : default:
729 [ + + ][ + + ]: 7 : if (msg.dev_password_id &&
730 : 6 : msg.dev_password_id == dev->oob_pw_id) {
731 : 4 : p2p_dbg(p2p, "Peer using NFC");
732 [ - + ]: 4 : if (dev->wps_method != WPS_NFC) {
733 : 0 : p2p_dbg(p2p, "We have wps_method=%s -> incompatible",
734 : : p2p_wps_method_str(
735 : : dev->wps_method));
736 : 0 : status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
737 : 0 : goto fail;
738 : : }
739 : 4 : break;
740 : : }
741 : : #ifdef CONFIG_WPS_NFC
742 [ + + ][ + - ]: 3 : if (p2p->authorized_oob_dev_pw_id &&
743 : 2 : msg.dev_password_id ==
744 : 2 : p2p->authorized_oob_dev_pw_id) {
745 : 2 : p2p_dbg(p2p, "Using static handover with our device password from NFC Tag");
746 : 2 : dev->wps_method = WPS_NFC;
747 : 2 : dev->oob_pw_id = p2p->authorized_oob_dev_pw_id;
748 : 2 : break;
749 : : }
750 : : #endif /* CONFIG_WPS_NFC */
751 : 1 : p2p_dbg(p2p, "Unsupported Device Password ID %d",
752 : 1 : msg.dev_password_id);
753 : 1 : status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
754 : 1 : goto fail;
755 : : }
756 : :
757 [ + + ][ + + ]: 48 : if (go && p2p_go_select_channel(p2p, dev, &status) < 0)
758 : 1 : goto fail;
759 : :
760 [ + + ]: 47 : dev->go_state = go ? LOCAL_GO : REMOTE_GO;
761 : 47 : dev->oper_freq = p2p_channel_to_freq(msg.operating_channel[3],
762 : 47 : msg.operating_channel[4]);
763 : 47 : p2p_dbg(p2p, "Peer operating channel preference: %d MHz",
764 : : dev->oper_freq);
765 : :
766 [ + - ]: 47 : if (msg.config_timeout) {
767 : 47 : dev->go_timeout = msg.config_timeout[0];
768 : 47 : dev->client_timeout = msg.config_timeout[1];
769 : : }
770 : :
771 : 47 : p2p_dbg(p2p, "GO Negotiation with " MACSTR, MAC2STR(sa));
772 [ + - ]: 47 : if (p2p->state != P2P_IDLE)
773 : 47 : p2p_stop_find_for_freq(p2p, rx_freq);
774 : 47 : p2p_set_state(p2p, P2P_GO_NEG);
775 : 47 : p2p_clear_timeout(p2p);
776 : 47 : dev->dialog_token = msg.dialog_token;
777 : 47 : os_memcpy(dev->intended_addr, msg.intended_addr, ETH_ALEN);
778 : 47 : p2p->go_neg_peer = dev;
779 : 47 : status = P2P_SC_SUCCESS;
780 : : }
781 : :
782 : : fail:
783 [ + + ]: 72 : if (dev)
784 : 65 : dev->status = status;
785 : 72 : resp = p2p_build_go_neg_resp(p2p, dev, msg.dialog_token, status,
786 : : !tie_breaker);
787 : 72 : p2p_parse_free(&msg);
788 [ - + ]: 72 : if (resp == NULL)
789 : 0 : return;
790 : 72 : p2p_dbg(p2p, "Sending GO Negotiation Response");
791 [ + - ]: 72 : if (rx_freq > 0)
792 : 72 : freq = rx_freq;
793 : : else
794 : 0 : freq = p2p_channel_to_freq(p2p->cfg->reg_class,
795 : 0 : p2p->cfg->channel);
796 [ - + ]: 72 : if (freq < 0) {
797 : 0 : p2p_dbg(p2p, "Unknown regulatory class/channel");
798 : 0 : wpabuf_free(resp);
799 : 0 : return;
800 : : }
801 [ + + ]: 72 : if (status == P2P_SC_SUCCESS) {
802 : 47 : p2p->pending_action_state = P2P_PENDING_GO_NEG_RESPONSE;
803 : 47 : dev->flags |= P2P_DEV_WAIT_GO_NEG_CONFIRM;
804 [ + + ]: 47 : if (os_memcmp(sa, p2p->cfg->dev_addr, ETH_ALEN) < 0) {
805 : : /*
806 : : * Peer has smaller address, so the GO Negotiation
807 : : * Response from us is expected to complete
808 : : * negotiation. Ignore a GO Negotiation Response from
809 : : * the peer if it happens to be received after this
810 : : * point due to a race condition in GO Negotiation
811 : : * Request transmission and processing.
812 : : */
813 : 40 : dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
814 : : }
815 : : } else
816 : 25 : p2p->pending_action_state =
817 : : P2P_PENDING_GO_NEG_RESPONSE_FAILURE;
818 [ - + ]: 144 : if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
819 : 72 : p2p->cfg->dev_addr,
820 : 72 : wpabuf_head(resp), wpabuf_len(resp), 500) < 0) {
821 : 0 : p2p_dbg(p2p, "Failed to send Action frame");
822 : : }
823 : :
824 : 74 : wpabuf_free(resp);
825 : : }
826 : :
827 : :
828 : 45 : static struct wpabuf * p2p_build_go_neg_conf(struct p2p_data *p2p,
829 : : struct p2p_device *peer,
830 : : u8 dialog_token, u8 status,
831 : : const u8 *resp_chan, int go)
832 : : {
833 : : struct wpabuf *buf;
834 : : u8 *len;
835 : : struct p2p_channels res;
836 : : u8 group_capab;
837 : 45 : size_t extra = 0;
838 : :
839 : 45 : p2p_dbg(p2p, "Building GO Negotiation Confirm");
840 : :
841 : : #ifdef CONFIG_WIFI_DISPLAY
842 [ + + ]: 45 : if (p2p->wfd_ie_go_neg)
843 : 37 : extra = wpabuf_len(p2p->wfd_ie_go_neg);
844 : : #endif /* CONFIG_WIFI_DISPLAY */
845 : :
846 : 45 : buf = wpabuf_alloc(1000 + extra);
847 [ - + ]: 45 : if (buf == NULL)
848 : 0 : return NULL;
849 : :
850 : 45 : p2p_buf_add_public_action_hdr(buf, P2P_GO_NEG_CONF, dialog_token);
851 : :
852 : 45 : len = p2p_buf_add_ie_hdr(buf);
853 : 45 : p2p_buf_add_status(buf, status);
854 : 45 : group_capab = 0;
855 [ - + ]: 45 : if (peer->go_state == LOCAL_GO) {
856 [ # # ]: 0 : if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) {
857 : 0 : group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
858 [ # # ]: 0 : if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN)
859 : 0 : group_capab |=
860 : : P2P_GROUP_CAPAB_PERSISTENT_RECONN;
861 : : }
862 [ # # ]: 0 : if (p2p->cross_connect)
863 : 0 : group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
864 [ # # ]: 0 : if (p2p->cfg->p2p_intra_bss)
865 : 0 : group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
866 : : }
867 : 45 : p2p_buf_add_capability(buf, p2p->dev_capab &
868 : : ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
869 : : group_capab);
870 [ + + ][ - + ]: 45 : if (go || resp_chan == NULL)
871 : 27 : p2p_buf_add_operating_channel(buf, p2p->cfg->country,
872 : 27 : p2p->op_reg_class,
873 : 27 : p2p->op_channel);
874 : : else
875 : 18 : p2p_buf_add_operating_channel(buf, (const char *) resp_chan,
876 : 36 : resp_chan[3], resp_chan[4]);
877 : 45 : p2p_channels_intersect(&p2p->channels, &peer->channels, &res);
878 : 45 : p2p_buf_add_channel_list(buf, p2p->cfg->country, &res);
879 [ + + ]: 45 : if (go) {
880 : 27 : p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, p2p->ssid,
881 : : p2p->ssid_len);
882 : : }
883 : 45 : p2p_buf_update_ie_hdr(buf, len);
884 : :
885 : : #ifdef CONFIG_WIFI_DISPLAY
886 [ + + ]: 45 : if (p2p->wfd_ie_go_neg)
887 : 37 : wpabuf_put_buf(buf, p2p->wfd_ie_go_neg);
888 : : #endif /* CONFIG_WIFI_DISPLAY */
889 : :
890 : 45 : return buf;
891 : : }
892 : :
893 : :
894 : 57 : void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa,
895 : : const u8 *data, size_t len, int rx_freq)
896 : : {
897 : : struct p2p_device *dev;
898 : : struct wpabuf *conf;
899 : 57 : int go = -1;
900 : : struct p2p_message msg;
901 : 57 : u8 status = P2P_SC_SUCCESS;
902 : : int freq;
903 : :
904 : 57 : p2p_dbg(p2p, "Received GO Negotiation Response from " MACSTR
905 : 342 : " (freq=%d)", MAC2STR(sa), rx_freq);
906 : 57 : dev = p2p_get_device(p2p, sa);
907 [ + - ][ + - ]: 57 : if (dev == NULL || dev->wps_method == WPS_NOT_READY ||
[ - + ]
908 : 57 : dev != p2p->go_neg_peer) {
909 : 0 : p2p_dbg(p2p, "Not ready for GO negotiation with " MACSTR,
910 : 0 : MAC2STR(sa));
911 : 0 : return;
912 : : }
913 : :
914 [ - + ]: 57 : if (p2p_parse(data, len, &msg))
915 : 0 : return;
916 : :
917 [ - + ]: 57 : if (!(dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE)) {
918 : 0 : p2p_dbg(p2p, "Was not expecting GO Negotiation Response - ignore");
919 : 0 : p2p_parse_free(&msg);
920 : 0 : return;
921 : : }
922 : 57 : dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
923 : :
924 [ - + ]: 57 : if (msg.dialog_token != dev->dialog_token) {
925 : 0 : p2p_dbg(p2p, "Unexpected Dialog Token %u (expected %u)",
926 : 0 : msg.dialog_token, dev->dialog_token);
927 : 0 : p2p_parse_free(&msg);
928 : 0 : return;
929 : : }
930 : :
931 [ - + ]: 57 : if (!msg.status) {
932 : 0 : p2p_dbg(p2p, "No Status attribute received");
933 : 0 : status = P2P_SC_FAIL_INVALID_PARAMS;
934 : 0 : goto fail;
935 : : }
936 [ + + ]: 57 : if (*msg.status) {
937 : 12 : p2p_dbg(p2p, "GO Negotiation rejected: status %d", *msg.status);
938 : 12 : dev->go_neg_req_sent = 0;
939 [ + + ]: 12 : if (*msg.status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
940 : 6 : p2p_dbg(p2p, "Wait for the peer to become ready for GO Negotiation");
941 : 6 : dev->flags |= P2P_DEV_NOT_YET_READY;
942 : 6 : dev->wait_count = 0;
943 : 6 : p2p_set_state(p2p, P2P_WAIT_PEER_IDLE);
944 : 6 : p2p_set_timeout(p2p, 0, 0);
945 : : } else {
946 : 6 : p2p_dbg(p2p, "Stop GO Negotiation attempt");
947 : 6 : p2p_go_neg_failed(p2p, dev, *msg.status);
948 : : }
949 : 12 : p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
950 : 12 : p2p_parse_free(&msg);
951 : 12 : return;
952 : : }
953 : :
954 [ - + ]: 45 : if (!msg.capability) {
955 : 0 : p2p_dbg(p2p, "Mandatory Capability attribute missing from GO Negotiation Response");
956 : : #ifdef CONFIG_P2P_STRICT
957 : : status = P2P_SC_FAIL_INVALID_PARAMS;
958 : : goto fail;
959 : : #endif /* CONFIG_P2P_STRICT */
960 : : }
961 : :
962 [ - + ]: 45 : if (!msg.p2p_device_info) {
963 : 0 : p2p_dbg(p2p, "Mandatory P2P Device Info attribute missing from GO Negotiation Response");
964 : : #ifdef CONFIG_P2P_STRICT
965 : : status = P2P_SC_FAIL_INVALID_PARAMS;
966 : : goto fail;
967 : : #endif /* CONFIG_P2P_STRICT */
968 : : }
969 : :
970 [ - + ]: 45 : if (!msg.intended_addr) {
971 : 0 : p2p_dbg(p2p, "No Intended P2P Interface Address attribute received");
972 : 0 : status = P2P_SC_FAIL_INVALID_PARAMS;
973 : 0 : goto fail;
974 : : }
975 : :
976 [ - + ]: 45 : if (!msg.go_intent) {
977 : 0 : p2p_dbg(p2p, "No GO Intent attribute received");
978 : 0 : status = P2P_SC_FAIL_INVALID_PARAMS;
979 : 0 : goto fail;
980 : : }
981 [ - + ]: 45 : if ((*msg.go_intent >> 1) > P2P_MAX_GO_INTENT) {
982 : 0 : p2p_dbg(p2p, "Invalid GO Intent value (%u) received",
983 : 0 : *msg.go_intent >> 1);
984 : 0 : status = P2P_SC_FAIL_INVALID_PARAMS;
985 : 0 : goto fail;
986 : : }
987 : :
988 : 45 : go = p2p_go_det(p2p->go_intent, *msg.go_intent);
989 [ - + ]: 45 : if (go < 0) {
990 : 0 : p2p_dbg(p2p, "Incompatible GO Intent");
991 : 0 : status = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
992 : 0 : goto fail;
993 : : }
994 : :
995 [ + + ][ + - ]: 45 : if (!go && msg.group_id) {
996 : : /* Store SSID for Provisioning step */
997 : 18 : p2p->ssid_len = msg.group_id_len - ETH_ALEN;
998 : 18 : os_memcpy(p2p->ssid, msg.group_id + ETH_ALEN, p2p->ssid_len);
999 [ - + ]: 27 : } else if (!go) {
1000 : 0 : p2p_dbg(p2p, "Mandatory P2P Group ID attribute missing from GO Negotiation Response");
1001 : 0 : p2p->ssid_len = 0;
1002 : 0 : status = P2P_SC_FAIL_INVALID_PARAMS;
1003 : 0 : goto fail;
1004 : : }
1005 : :
1006 [ - + ]: 45 : if (!msg.config_timeout) {
1007 : 0 : p2p_dbg(p2p, "Mandatory Configuration Timeout attribute missing from GO Negotiation Response");
1008 : : #ifdef CONFIG_P2P_STRICT
1009 : : status = P2P_SC_FAIL_INVALID_PARAMS;
1010 : : goto fail;
1011 : : #endif /* CONFIG_P2P_STRICT */
1012 : : } else {
1013 : 45 : dev->go_timeout = msg.config_timeout[0];
1014 : 45 : dev->client_timeout = msg.config_timeout[1];
1015 : : }
1016 : :
1017 [ + + ][ - + ]: 45 : if (!msg.operating_channel && !go) {
1018 : : /*
1019 : : * Note: P2P Client may omit Operating Channel attribute to
1020 : : * indicate it does not have a preference.
1021 : : */
1022 : 0 : p2p_dbg(p2p, "No Operating Channel attribute received");
1023 : 0 : status = P2P_SC_FAIL_INVALID_PARAMS;
1024 : 0 : goto fail;
1025 : : }
1026 [ - + ]: 45 : if (!msg.channel_list) {
1027 : 0 : p2p_dbg(p2p, "No Channel List attribute received");
1028 : 0 : status = P2P_SC_FAIL_INVALID_PARAMS;
1029 : 0 : goto fail;
1030 : : }
1031 : :
1032 [ - + ]: 45 : if (p2p_peer_channels(p2p, dev, msg.channel_list,
1033 : 45 : msg.channel_list_len) < 0) {
1034 : 0 : p2p_dbg(p2p, "No common channels found");
1035 : 0 : status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
1036 : 0 : goto fail;
1037 : : }
1038 : :
1039 [ + + ]: 45 : if (msg.operating_channel) {
1040 : 18 : dev->oper_freq = p2p_channel_to_freq(msg.operating_channel[3],
1041 : 18 : msg.operating_channel[4]);
1042 : 18 : p2p_dbg(p2p, "Peer operating channel preference: %d MHz",
1043 : : dev->oper_freq);
1044 : : } else
1045 : 27 : dev->oper_freq = 0;
1046 : :
1047 [ + + + + ]: 45 : switch (msg.dev_password_id) {
1048 : : case DEV_PW_REGISTRAR_SPECIFIED:
1049 : 33 : p2p_dbg(p2p, "PIN from peer Display");
1050 [ - + ]: 33 : if (dev->wps_method != WPS_PIN_KEYPAD) {
1051 : 0 : p2p_dbg(p2p, "We have wps_method=%s -> incompatible",
1052 : : p2p_wps_method_str(dev->wps_method));
1053 : 0 : status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
1054 : 0 : goto fail;
1055 : : }
1056 : 33 : break;
1057 : : case DEV_PW_USER_SPECIFIED:
1058 : 3 : p2p_dbg(p2p, "Peer entered PIN on Keypad");
1059 [ - + ]: 3 : if (dev->wps_method != WPS_PIN_DISPLAY) {
1060 : 0 : p2p_dbg(p2p, "We have wps_method=%s -> incompatible",
1061 : : p2p_wps_method_str(dev->wps_method));
1062 : 0 : status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
1063 : 0 : goto fail;
1064 : : }
1065 : 3 : break;
1066 : : case DEV_PW_PUSHBUTTON:
1067 : 3 : p2p_dbg(p2p, "Peer using pushbutton");
1068 [ - + ]: 3 : if (dev->wps_method != WPS_PBC) {
1069 : 0 : p2p_dbg(p2p, "We have wps_method=%s -> incompatible",
1070 : : p2p_wps_method_str(dev->wps_method));
1071 : 0 : status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
1072 : 0 : goto fail;
1073 : : }
1074 : 3 : break;
1075 : : default:
1076 [ + - ][ + - ]: 6 : if (msg.dev_password_id &&
1077 : 6 : msg.dev_password_id == dev->oob_pw_id) {
1078 : 6 : p2p_dbg(p2p, "Peer using NFC");
1079 [ - + ]: 6 : if (dev->wps_method != WPS_NFC) {
1080 : 0 : p2p_dbg(p2p, "We have wps_method=%s -> incompatible",
1081 : : p2p_wps_method_str(dev->wps_method));
1082 : 0 : status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
1083 : 0 : goto fail;
1084 : : }
1085 : 6 : break;
1086 : : }
1087 : 0 : p2p_dbg(p2p, "Unsupported Device Password ID %d",
1088 : 0 : msg.dev_password_id);
1089 : 0 : status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
1090 : 0 : goto fail;
1091 : : }
1092 : :
1093 [ + + ][ - + ]: 45 : if (go && p2p_go_select_channel(p2p, dev, &status) < 0)
1094 : 0 : goto fail;
1095 : :
1096 : 45 : p2p_set_state(p2p, P2P_GO_NEG);
1097 : 45 : p2p_clear_timeout(p2p);
1098 : :
1099 : 45 : p2p_dbg(p2p, "GO Negotiation with " MACSTR, MAC2STR(sa));
1100 : 45 : os_memcpy(dev->intended_addr, msg.intended_addr, ETH_ALEN);
1101 : :
1102 : : fail:
1103 : 45 : conf = p2p_build_go_neg_conf(p2p, dev, msg.dialog_token, status,
1104 : : msg.operating_channel, go);
1105 : 45 : p2p_parse_free(&msg);
1106 [ - + ]: 45 : if (conf == NULL)
1107 : 0 : return;
1108 : 45 : p2p_dbg(p2p, "Sending GO Negotiation Confirm");
1109 [ + - ]: 45 : if (status == P2P_SC_SUCCESS) {
1110 : 45 : p2p->pending_action_state = P2P_PENDING_GO_NEG_CONFIRM;
1111 [ + + ]: 45 : dev->go_state = go ? LOCAL_GO : REMOTE_GO;
1112 : : } else
1113 : 0 : p2p->pending_action_state = P2P_NO_PENDING_ACTION;
1114 [ + - ]: 45 : if (rx_freq > 0)
1115 : 45 : freq = rx_freq;
1116 : : else
1117 : 0 : freq = dev->listen_freq;
1118 [ - + ]: 90 : if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, sa,
1119 : 45 : wpabuf_head(conf), wpabuf_len(conf), 200) < 0) {
1120 : 0 : p2p_dbg(p2p, "Failed to send Action frame");
1121 : 0 : p2p_go_neg_failed(p2p, dev, -1);
1122 : 0 : p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
1123 : : }
1124 : 45 : wpabuf_free(conf);
1125 [ - + ]: 45 : if (status != P2P_SC_SUCCESS) {
1126 : 0 : p2p_dbg(p2p, "GO Negotiation failed");
1127 : 57 : p2p_go_neg_failed(p2p, dev, status);
1128 : : }
1129 : : }
1130 : :
1131 : :
1132 : 45 : void p2p_process_go_neg_conf(struct p2p_data *p2p, const u8 *sa,
1133 : : const u8 *data, size_t len)
1134 : : {
1135 : : struct p2p_device *dev;
1136 : : struct p2p_message msg;
1137 : :
1138 : 45 : p2p_dbg(p2p, "Received GO Negotiation Confirm from " MACSTR,
1139 : 270 : MAC2STR(sa));
1140 : 45 : dev = p2p_get_device(p2p, sa);
1141 [ + - ][ + - ]: 45 : if (dev == NULL || dev->wps_method == WPS_NOT_READY ||
[ - + ]
1142 : 45 : dev != p2p->go_neg_peer) {
1143 : 0 : p2p_dbg(p2p, "Not ready for GO negotiation with " MACSTR,
1144 : 0 : MAC2STR(sa));
1145 : 0 : return;
1146 : : }
1147 : :
1148 [ - + ]: 45 : if (p2p->pending_action_state == P2P_PENDING_GO_NEG_RESPONSE) {
1149 : 0 : p2p_dbg(p2p, "Stopped waiting for TX status on GO Negotiation Response since we already received Confirmation");
1150 : 0 : p2p->pending_action_state = P2P_NO_PENDING_ACTION;
1151 : : }
1152 : :
1153 [ - + ]: 45 : if (p2p_parse(data, len, &msg))
1154 : 0 : return;
1155 : :
1156 [ - + ]: 45 : if (!(dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) {
1157 : 0 : p2p_dbg(p2p, "Was not expecting GO Negotiation Confirm - ignore");
1158 : 0 : p2p_parse_free(&msg);
1159 : 0 : return;
1160 : : }
1161 : 45 : dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM;
1162 : 45 : p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
1163 : :
1164 [ - + ]: 45 : if (msg.dialog_token != dev->dialog_token) {
1165 : 0 : p2p_dbg(p2p, "Unexpected Dialog Token %u (expected %u)",
1166 : 0 : msg.dialog_token, dev->dialog_token);
1167 : 0 : p2p_parse_free(&msg);
1168 : 0 : return;
1169 : : }
1170 : :
1171 [ - + ]: 45 : if (!msg.status) {
1172 : 0 : p2p_dbg(p2p, "No Status attribute received");
1173 : 0 : p2p_parse_free(&msg);
1174 : 0 : return;
1175 : : }
1176 [ - + ]: 45 : if (*msg.status) {
1177 : 0 : p2p_dbg(p2p, "GO Negotiation rejected: status %d", *msg.status);
1178 : 0 : p2p_go_neg_failed(p2p, dev, *msg.status);
1179 : 0 : p2p_parse_free(&msg);
1180 : 0 : return;
1181 : : }
1182 : :
1183 [ + + ][ + - ]: 45 : if (dev->go_state == REMOTE_GO && msg.group_id) {
1184 : : /* Store SSID for Provisioning step */
1185 : 27 : p2p->ssid_len = msg.group_id_len - ETH_ALEN;
1186 : 27 : os_memcpy(p2p->ssid, msg.group_id + ETH_ALEN, p2p->ssid_len);
1187 [ - + ]: 18 : } else if (dev->go_state == REMOTE_GO) {
1188 : 0 : p2p_dbg(p2p, "Mandatory P2P Group ID attribute missing from GO Negotiation Confirmation");
1189 : 0 : p2p->ssid_len = 0;
1190 : 0 : p2p_go_neg_failed(p2p, dev, P2P_SC_FAIL_INVALID_PARAMS);
1191 : 0 : p2p_parse_free(&msg);
1192 : 0 : return;
1193 : : }
1194 : :
1195 [ - + ]: 45 : if (!msg.operating_channel) {
1196 : 0 : p2p_dbg(p2p, "Mandatory Operating Channel attribute missing from GO Negotiation Confirmation");
1197 : : #ifdef CONFIG_P2P_STRICT
1198 : : p2p_parse_free(&msg);
1199 : : return;
1200 : : #endif /* CONFIG_P2P_STRICT */
1201 [ + + ]: 45 : } else if (dev->go_state == REMOTE_GO) {
1202 : 27 : int oper_freq = p2p_channel_to_freq(msg.operating_channel[3],
1203 : 27 : msg.operating_channel[4]);
1204 [ - + ]: 27 : if (oper_freq != dev->oper_freq) {
1205 : 0 : p2p_dbg(p2p, "Updated peer (GO) operating channel preference from %d MHz to %d MHz",
1206 : : dev->oper_freq, oper_freq);
1207 : 0 : dev->oper_freq = oper_freq;
1208 : : }
1209 : : }
1210 : :
1211 [ - + ]: 45 : if (!msg.channel_list) {
1212 : 0 : p2p_dbg(p2p, "Mandatory Operating Channel attribute missing from GO Negotiation Confirmation");
1213 : : #ifdef CONFIG_P2P_STRICT
1214 : : p2p_parse_free(&msg);
1215 : : return;
1216 : : #endif /* CONFIG_P2P_STRICT */
1217 : : }
1218 : :
1219 : 45 : p2p_parse_free(&msg);
1220 : :
1221 [ - + ]: 45 : if (dev->go_state == UNKNOWN_GO) {
1222 : : /*
1223 : : * This should not happen since GO negotiation has already
1224 : : * been completed.
1225 : : */
1226 : 0 : p2p_dbg(p2p, "Unexpected GO Neg state - do not know which end becomes GO");
1227 : 0 : return;
1228 : : }
1229 : :
1230 : : /*
1231 : : * The peer could have missed our ctrl::ack frame for GO Negotiation
1232 : : * Confirm and continue retransmitting the frame. To reduce the
1233 : : * likelihood of the peer not getting successful TX status for the
1234 : : * GO Negotiation Confirm frame, wait a short time here before starting
1235 : : * the group so that we will remain on the current channel to
1236 : : * acknowledge any possible retransmission from the peer.
1237 : : */
1238 : 45 : p2p_dbg(p2p, "20 ms wait on current channel before starting group");
1239 : 45 : os_sleep(0, 20000);
1240 : :
1241 : 45 : p2p_go_complete(p2p, dev);
1242 : : }
|