p2p_sd.c revision 1f69aa52ea2e0a73ac502565df8c666ee49cab6a
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/*
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Wi-Fi Direct - P2P service discovery
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Copyright (c) 2009, Atheros Communications
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * This program is free software; you can redistribute it and/or modify
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * it under the terms of the GNU General Public License version 2 as
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * published by the Free Software Foundation.
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Alternatively, this software may be distributed under the terms of BSD
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * license.
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * See README and COPYING for more details.
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "includes.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "common.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "common/ieee802_11_defs.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "common/gas.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "p2p_i.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "p2p.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstruct p2p_sd_query * p2p_pending_sd_req(struct p2p_data *p2p,
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch					 struct p2p_device *dev)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	struct p2p_sd_query *q;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch	if (!(dev->info.dev_capab & P2P_DEV_CAPAB_SERVICE_DISCOVERY))
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		return NULL; /* peer does not support SD */
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	for (q = p2p->sd_queries; q; q = q->next) {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		if (q->for_all_peers && !(dev->flags & P2P_DEV_SD_INFO))
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			return q;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		if (!q->for_all_peers &&
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		    os_memcmp(q->peer, dev->info.p2p_device_addr, ETH_ALEN) ==
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		    0)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			return q;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	}
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	return NULL;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
44
45static int p2p_unlink_sd_query(struct p2p_data *p2p,
46			       struct p2p_sd_query *query)
47{
48	struct p2p_sd_query *q, *prev;
49	q = p2p->sd_queries;
50	prev = NULL;
51	while (q) {
52		if (q == query) {
53			if (prev)
54				prev->next = q->next;
55			else
56				p2p->sd_queries = q->next;
57			if (p2p->sd_query == query)
58				p2p->sd_query = NULL;
59			return 1;
60		}
61		prev = q;
62		q = q->next;
63	}
64	return 0;
65}
66
67
68static void p2p_free_sd_query(struct p2p_sd_query *q)
69{
70	if (q == NULL)
71		return;
72	wpabuf_free(q->tlvs);
73	os_free(q);
74}
75
76
77void p2p_free_sd_queries(struct p2p_data *p2p)
78{
79	struct p2p_sd_query *q, *prev;
80	q = p2p->sd_queries;
81	p2p->sd_queries = NULL;
82	while (q) {
83		prev = q;
84		q = q->next;
85		p2p_free_sd_query(prev);
86	}
87}
88
89
90static struct wpabuf * p2p_build_sd_query(u16 update_indic,
91					  struct wpabuf *tlvs)
92{
93	struct wpabuf *buf;
94	u8 *len_pos;
95
96	buf = gas_anqp_build_initial_req(0, 100 + wpabuf_len(tlvs));
97	if (buf == NULL)
98		return NULL;
99
100	/* ANQP Query Request Frame */
101	len_pos = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
102	wpabuf_put_be24(buf, OUI_WFA);
103	wpabuf_put_u8(buf, P2P_OUI_TYPE);
104	wpabuf_put_le16(buf, update_indic); /* Service Update Indicator */
105	wpabuf_put_buf(buf, tlvs);
106	gas_anqp_set_element_len(buf, len_pos);
107
108	gas_anqp_set_len(buf);
109
110	return buf;
111}
112
113
114static void p2p_send_gas_comeback_req(struct p2p_data *p2p, const u8 *dst,
115				      u8 dialog_token, int freq)
116{
117	struct wpabuf *req;
118
119	req = gas_build_comeback_req(dialog_token);
120	if (req == NULL)
121		return;
122
123	p2p->pending_action_state = P2P_NO_PENDING_ACTION;
124	if (p2p_send_action(p2p, freq, dst, p2p->cfg->dev_addr, dst,
125			    wpabuf_head(req), wpabuf_len(req), 200) < 0)
126		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
127			"P2P: Failed to send Action frame");
128
129	wpabuf_free(req);
130}
131
132
133static struct wpabuf * p2p_build_sd_response(u8 dialog_token, u16 status_code,
134					     u16 comeback_delay,
135					     u16 update_indic,
136					     const struct wpabuf *tlvs)
137{
138	struct wpabuf *buf;
139	u8 *len_pos;
140
141	buf = gas_anqp_build_initial_resp(dialog_token, status_code,
142					  comeback_delay,
143					  100 + (tlvs ? wpabuf_len(tlvs) : 0));
144	if (buf == NULL)
145		return NULL;
146
147	if (tlvs) {
148		/* ANQP Query Response Frame */
149		len_pos = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
150		wpabuf_put_be24(buf, OUI_WFA);
151		wpabuf_put_u8(buf, P2P_OUI_TYPE);
152		 /* Service Update Indicator */
153		wpabuf_put_le16(buf, update_indic);
154		wpabuf_put_buf(buf, tlvs);
155		gas_anqp_set_element_len(buf, len_pos);
156	}
157
158	gas_anqp_set_len(buf);
159
160	return buf;
161}
162
163
164static struct wpabuf * p2p_build_gas_comeback_resp(u8 dialog_token,
165						   u16 status_code,
166						   u16 update_indic,
167						   const u8 *data, size_t len,
168						   u8 frag_id, u8 more,
169						   u16 total_len)
170{
171	struct wpabuf *buf;
172
173	buf = gas_anqp_build_comeback_resp(dialog_token, status_code, frag_id,
174					   more, 0, 100 + len);
175	if (buf == NULL)
176		return NULL;
177
178	if (frag_id == 0) {
179		/* ANQP Query Response Frame */
180		wpabuf_put_le16(buf, ANQP_VENDOR_SPECIFIC); /* Info ID */
181		wpabuf_put_le16(buf, 3 + 1 + 2 + total_len);
182		wpabuf_put_be24(buf, OUI_WFA);
183		wpabuf_put_u8(buf, P2P_OUI_TYPE);
184		/* Service Update Indicator */
185		wpabuf_put_le16(buf, update_indic);
186	}
187
188	wpabuf_put_data(buf, data, len);
189	gas_anqp_set_len(buf);
190
191	return buf;
192}
193
194
195int p2p_start_sd(struct p2p_data *p2p, struct p2p_device *dev)
196{
197	struct wpabuf *req;
198	int ret = 0;
199	struct p2p_sd_query *query;
200	int freq;
201
202	freq = dev->listen_freq > 0 ? dev->listen_freq : dev->oper_freq;
203	if (freq <= 0) {
204		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
205			"P2P: No Listen/Operating frequency known for the "
206			"peer " MACSTR " to send SD Request",
207			MAC2STR(dev->info.p2p_device_addr));
208		return -1;
209	}
210
211	query = p2p_pending_sd_req(p2p, dev);
212	if (query == NULL)
213		return -1;
214
215	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
216		"P2P: Start Service Discovery with " MACSTR,
217		MAC2STR(dev->info.p2p_device_addr));
218
219	req = p2p_build_sd_query(p2p->srv_update_indic, query->tlvs);
220	if (req == NULL)
221		return -1;
222
223	p2p->sd_peer = dev;
224	p2p->sd_query = query;
225	p2p->pending_action_state = P2P_PENDING_SD;
226
227	if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
228			    p2p->cfg->dev_addr, dev->info.p2p_device_addr,
229			    wpabuf_head(req), wpabuf_len(req), 5000) < 0) {
230		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
231			"P2P: Failed to send Action frame");
232		ret = -1;
233	}
234
235	wpabuf_free(req);
236
237	return ret;
238}
239
240
241void p2p_rx_gas_initial_req(struct p2p_data *p2p, const u8 *sa,
242			    const u8 *data, size_t len, int rx_freq)
243{
244	const u8 *pos = data;
245	const u8 *end = data + len;
246	const u8 *next;
247	u8 dialog_token;
248	u16 slen;
249	int freq;
250	u16 update_indic;
251
252
253	if (p2p->cfg->sd_request == NULL)
254		return;
255
256	if (rx_freq > 0)
257		freq = rx_freq;
258	else
259		freq = p2p_channel_to_freq(p2p->cfg->country,
260					   p2p->cfg->reg_class,
261					   p2p->cfg->channel);
262	if (freq < 0)
263		return;
264
265	if (len < 1 + 2)
266		return;
267
268	dialog_token = *pos++;
269	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
270		"P2P: GAS Initial Request from " MACSTR " (dialog token %u, "
271		"freq %d)",
272		MAC2STR(sa), dialog_token, rx_freq);
273
274	if (*pos != WLAN_EID_ADV_PROTO) {
275		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
276			"P2P: Unexpected IE in GAS Initial Request: %u", *pos);
277		return;
278	}
279	pos++;
280
281	slen = *pos++;
282	next = pos + slen;
283	if (next > end || slen < 2) {
284		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
285			"P2P: Invalid IE in GAS Initial Request");
286		return;
287	}
288	pos++; /* skip QueryRespLenLimit and PAME-BI */
289
290	if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) {
291		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
292			"P2P: Unsupported GAS advertisement protocol id %u",
293			*pos);
294		return;
295	}
296
297	pos = next;
298	/* Query Request */
299	if (pos + 2 > end)
300		return;
301	slen = WPA_GET_LE16(pos);
302	pos += 2;
303	if (pos + slen > end)
304		return;
305	end = pos + slen;
306
307	/* ANQP Query Request */
308	if (pos + 4 > end)
309		return;
310	if (WPA_GET_LE16(pos) != ANQP_VENDOR_SPECIFIC) {
311		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
312			"P2P: Unsupported ANQP Info ID %u", WPA_GET_LE16(pos));
313		return;
314	}
315	pos += 2;
316
317	slen = WPA_GET_LE16(pos);
318	pos += 2;
319	if (pos + slen > end || slen < 3 + 1) {
320		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
321			"P2P: Invalid ANQP Query Request length");
322		return;
323	}
324
325	if (WPA_GET_BE24(pos) != OUI_WFA) {
326		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
327			"P2P: Unsupported ANQP OUI %06x", WPA_GET_BE24(pos));
328		return;
329	}
330	pos += 3;
331
332	if (*pos != P2P_OUI_TYPE) {
333		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
334			"P2P: Unsupported ANQP vendor type %u", *pos);
335		return;
336	}
337	pos++;
338
339	if (pos + 2 > end)
340		return;
341	update_indic = WPA_GET_LE16(pos);
342	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
343		"P2P: Service Update Indicator: %u", update_indic);
344	pos += 2;
345
346	p2p->cfg->sd_request(p2p->cfg->cb_ctx, freq, sa, dialog_token,
347			     update_indic, pos, end - pos);
348	/* the response will be indicated with a call to p2p_sd_response() */
349}
350
351
352void p2p_sd_response(struct p2p_data *p2p, int freq, const u8 *dst,
353		     u8 dialog_token, const struct wpabuf *resp_tlvs)
354{
355	struct wpabuf *resp;
356
357	/* TODO: fix the length limit to match with the maximum frame length */
358	if (wpabuf_len(resp_tlvs) > 1400) {
359		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: SD response long "
360			"enough to require fragmentation");
361		if (p2p->sd_resp) {
362			/*
363			 * TODO: Could consider storing the fragmented response
364			 * separately for each peer to avoid having to drop old
365			 * one if there is more than one pending SD query.
366			 * Though, that would eat more memory, so there are
367			 * also benefits to just using a single buffer.
368			 */
369			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Drop "
370				"previous SD response");
371			wpabuf_free(p2p->sd_resp);
372		}
373		os_memcpy(p2p->sd_resp_addr, dst, ETH_ALEN);
374		p2p->sd_resp_dialog_token = dialog_token;
375		p2p->sd_resp = wpabuf_dup(resp_tlvs);
376		p2p->sd_resp_pos = 0;
377		p2p->sd_frag_id = 0;
378		resp = p2p_build_sd_response(dialog_token, WLAN_STATUS_SUCCESS,
379					     1, p2p->srv_update_indic, NULL);
380	} else {
381		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: SD response fits "
382			"in initial response");
383		resp = p2p_build_sd_response(dialog_token,
384					     WLAN_STATUS_SUCCESS, 0,
385					     p2p->srv_update_indic, resp_tlvs);
386	}
387	if (resp == NULL)
388		return;
389
390	p2p->pending_action_state = P2P_NO_PENDING_ACTION;
391	if (p2p_send_action(p2p, freq, dst, p2p->cfg->dev_addr,
392			    p2p->cfg->dev_addr,
393			    wpabuf_head(resp), wpabuf_len(resp), 200) < 0)
394		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
395			"P2P: Failed to send Action frame");
396
397	wpabuf_free(resp);
398}
399
400
401void p2p_rx_gas_initial_resp(struct p2p_data *p2p, const u8 *sa,
402			     const u8 *data, size_t len, int rx_freq)
403{
404	const u8 *pos = data;
405	const u8 *end = data + len;
406	const u8 *next;
407	u8 dialog_token;
408	u16 status_code;
409	u16 comeback_delay;
410	u16 slen;
411	u16 update_indic;
412
413	if (p2p->state != P2P_SD_DURING_FIND || p2p->sd_peer == NULL ||
414	    os_memcmp(sa, p2p->sd_peer->info.p2p_device_addr, ETH_ALEN) != 0) {
415		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
416			"P2P: Ignore unexpected GAS Initial Response from "
417			MACSTR, MAC2STR(sa));
418		return;
419	}
420	p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
421	p2p_clear_timeout(p2p);
422
423	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
424		"P2P: Received GAS Initial Response from " MACSTR " (len=%d)",
425		MAC2STR(sa), (int) len);
426
427	if (len < 5 + 2) {
428		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
429			"P2P: Too short GAS Initial Response frame");
430		return;
431	}
432
433	dialog_token = *pos++;
434	/* TODO: check dialog_token match */
435	status_code = WPA_GET_LE16(pos);
436	pos += 2;
437	comeback_delay = WPA_GET_LE16(pos);
438	pos += 2;
439	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
440		"P2P: dialog_token=%u status_code=%u comeback_delay=%u",
441		dialog_token, status_code, comeback_delay);
442	if (status_code) {
443		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
444			"P2P: Service Discovery failed: status code %u",
445			status_code);
446		return;
447	}
448
449	if (*pos != WLAN_EID_ADV_PROTO) {
450		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
451			"P2P: Unexpected IE in GAS Initial Response: %u",
452			*pos);
453		return;
454	}
455	pos++;
456
457	slen = *pos++;
458	next = pos + slen;
459	if (next > end || slen < 2) {
460		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
461			"P2P: Invalid IE in GAS Initial Response");
462		return;
463	}
464	pos++; /* skip QueryRespLenLimit and PAME-BI */
465
466	if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) {
467		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
468			"P2P: Unsupported GAS advertisement protocol id %u",
469			*pos);
470		return;
471	}
472
473	pos = next;
474	/* Query Response */
475	if (pos + 2 > end) {
476		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Too short Query "
477			"Response");
478		return;
479	}
480	slen = WPA_GET_LE16(pos);
481	pos += 2;
482	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Query Response Length: %d",
483		slen);
484	if (pos + slen > end) {
485		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Not enough Query "
486			"Response data");
487		return;
488	}
489	end = pos + slen;
490
491	if (comeback_delay) {
492		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Fragmented "
493			"response - request fragments");
494		if (p2p->sd_rx_resp) {
495			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Drop "
496				"old SD reassembly buffer");
497			wpabuf_free(p2p->sd_rx_resp);
498			p2p->sd_rx_resp = NULL;
499		}
500		p2p_send_gas_comeback_req(p2p, sa, dialog_token, rx_freq);
501		return;
502	}
503
504	/* ANQP Query Response */
505	if (pos + 4 > end)
506		return;
507	if (WPA_GET_LE16(pos) != ANQP_VENDOR_SPECIFIC) {
508		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
509			"P2P: Unsupported ANQP Info ID %u", WPA_GET_LE16(pos));
510		return;
511	}
512	pos += 2;
513
514	slen = WPA_GET_LE16(pos);
515	pos += 2;
516	if (pos + slen > end || slen < 3 + 1) {
517		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
518			"P2P: Invalid ANQP Query Response length");
519		return;
520	}
521
522	if (WPA_GET_BE24(pos) != OUI_WFA) {
523		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
524			"P2P: Unsupported ANQP OUI %06x", WPA_GET_BE24(pos));
525		return;
526	}
527	pos += 3;
528
529	if (*pos != P2P_OUI_TYPE) {
530		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
531			"P2P: Unsupported ANQP vendor type %u", *pos);
532		return;
533	}
534	pos++;
535
536	if (pos + 2 > end)
537		return;
538	update_indic = WPA_GET_LE16(pos);
539	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
540		"P2P: Service Update Indicator: %u", update_indic);
541	pos += 2;
542
543	p2p->sd_peer->flags |= P2P_DEV_SD_INFO;
544	p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE;
545	p2p->sd_peer = NULL;
546
547	if (p2p->sd_query) {
548		if (!p2p->sd_query->for_all_peers) {
549			struct p2p_sd_query *q;
550			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
551				"P2P: Remove completed SD query %p",
552				p2p->sd_query);
553			q = p2p->sd_query;
554			p2p_unlink_sd_query(p2p, p2p->sd_query);
555			p2p_free_sd_query(q);
556		}
557		p2p->sd_query = NULL;
558	}
559
560	if (p2p->cfg->sd_response)
561		p2p->cfg->sd_response(p2p->cfg->cb_ctx, sa, update_indic,
562				      pos, end - pos);
563	p2p_continue_find(p2p);
564}
565
566
567void p2p_rx_gas_comeback_req(struct p2p_data *p2p, const u8 *sa,
568			     const u8 *data, size_t len, int rx_freq)
569{
570	struct wpabuf *resp;
571	u8 dialog_token;
572	size_t frag_len;
573	int more = 0;
574
575	wpa_hexdump(MSG_DEBUG, "P2P: RX GAS Comeback Request", data, len);
576	if (len < 1)
577		return;
578	dialog_token = *data;
579	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dialog Token: %u",
580		dialog_token);
581	if (dialog_token != p2p->sd_resp_dialog_token) {
582		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: No pending SD "
583			"response fragment for dialog token %u", dialog_token);
584		return;
585	}
586
587	if (p2p->sd_resp == NULL) {
588		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: No pending SD "
589			"response fragment available");
590		return;
591	}
592	if (os_memcmp(sa, p2p->sd_resp_addr, ETH_ALEN) != 0) {
593		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: No pending SD "
594			"response fragment for " MACSTR, MAC2STR(sa));
595		return;
596	}
597
598	frag_len = wpabuf_len(p2p->sd_resp) - p2p->sd_resp_pos;
599	if (frag_len > 1400) {
600		frag_len = 1400;
601		more = 1;
602	}
603	resp = p2p_build_gas_comeback_resp(dialog_token, WLAN_STATUS_SUCCESS,
604					   p2p->srv_update_indic,
605					   wpabuf_head_u8(p2p->sd_resp) +
606					   p2p->sd_resp_pos, frag_len,
607					   p2p->sd_frag_id, more,
608					   wpabuf_len(p2p->sd_resp));
609	if (resp == NULL)
610		return;
611	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send GAS Comeback "
612		"Response (frag_id %d more=%d frag_len=%d)",
613		p2p->sd_frag_id, more, (int) frag_len);
614	p2p->sd_frag_id++;
615	p2p->sd_resp_pos += frag_len;
616
617	if (more) {
618		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: %d more bytes "
619			"remain to be sent",
620			(int) (wpabuf_len(p2p->sd_resp) - p2p->sd_resp_pos));
621	} else {
622		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: All fragments of "
623			"SD response sent");
624		wpabuf_free(p2p->sd_resp);
625		p2p->sd_resp = NULL;
626	}
627
628	p2p->pending_action_state = P2P_NO_PENDING_ACTION;
629	if (p2p_send_action(p2p, rx_freq, sa, p2p->cfg->dev_addr,
630			    p2p->cfg->dev_addr,
631			    wpabuf_head(resp), wpabuf_len(resp), 200) < 0)
632		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
633			"P2P: Failed to send Action frame");
634
635	wpabuf_free(resp);
636}
637
638
639void p2p_rx_gas_comeback_resp(struct p2p_data *p2p, const u8 *sa,
640			      const u8 *data, size_t len, int rx_freq)
641{
642	const u8 *pos = data;
643	const u8 *end = data + len;
644	const u8 *next;
645	u8 dialog_token;
646	u16 status_code;
647	u8 frag_id;
648	u8 more_frags;
649	u16 comeback_delay;
650	u16 slen;
651
652	wpa_hexdump(MSG_DEBUG, "P2P: RX GAS Comeback Response", data, len);
653
654	if (p2p->state != P2P_SD_DURING_FIND || p2p->sd_peer == NULL ||
655	    os_memcmp(sa, p2p->sd_peer->info.p2p_device_addr, ETH_ALEN) != 0) {
656		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
657			"P2P: Ignore unexpected GAS Comeback Response from "
658			MACSTR, MAC2STR(sa));
659		return;
660	}
661	p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
662	p2p_clear_timeout(p2p);
663
664	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
665		"P2P: Received GAS Comeback Response from " MACSTR " (len=%d)",
666		MAC2STR(sa), (int) len);
667
668	if (len < 6 + 2) {
669		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
670			"P2P: Too short GAS Comeback Response frame");
671		return;
672	}
673
674	dialog_token = *pos++;
675	/* TODO: check dialog_token match */
676	status_code = WPA_GET_LE16(pos);
677	pos += 2;
678	frag_id = *pos & 0x7f;
679	more_frags = (*pos & 0x80) >> 7;
680	pos++;
681	comeback_delay = WPA_GET_LE16(pos);
682	pos += 2;
683	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
684		"P2P: dialog_token=%u status_code=%u frag_id=%d more_frags=%d "
685		"comeback_delay=%u",
686		dialog_token, status_code, frag_id, more_frags,
687		comeback_delay);
688	/* TODO: check frag_id match */
689	if (status_code) {
690		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
691			"P2P: Service Discovery failed: status code %u",
692			status_code);
693		return;
694	}
695
696	if (*pos != WLAN_EID_ADV_PROTO) {
697		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
698			"P2P: Unexpected IE in GAS Comeback Response: %u",
699			*pos);
700		return;
701	}
702	pos++;
703
704	slen = *pos++;
705	next = pos + slen;
706	if (next > end || slen < 2) {
707		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
708			"P2P: Invalid IE in GAS Comeback Response");
709		return;
710	}
711	pos++; /* skip QueryRespLenLimit and PAME-BI */
712
713	if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) {
714		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
715			"P2P: Unsupported GAS advertisement protocol id %u",
716			*pos);
717		return;
718	}
719
720	pos = next;
721	/* Query Response */
722	if (pos + 2 > end) {
723		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Too short Query "
724			"Response");
725		return;
726	}
727	slen = WPA_GET_LE16(pos);
728	pos += 2;
729	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Query Response Length: %d",
730		slen);
731	if (pos + slen > end) {
732		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Not enough Query "
733			"Response data");
734		return;
735	}
736	if (slen == 0) {
737		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: No Query Response "
738			"data");
739		return;
740	}
741	end = pos + slen;
742
743	if (p2p->sd_rx_resp) {
744		 /*
745		  * ANQP header is only included in the first fragment; rest of
746		  * the fragments start with continue TLVs.
747		  */
748		goto skip_nqp_header;
749	}
750
751	/* ANQP Query Response */
752	if (pos + 4 > end)
753		return;
754	if (WPA_GET_LE16(pos) != ANQP_VENDOR_SPECIFIC) {
755		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
756			"P2P: Unsupported ANQP Info ID %u", WPA_GET_LE16(pos));
757		return;
758	}
759	pos += 2;
760
761	slen = WPA_GET_LE16(pos);
762	pos += 2;
763	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: ANQP Query Response "
764		"length: %u", slen);
765	if (slen < 3 + 1) {
766		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
767			"P2P: Invalid ANQP Query Response length");
768		return;
769	}
770	if (pos + 4 > end)
771		return;
772
773	if (WPA_GET_BE24(pos) != OUI_WFA) {
774		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
775			"P2P: Unsupported ANQP OUI %06x", WPA_GET_BE24(pos));
776		return;
777	}
778	pos += 3;
779
780	if (*pos != P2P_OUI_TYPE) {
781		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
782			"P2P: Unsupported ANQP vendor type %u", *pos);
783		return;
784	}
785	pos++;
786
787	if (pos + 2 > end)
788		return;
789	p2p->sd_rx_update_indic = WPA_GET_LE16(pos);
790	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
791		"P2P: Service Update Indicator: %u", p2p->sd_rx_update_indic);
792	pos += 2;
793
794skip_nqp_header:
795	if (wpabuf_resize(&p2p->sd_rx_resp, end - pos) < 0)
796		return;
797	wpabuf_put_data(p2p->sd_rx_resp, pos, end - pos);
798	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Current SD reassembly "
799		"buffer length: %u",
800		(unsigned int) wpabuf_len(p2p->sd_rx_resp));
801
802	if (more_frags) {
803		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: More fragments "
804			"remains");
805		/* TODO: what would be a good size limit? */
806		if (wpabuf_len(p2p->sd_rx_resp) > 64000) {
807			wpabuf_free(p2p->sd_rx_resp);
808			p2p->sd_rx_resp = NULL;
809			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Too long "
810				"SD response - drop it");
811			return;
812		}
813		p2p_send_gas_comeback_req(p2p, sa, dialog_token, rx_freq);
814		return;
815	}
816
817	p2p->sd_peer->flags |= P2P_DEV_SD_INFO;
818	p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE;
819	p2p->sd_peer = NULL;
820
821	if (p2p->sd_query) {
822		if (!p2p->sd_query->for_all_peers) {
823			struct p2p_sd_query *q;
824			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
825				"P2P: Remove completed SD query %p",
826				p2p->sd_query);
827			q = p2p->sd_query;
828			p2p_unlink_sd_query(p2p, p2p->sd_query);
829			p2p_free_sd_query(q);
830		}
831		p2p->sd_query = NULL;
832	}
833
834	if (p2p->cfg->sd_response)
835		p2p->cfg->sd_response(p2p->cfg->cb_ctx, sa,
836				      p2p->sd_rx_update_indic,
837				      wpabuf_head(p2p->sd_rx_resp),
838				      wpabuf_len(p2p->sd_rx_resp));
839	wpabuf_free(p2p->sd_rx_resp);
840	p2p->sd_rx_resp = NULL;
841
842	p2p_continue_find(p2p);
843}
844
845
846void * p2p_sd_request(struct p2p_data *p2p, const u8 *dst,
847		      const struct wpabuf *tlvs)
848{
849	struct p2p_sd_query *q;
850
851	q = os_zalloc(sizeof(*q));
852	if (q == NULL)
853		return NULL;
854
855	if (dst)
856		os_memcpy(q->peer, dst, ETH_ALEN);
857	else
858		q->for_all_peers = 1;
859
860	q->tlvs = wpabuf_dup(tlvs);
861	if (q->tlvs == NULL) {
862		p2p_free_sd_query(q);
863		return NULL;
864	}
865
866	q->next = p2p->sd_queries;
867	p2p->sd_queries = q;
868	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Added SD Query %p", q);
869
870	return q;
871}
872
873
874void p2p_sd_service_update(struct p2p_data *p2p)
875{
876	p2p->srv_update_indic++;
877}
878
879
880int p2p_sd_cancel_request(struct p2p_data *p2p, void *req)
881{
882	if (p2p_unlink_sd_query(p2p, req)) {
883		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
884			"P2P: Cancel pending SD query %p", req);
885		p2p_free_sd_query(req);
886		return 0;
887	}
888	return -1;
889}
890