2 * Wi-Fi Direct - P2P service discovery
3 * Copyright (c) 2009, Atheros Communications
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
18 #include "common/ieee802_11_defs.h"
19 #include "common/gas.h"
24 struct p2p_sd_query
* p2p_pending_sd_req(struct p2p_data
*p2p
,
25 struct p2p_device
*dev
)
27 struct p2p_sd_query
*q
;
29 if (!(dev
->info
.dev_capab
& P2P_DEV_CAPAB_SERVICE_DISCOVERY
))
30 return NULL
; /* peer does not support SD */
32 for (q
= p2p
->sd_queries
; q
; q
= q
->next
) {
33 if (q
->for_all_peers
&& !(dev
->flags
& P2P_DEV_SD_INFO
))
35 if (!q
->for_all_peers
&&
36 os_memcmp(q
->peer
, dev
->info
.p2p_device_addr
, ETH_ALEN
) ==
45 static int p2p_unlink_sd_query(struct p2p_data
*p2p
,
46 struct p2p_sd_query
*query
)
48 struct p2p_sd_query
*q
, *prev
;
56 p2p
->sd_queries
= q
->next
;
57 if (p2p
->sd_query
== query
)
68 static void p2p_free_sd_query(struct p2p_sd_query
*q
)
77 void p2p_free_sd_queries(struct p2p_data
*p2p
)
79 struct p2p_sd_query
*q
, *prev
;
81 p2p
->sd_queries
= NULL
;
85 p2p_free_sd_query(prev
);
90 static struct wpabuf
* p2p_build_sd_query(u16 update_indic
,
96 buf
= gas_anqp_build_initial_req(0, 100 + wpabuf_len(tlvs
));
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
);
108 gas_anqp_set_len(buf
);
114 static void p2p_send_gas_comeback_req(struct p2p_data
*p2p
, const u8
*dst
,
115 u8 dialog_token
, int freq
)
119 req
= gas_build_comeback_req(dialog_token
);
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");
133 static struct wpabuf
* p2p_build_sd_response(u8 dialog_token
, u16 status_code
,
136 const struct wpabuf
*tlvs
)
141 buf
= gas_anqp_build_initial_resp(dialog_token
, status_code
,
143 100 + (tlvs
? wpabuf_len(tlvs
) : 0));
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
);
158 gas_anqp_set_len(buf
);
164 static struct wpabuf
* p2p_build_gas_comeback_resp(u8 dialog_token
,
167 const u8
*data
, size_t len
,
173 buf
= gas_anqp_build_comeback_resp(dialog_token
, status_code
, frag_id
,
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
);
188 wpabuf_put_data(buf
, data
, len
);
189 gas_anqp_set_len(buf
);
195 int p2p_start_sd(struct p2p_data
*p2p
, struct p2p_device
*dev
)
199 struct p2p_sd_query
*query
;
202 freq
= dev
->listen_freq
> 0 ? dev
->listen_freq
: dev
->oper_freq
;
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
));
211 query
= p2p_pending_sd_req(p2p
, dev
);
215 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
216 "P2P: Start Service Discovery with " MACSTR
,
217 MAC2STR(dev
->info
.p2p_device_addr
));
219 req
= p2p_build_sd_query(p2p
->srv_update_indic
, query
->tlvs
);
224 p2p
->sd_query
= query
;
225 p2p
->pending_action_state
= P2P_PENDING_SD
;
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");
241 void p2p_rx_gas_initial_req(struct p2p_data
*p2p
, const u8
*sa
,
242 const u8
*data
, size_t len
, int rx_freq
)
244 const u8
*pos
= data
;
245 const u8
*end
= data
+ len
;
253 if (p2p
->cfg
->sd_request
== NULL
)
259 freq
= p2p_channel_to_freq(p2p
->cfg
->country
,
268 dialog_token
= *pos
++;
269 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
270 "P2P: GAS Initial Request from " MACSTR
" (dialog token %u, "
272 MAC2STR(sa
), dialog_token
, rx_freq
);
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
);
283 if (next
> end
|| slen
< 2) {
284 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
285 "P2P: Invalid IE in GAS Initial Request");
288 pos
++; /* skip QueryRespLenLimit and PAME-BI */
290 if (*pos
!= ACCESS_NETWORK_QUERY_PROTOCOL
) {
291 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
292 "P2P: Unsupported GAS advertisement protocol id %u",
301 slen
= WPA_GET_LE16(pos
);
303 if (pos
+ slen
> end
)
307 /* ANQP Query Request */
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
));
317 slen
= WPA_GET_LE16(pos
);
319 if (pos
+ slen
> end
|| slen
< 3 + 1) {
320 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
321 "P2P: Invalid ANQP Query Request length");
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
));
332 if (*pos
!= P2P_OUI_TYPE
) {
333 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
334 "P2P: Unsupported ANQP vendor type %u", *pos
);
341 update_indic
= WPA_GET_LE16(pos
);
342 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
343 "P2P: Service Update Indicator: %u", update_indic
);
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() */
352 void p2p_sd_response(struct p2p_data
*p2p
, int freq
, const u8
*dst
,
353 u8 dialog_token
, const struct wpabuf
*resp_tlvs
)
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");
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.
369 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: Drop "
370 "previous SD response");
371 wpabuf_free(p2p
->sd_resp
);
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;
378 resp
= p2p_build_sd_response(dialog_token
, WLAN_STATUS_SUCCESS
,
379 1, p2p
->srv_update_indic
, NULL
);
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
);
390 p2p
->pending_action_state
= P2P_NO_PENDING_ACTION
;
391 if (p2p_send_action(p2p
, freq
, dst
, 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");
401 void p2p_rx_gas_initial_resp(struct p2p_data
*p2p
, const u8
*sa
,
402 const u8
*data
, size_t len
, int rx_freq
)
404 const u8
*pos
= data
;
405 const u8
*end
= data
+ len
;
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
));
420 p2p
->cfg
->send_action_done(p2p
->cfg
->cb_ctx
);
421 p2p_clear_timeout(p2p
);
423 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
424 "P2P: Received GAS Initial Response from " MACSTR
" (len=%d)",
425 MAC2STR(sa
), (int) len
);
428 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
429 "P2P: Too short GAS Initial Response frame");
433 dialog_token
= *pos
++;
434 /* TODO: check dialog_token match */
435 status_code
= WPA_GET_LE16(pos
);
437 comeback_delay
= WPA_GET_LE16(pos
);
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
);
443 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
444 "P2P: Service Discovery failed: status code %u",
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",
459 if (next
> end
|| slen
< 2) {
460 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
461 "P2P: Invalid IE in GAS Initial Response");
464 pos
++; /* skip QueryRespLenLimit and PAME-BI */
466 if (*pos
!= ACCESS_NETWORK_QUERY_PROTOCOL
) {
467 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
468 "P2P: Unsupported GAS advertisement protocol id %u",
476 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: Too short Query "
480 slen
= WPA_GET_LE16(pos
);
482 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: Query Response Length: %d",
484 if (pos
+ slen
> end
) {
485 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: Not enough Query "
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
;
500 p2p_send_gas_comeback_req(p2p
, sa
, dialog_token
, rx_freq
);
504 /* ANQP Query Response */
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
));
514 slen
= WPA_GET_LE16(pos
);
516 if (pos
+ slen
> end
|| slen
< 3 + 1) {
517 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
518 "P2P: Invalid ANQP Query Response length");
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
));
529 if (*pos
!= P2P_OUI_TYPE
) {
530 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
531 "P2P: Unsupported ANQP vendor type %u", *pos
);
538 update_indic
= WPA_GET_LE16(pos
);
539 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
540 "P2P: Service Update Indicator: %u", update_indic
);
543 p2p
->sd_peer
->flags
|= P2P_DEV_SD_INFO
;
544 p2p
->sd_peer
->flags
&= ~P2P_DEV_SD_SCHEDULE
;
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",
554 p2p_unlink_sd_query(p2p
, p2p
->sd_query
);
555 p2p_free_sd_query(q
);
557 p2p
->sd_query
= NULL
;
560 if (p2p
->cfg
->sd_response
)
561 p2p
->cfg
->sd_response(p2p
->cfg
->cb_ctx
, sa
, update_indic
,
563 p2p_continue_find(p2p
);
567 void p2p_rx_gas_comeback_req(struct p2p_data
*p2p
, const u8
*sa
,
568 const u8
*data
, size_t len
, int rx_freq
)
575 wpa_hexdump(MSG_DEBUG
, "P2P: RX GAS Comeback Request", data
, len
);
578 dialog_token
= *data
;
579 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: Dialog Token: %u",
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
);
587 if (p2p
->sd_resp
== NULL
) {
588 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: No pending SD "
589 "response fragment available");
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
));
598 frag_len
= wpabuf_len(p2p
->sd_resp
) - p2p
->sd_resp_pos
;
599 if (frag_len
> 1400) {
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
));
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
);
615 p2p
->sd_resp_pos
+= frag_len
;
618 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: %d more bytes "
620 (int) (wpabuf_len(p2p
->sd_resp
) - p2p
->sd_resp_pos
));
622 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: All fragments of "
624 wpabuf_free(p2p
->sd_resp
);
628 p2p
->pending_action_state
= P2P_NO_PENDING_ACTION
;
629 if (p2p_send_action(p2p
, rx_freq
, sa
, 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");
639 void p2p_rx_gas_comeback_resp(struct p2p_data
*p2p
, const u8
*sa
,
640 const u8
*data
, size_t len
, int rx_freq
)
642 const u8
*pos
= data
;
643 const u8
*end
= data
+ len
;
652 wpa_hexdump(MSG_DEBUG
, "P2P: RX GAS Comeback Response", data
, len
);
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
));
661 p2p
->cfg
->send_action_done(p2p
->cfg
->cb_ctx
);
662 p2p_clear_timeout(p2p
);
664 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
665 "P2P: Received GAS Comeback Response from " MACSTR
" (len=%d)",
666 MAC2STR(sa
), (int) len
);
669 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
670 "P2P: Too short GAS Comeback Response frame");
674 dialog_token
= *pos
++;
675 /* TODO: check dialog_token match */
676 status_code
= WPA_GET_LE16(pos
);
678 frag_id
= *pos
& 0x7f;
679 more_frags
= (*pos
& 0x80) >> 7;
681 comeback_delay
= WPA_GET_LE16(pos
);
683 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
684 "P2P: dialog_token=%u status_code=%u frag_id=%d more_frags=%d "
686 dialog_token
, status_code
, frag_id
, more_frags
,
688 /* TODO: check frag_id match */
690 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
691 "P2P: Service Discovery failed: status code %u",
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",
706 if (next
> end
|| slen
< 2) {
707 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
708 "P2P: Invalid IE in GAS Comeback Response");
711 pos
++; /* skip QueryRespLenLimit and PAME-BI */
713 if (*pos
!= ACCESS_NETWORK_QUERY_PROTOCOL
) {
714 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
715 "P2P: Unsupported GAS advertisement protocol id %u",
723 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: Too short Query "
727 slen
= WPA_GET_LE16(pos
);
729 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: Query Response Length: %d",
731 if (pos
+ slen
> end
) {
732 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: Not enough Query "
737 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: No Query Response "
743 if (p2p
->sd_rx_resp
) {
745 * ANQP header is only included in the first fragment; rest of
746 * the fragments start with continue TLVs.
748 goto skip_nqp_header
;
751 /* ANQP Query Response */
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
));
761 slen
= WPA_GET_LE16(pos
);
763 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: ANQP Query Response "
766 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
767 "P2P: Invalid ANQP Query Response length");
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
));
780 if (*pos
!= P2P_OUI_TYPE
) {
781 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
782 "P2P: Unsupported ANQP vendor type %u", *pos
);
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
);
795 if (wpabuf_resize(&p2p
->sd_rx_resp
, end
- pos
) < 0)
797 wpabuf_put_data(p2p
->sd_rx_resp
, pos
, end
- pos
);
798 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: Current SD reassembly "
800 (unsigned int) wpabuf_len(p2p
->sd_rx_resp
));
803 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: More fragments "
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");
813 p2p_send_gas_comeback_req(p2p
, sa
, dialog_token
, rx_freq
);
817 p2p
->sd_peer
->flags
|= P2P_DEV_SD_INFO
;
818 p2p
->sd_peer
->flags
&= ~P2P_DEV_SD_SCHEDULE
;
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",
828 p2p_unlink_sd_query(p2p
, p2p
->sd_query
);
829 p2p_free_sd_query(q
);
831 p2p
->sd_query
= NULL
;
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
;
842 p2p_continue_find(p2p
);
846 void * p2p_sd_request(struct p2p_data
*p2p
, const u8
*dst
,
847 const struct wpabuf
*tlvs
)
849 struct p2p_sd_query
*q
;
851 q
= os_zalloc(sizeof(*q
));
856 os_memcpy(q
->peer
, dst
, ETH_ALEN
);
858 q
->for_all_peers
= 1;
860 q
->tlvs
= wpabuf_dup(tlvs
);
861 if (q
->tlvs
== NULL
) {
862 p2p_free_sd_query(q
);
866 q
->next
= p2p
->sd_queries
;
868 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
, "P2P: Added SD Query %p", q
);
874 void p2p_sd_service_update(struct p2p_data
*p2p
)
876 p2p
->srv_update_indic
++;
880 int p2p_sd_cancel_request(struct p2p_data
*p2p
, void *req
)
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
);