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