3 * Copyright (c) 2009-2010, Atheros Communications
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
12 #include "common/ieee802_11_defs.h"
13 #include "wps/wps_i.h"
17 void p2p_buf_add_action_hdr(struct wpabuf
*buf
, u8 subtype
, u8 dialog_token
)
19 wpabuf_put_u8(buf
, WLAN_ACTION_VENDOR_SPECIFIC
);
20 wpabuf_put_be32(buf
, P2P_IE_VENDOR_TYPE
);
22 wpabuf_put_u8(buf
, subtype
); /* OUI Subtype */
23 wpabuf_put_u8(buf
, dialog_token
);
24 wpa_printf(MSG_DEBUG
, "P2P: * Dialog Token: %d", dialog_token
);
28 void p2p_buf_add_public_action_hdr(struct wpabuf
*buf
, u8 subtype
,
31 wpabuf_put_u8(buf
, WLAN_ACTION_PUBLIC
);
32 wpabuf_put_u8(buf
, WLAN_PA_VENDOR_SPECIFIC
);
33 wpabuf_put_be32(buf
, P2P_IE_VENDOR_TYPE
);
35 wpabuf_put_u8(buf
, subtype
); /* OUI Subtype */
36 wpabuf_put_u8(buf
, dialog_token
);
37 wpa_printf(MSG_DEBUG
, "P2P: * Dialog Token: %d", dialog_token
);
41 u8
* p2p_buf_add_ie_hdr(struct wpabuf
*buf
)
46 wpabuf_put_u8(buf
, WLAN_EID_VENDOR_SPECIFIC
);
47 len
= wpabuf_put(buf
, 1); /* IE length to be filled */
48 wpabuf_put_be32(buf
, P2P_IE_VENDOR_TYPE
);
49 wpa_printf(MSG_DEBUG
, "P2P: * P2P IE header");
54 void p2p_buf_update_ie_hdr(struct wpabuf
*buf
, u8
*len
)
56 /* Update P2P IE Length */
57 *len
= (u8
*) wpabuf_put(buf
, 0) - len
- 1;
61 void p2p_buf_add_capability(struct wpabuf
*buf
, u8 dev_capab
, u8 group_capab
)
64 wpabuf_put_u8(buf
, P2P_ATTR_CAPABILITY
);
65 wpabuf_put_le16(buf
, 2);
66 wpabuf_put_u8(buf
, dev_capab
); /* Device Capabilities */
67 wpabuf_put_u8(buf
, group_capab
); /* Group Capabilities */
68 wpa_printf(MSG_DEBUG
, "P2P: * Capability dev=%02x group=%02x",
69 dev_capab
, group_capab
);
73 void p2p_buf_add_go_intent(struct wpabuf
*buf
, u8 go_intent
)
75 /* Group Owner Intent */
76 wpabuf_put_u8(buf
, P2P_ATTR_GROUP_OWNER_INTENT
);
77 wpabuf_put_le16(buf
, 1);
78 wpabuf_put_u8(buf
, go_intent
);
79 wpa_printf(MSG_DEBUG
, "P2P: * GO Intent: Intent %u Tie breaker %u",
80 go_intent
>> 1, go_intent
& 0x01);
84 void p2p_buf_add_listen_channel(struct wpabuf
*buf
, const char *country
,
85 u8 reg_class
, u8 channel
)
88 wpabuf_put_u8(buf
, P2P_ATTR_LISTEN_CHANNEL
);
89 wpabuf_put_le16(buf
, 5);
90 wpabuf_put_data(buf
, country
, 3);
91 wpabuf_put_u8(buf
, reg_class
); /* Regulatory Class */
92 wpabuf_put_u8(buf
, channel
); /* Channel Number */
93 wpa_printf(MSG_DEBUG
, "P2P: * Listen Channel: Regulatory Class %u "
94 "Channel %u", reg_class
, channel
);
98 void p2p_buf_add_operating_channel(struct wpabuf
*buf
, const char *country
,
99 u8 reg_class
, u8 channel
)
101 /* Operating Channel */
102 wpabuf_put_u8(buf
, P2P_ATTR_OPERATING_CHANNEL
);
103 wpabuf_put_le16(buf
, 5);
104 wpabuf_put_data(buf
, country
, 3);
105 wpabuf_put_u8(buf
, reg_class
); /* Regulatory Class */
106 wpabuf_put_u8(buf
, channel
); /* Channel Number */
107 wpa_printf(MSG_DEBUG
, "P2P: * Operating Channel: Regulatory Class %u "
108 "Channel %u", reg_class
, channel
);
112 void p2p_buf_add_channel_list(struct wpabuf
*buf
, const char *country
,
113 struct p2p_channels
*chan
)
119 wpabuf_put_u8(buf
, P2P_ATTR_CHANNEL_LIST
);
120 len
= wpabuf_put(buf
, 2); /* IE length to be filled */
121 wpabuf_put_data(buf
, country
, 3); /* Country String */
123 for (i
= 0; i
< chan
->reg_classes
; i
++) {
124 struct p2p_reg_class
*c
= &chan
->reg_class
[i
];
125 wpabuf_put_u8(buf
, c
->reg_class
);
126 wpabuf_put_u8(buf
, c
->channels
);
127 wpabuf_put_data(buf
, c
->channel
, c
->channels
);
130 /* Update attribute length */
131 WPA_PUT_LE16(len
, (u8
*) wpabuf_put(buf
, 0) - len
- 2);
132 wpa_hexdump(MSG_DEBUG
, "P2P: * Channel List",
133 len
+ 2, (u8
*) wpabuf_put(buf
, 0) - len
- 2);
137 void p2p_buf_add_status(struct wpabuf
*buf
, u8 status
)
140 wpabuf_put_u8(buf
, P2P_ATTR_STATUS
);
141 wpabuf_put_le16(buf
, 1);
142 wpabuf_put_u8(buf
, status
);
143 wpa_printf(MSG_DEBUG
, "P2P: * Status: %d", status
);
147 void p2p_buf_add_device_info(struct wpabuf
*buf
, struct p2p_data
*p2p
,
148 struct p2p_device
*peer
)
154 /* P2P Device Info */
155 wpabuf_put_u8(buf
, P2P_ATTR_DEVICE_INFO
);
156 len
= wpabuf_put(buf
, 2); /* IE length to be filled */
158 /* P2P Device address */
159 wpabuf_put_data(buf
, p2p
->cfg
->dev_addr
, ETH_ALEN
);
163 if (peer
&& peer
->wps_method
!= WPS_NOT_READY
) {
164 if (peer
->wps_method
== WPS_PBC
)
165 methods
|= WPS_CONFIG_PUSHBUTTON
;
166 else if (peer
->wps_method
== WPS_PIN_DISPLAY
||
167 peer
->wps_method
== WPS_PIN_KEYPAD
) {
168 methods
|= WPS_CONFIG_DISPLAY
| WPS_CONFIG_KEYPAD
;
169 methods
|= WPS_CONFIG_P2PS
;
171 } else if (p2p
->cfg
->config_methods
) {
172 methods
|= p2p
->cfg
->config_methods
&
173 (WPS_CONFIG_PUSHBUTTON
| WPS_CONFIG_DISPLAY
|
174 WPS_CONFIG_KEYPAD
| WPS_CONFIG_P2PS
);
176 methods
|= WPS_CONFIG_PUSHBUTTON
;
177 methods
|= WPS_CONFIG_DISPLAY
| WPS_CONFIG_KEYPAD
;
178 methods
|= WPS_CONFIG_P2PS
;
180 wpabuf_put_be16(buf
, methods
);
182 /* Primary Device Type */
183 wpabuf_put_data(buf
, p2p
->cfg
->pri_dev_type
,
184 sizeof(p2p
->cfg
->pri_dev_type
));
186 /* Number of Secondary Device Types */
187 wpabuf_put_u8(buf
, p2p
->cfg
->num_sec_dev_types
);
189 /* Secondary Device Type List */
190 for (i
= 0; i
< p2p
->cfg
->num_sec_dev_types
; i
++)
191 wpabuf_put_data(buf
, p2p
->cfg
->sec_dev_type
[i
],
195 nlen
= p2p
->cfg
->dev_name
? os_strlen(p2p
->cfg
->dev_name
) : 0;
196 wpabuf_put_be16(buf
, ATTR_DEV_NAME
);
197 wpabuf_put_be16(buf
, nlen
);
198 wpabuf_put_data(buf
, p2p
->cfg
->dev_name
, nlen
);
200 /* Update attribute length */
201 WPA_PUT_LE16(len
, (u8
*) wpabuf_put(buf
, 0) - len
- 2);
202 wpa_printf(MSG_DEBUG
, "P2P: * Device Info");
206 void p2p_buf_add_device_id(struct wpabuf
*buf
, const u8
*dev_addr
)
209 wpabuf_put_u8(buf
, P2P_ATTR_DEVICE_ID
);
210 wpabuf_put_le16(buf
, ETH_ALEN
);
211 wpabuf_put_data(buf
, dev_addr
, ETH_ALEN
);
212 wpa_printf(MSG_DEBUG
, "P2P: * Device ID: " MACSTR
, MAC2STR(dev_addr
));
216 void p2p_buf_add_config_timeout(struct wpabuf
*buf
, u8 go_timeout
,
219 /* Configuration Timeout */
220 wpabuf_put_u8(buf
, P2P_ATTR_CONFIGURATION_TIMEOUT
);
221 wpabuf_put_le16(buf
, 2);
222 wpabuf_put_u8(buf
, go_timeout
);
223 wpabuf_put_u8(buf
, client_timeout
);
224 wpa_printf(MSG_DEBUG
, "P2P: * Configuration Timeout: GO %d (*10ms) "
225 "client %d (*10ms)", go_timeout
, client_timeout
);
229 void p2p_buf_add_intended_addr(struct wpabuf
*buf
, const u8
*interface_addr
)
231 /* Intended P2P Interface Address */
232 wpabuf_put_u8(buf
, P2P_ATTR_INTENDED_INTERFACE_ADDR
);
233 wpabuf_put_le16(buf
, ETH_ALEN
);
234 wpabuf_put_data(buf
, interface_addr
, ETH_ALEN
);
235 wpa_printf(MSG_DEBUG
, "P2P: * Intended P2P Interface Address " MACSTR
,
236 MAC2STR(interface_addr
));
240 void p2p_buf_add_group_bssid(struct wpabuf
*buf
, const u8
*bssid
)
242 /* P2P Group BSSID */
243 wpabuf_put_u8(buf
, P2P_ATTR_GROUP_BSSID
);
244 wpabuf_put_le16(buf
, ETH_ALEN
);
245 wpabuf_put_data(buf
, bssid
, ETH_ALEN
);
246 wpa_printf(MSG_DEBUG
, "P2P: * P2P Group BSSID " MACSTR
,
251 void p2p_buf_add_group_id(struct wpabuf
*buf
, const u8
*dev_addr
,
252 const u8
*ssid
, size_t ssid_len
)
255 wpabuf_put_u8(buf
, P2P_ATTR_GROUP_ID
);
256 wpabuf_put_le16(buf
, ETH_ALEN
+ ssid_len
);
257 wpabuf_put_data(buf
, dev_addr
, ETH_ALEN
);
258 wpabuf_put_data(buf
, ssid
, ssid_len
);
259 wpa_printf(MSG_DEBUG
, "P2P: * P2P Group ID " MACSTR
,
261 wpa_hexdump_ascii(MSG_DEBUG
, "P2P: P2P Group ID SSID", ssid
, ssid_len
);
265 void p2p_buf_add_invitation_flags(struct wpabuf
*buf
, u8 flags
)
267 /* Invitation Flags */
268 wpabuf_put_u8(buf
, P2P_ATTR_INVITATION_FLAGS
);
269 wpabuf_put_le16(buf
, 1);
270 wpabuf_put_u8(buf
, flags
);
271 wpa_printf(MSG_DEBUG
, "P2P: * Invitation Flags: bitmap 0x%x", flags
);
275 static void p2p_buf_add_noa_desc(struct wpabuf
*buf
, struct p2p_noa_desc
*desc
)
280 wpabuf_put_u8(buf
, desc
->count_type
);
281 wpabuf_put_le32(buf
, desc
->duration
);
282 wpabuf_put_le32(buf
, desc
->interval
);
283 wpabuf_put_le32(buf
, desc
->start_time
);
287 void p2p_buf_add_noa(struct wpabuf
*buf
, u8 noa_index
, u8 opp_ps
, u8 ctwindow
,
288 struct p2p_noa_desc
*desc1
, struct p2p_noa_desc
*desc2
)
290 /* Notice of Absence */
291 wpabuf_put_u8(buf
, P2P_ATTR_NOTICE_OF_ABSENCE
);
292 wpabuf_put_le16(buf
, 2 + (desc1
? 13 : 0) + (desc2
? 13 : 0));
293 wpabuf_put_u8(buf
, noa_index
);
294 wpabuf_put_u8(buf
, (opp_ps
? 0x80 : 0) | (ctwindow
& 0x7f));
295 p2p_buf_add_noa_desc(buf
, desc1
);
296 p2p_buf_add_noa_desc(buf
, desc2
);
297 wpa_printf(MSG_DEBUG
, "P2P: * Notice of Absence");
301 void p2p_buf_add_ext_listen_timing(struct wpabuf
*buf
, u16 period
,
304 /* Extended Listen Timing */
305 wpabuf_put_u8(buf
, P2P_ATTR_EXT_LISTEN_TIMING
);
306 wpabuf_put_le16(buf
, 4);
307 wpabuf_put_le16(buf
, period
);
308 wpabuf_put_le16(buf
, interval
);
309 wpa_printf(MSG_DEBUG
, "P2P: * Extended Listen Timing (period %u msec "
310 "interval %u msec)", period
, interval
);
314 void p2p_buf_add_p2p_interface(struct wpabuf
*buf
, struct p2p_data
*p2p
)
317 wpabuf_put_u8(buf
, P2P_ATTR_INTERFACE
);
318 wpabuf_put_le16(buf
, ETH_ALEN
+ 1 + ETH_ALEN
);
319 /* P2P Device address */
320 wpabuf_put_data(buf
, p2p
->cfg
->dev_addr
, ETH_ALEN
);
322 * FIX: Fetch interface address list from driver. Do not include
323 * the P2P Device address if it is never used as interface address.
325 /* P2P Interface Address Count */
326 wpabuf_put_u8(buf
, 1);
327 wpabuf_put_data(buf
, p2p
->cfg
->dev_addr
, ETH_ALEN
);
331 void p2p_buf_add_oob_go_neg_channel(struct wpabuf
*buf
, const char *country
,
332 u8 oper_class
, u8 channel
,
333 enum p2p_role_indication role
)
335 /* OOB Group Owner Negotiation Channel */
336 wpabuf_put_u8(buf
, P2P_ATTR_OOB_GO_NEG_CHANNEL
);
337 wpabuf_put_le16(buf
, 6);
338 wpabuf_put_data(buf
, country
, 3);
339 wpabuf_put_u8(buf
, oper_class
); /* Operating Class */
340 wpabuf_put_u8(buf
, channel
); /* Channel Number */
341 wpabuf_put_u8(buf
, (u8
) role
); /* Role indication */
342 wpa_printf(MSG_DEBUG
, "P2P: * OOB GO Negotiation Channel: Operating "
343 "Class %u Channel %u Role %d",
344 oper_class
, channel
, role
);
348 void p2p_buf_add_service_hash(struct wpabuf
*buf
, struct p2p_data
*p2p
)
354 wpabuf_put_u8(buf
, P2P_ATTR_SERVICE_HASH
);
355 wpabuf_put_le16(buf
, p2p
->p2ps_seek_count
* P2PS_HASH_LEN
);
356 wpabuf_put_data(buf
, p2p
->p2ps_seek_hash
,
357 p2p
->p2ps_seek_count
* P2PS_HASH_LEN
);
358 wpa_hexdump(MSG_DEBUG
, "P2P: * Service Hash",
359 p2p
->p2ps_seek_hash
, p2p
->p2ps_seek_count
* P2PS_HASH_LEN
);
363 void p2p_buf_add_session_info(struct wpabuf
*buf
, const char *info
)
368 info_len
= os_strlen(info
);
370 /* Session Information Data Info */
371 wpabuf_put_u8(buf
, P2P_ATTR_SESSION_INFORMATION_DATA
);
372 wpabuf_put_le16(buf
, (u16
) info_len
);
375 wpabuf_put_data(buf
, info
, info_len
);
376 wpa_printf(MSG_DEBUG
, "P2P: * Session Info Data (%s)", info
);
381 void p2p_buf_add_connection_capability(struct wpabuf
*buf
, u8 connection_cap
)
383 /* Connection Capability Info */
384 wpabuf_put_u8(buf
, P2P_ATTR_CONNECTION_CAPABILITY
);
385 wpabuf_put_le16(buf
, 1);
386 wpabuf_put_u8(buf
, connection_cap
);
387 wpa_printf(MSG_DEBUG
, "P2P: * Connection Capability: 0x%x",
392 void p2p_buf_add_advertisement_id(struct wpabuf
*buf
, u32 id
, const u8
*mac
)
397 /* Advertisement ID Info */
398 wpabuf_put_u8(buf
, P2P_ATTR_ADVERTISEMENT_ID
);
399 wpabuf_put_le16(buf
, (u16
) (sizeof(u32
) + ETH_ALEN
));
400 wpabuf_put_le32(buf
, id
);
401 wpabuf_put_data(buf
, mac
, ETH_ALEN
);
402 wpa_printf(MSG_DEBUG
, "P2P: * Advertisement ID (%x) " MACSTR
,
407 static int p2ps_wildcard_hash(struct p2p_data
*p2p
,
408 const u8
*hash
, u8 hash_count
)
411 const u8
*test
= hash
;
413 for (i
= 0; i
< hash_count
; i
++) {
414 if (os_memcmp(test
, p2p
->wild_card_hash
, P2PS_HASH_LEN
) == 0)
416 test
+= P2PS_HASH_LEN
;
423 static int p2p_wfa_service_adv(struct p2p_data
*p2p
)
425 struct p2ps_advertisement
*adv
;
427 for (adv
= p2p
->p2ps_adv_list
; adv
; adv
= adv
->next
) {
428 if (os_strncmp(adv
->svc_name
, P2PS_WILD_HASH_STR
,
429 os_strlen(P2PS_WILD_HASH_STR
)) == 0)
437 static int p2p_buf_add_service_info(struct wpabuf
*buf
, struct p2p_data
*p2p
,
438 u32 adv_id
, u16 config_methods
,
439 const char *svc_name
, u8
**ie_len
, u8
**pos
,
440 size_t *total_len
, u8
*attr_len
)
446 p2p_dbg(p2p
, "Add service info for %s (adv_id=%u)", svc_name
, adv_id
);
447 svc_len
= os_strlen(svc_name
);
448 info_len
= sizeof(adv_id
) + sizeof(config_methods
) + sizeof(u8
) +
451 if (info_len
+ *total_len
> MAX_SVC_ADV_LEN
) {
453 "Unsufficient buffer, failed to add advertised service info");
459 "Invalid service name length (%u bytes), failed to add advertised service info",
460 (unsigned int) svc_len
);
465 int ie_data_len
= (*pos
- *ie_len
) - 1;
467 if (ie_data_len
< 0 || ie_data_len
> 255) {
469 "Invalid IE length, failed to add advertised service info");
472 remaining
= 255 - ie_data_len
;
475 * Adding new P2P IE header takes 6 extra bytes:
476 * - 2 byte IE header (1 byte IE id and 1 byte length)
477 * - 4 bytes of IE_VENDOR_TYPE are reduced from 255 below
479 *ie_len
= p2p_buf_add_ie_hdr(buf
);
483 if (remaining
< sizeof(u32
) + sizeof(u16
) + sizeof(u8
)) {
485 * Split adv_id, config_methods, and svc_name_len between two
488 size_t front
= remaining
;
489 size_t back
= sizeof(u32
) + sizeof(u16
) + sizeof(u8
) - front
;
490 u8 holder
[sizeof(u32
) + sizeof(u16
) + sizeof(u8
)];
492 WPA_PUT_LE32(holder
, adv_id
);
493 WPA_PUT_BE16(&holder
[sizeof(u32
)], config_methods
);
494 holder
[sizeof(u32
) + sizeof(u16
)] = svc_len
;
497 wpabuf_put_data(buf
, holder
, front
);
499 p2p_buf_update_ie_hdr(buf
, *ie_len
);
500 *ie_len
= p2p_buf_add_ie_hdr(buf
);
502 wpabuf_put_data(buf
, &holder
[front
], back
);
503 remaining
= 255 - 4 - (sizeof(u32
) + sizeof(u16
) + sizeof(u8
)) -
506 wpabuf_put_le32(buf
, adv_id
);
507 wpabuf_put_be16(buf
, config_methods
);
508 wpabuf_put_u8(buf
, svc_len
);
509 remaining
-= sizeof(adv_id
) + sizeof(config_methods
) +
513 if (remaining
< svc_len
) {
514 /* split svc_name between two or three IEs */
515 size_t front
= remaining
;
516 size_t back
= svc_len
- front
;
519 wpabuf_put_data(buf
, svc_name
, front
);
521 p2p_buf_update_ie_hdr(buf
, *ie_len
);
522 *ie_len
= p2p_buf_add_ie_hdr(buf
);
524 /* In rare cases, we must split across 3 attributes */
525 if (back
> 255 - 4) {
526 wpabuf_put_data(buf
, &svc_name
[front
], 255 - 4);
529 p2p_buf_update_ie_hdr(buf
, *ie_len
);
530 *ie_len
= p2p_buf_add_ie_hdr(buf
);
533 wpabuf_put_data(buf
, &svc_name
[front
], back
);
534 remaining
= 255 - 4 - back
;
536 wpabuf_put_data(buf
, svc_name
, svc_len
);
537 remaining
-= svc_len
;
540 p2p_buf_update_ie_hdr(buf
, *ie_len
);
542 /* set *ie_len to NULL if a new IE has to be added on the next call */
546 /* set *pos to point to the next byte to update */
547 *pos
= wpabuf_put(buf
, 0);
549 *total_len
+= info_len
;
550 WPA_PUT_LE16(attr_len
, (u16
) *total_len
);
555 void p2p_buf_add_service_instance(struct wpabuf
*buf
, struct p2p_data
*p2p
,
556 u8 hash_count
, const u8
*hash
,
557 struct p2ps_advertisement
*adv_list
)
559 struct p2ps_advertisement
*adv
;
562 struct wpabuf
*tmp_buf
= NULL
;
563 u8
*pos
, *attr_len
, *ie_len
= NULL
;
565 if (!adv_list
|| !hash
|| !hash_count
)
568 wpa_hexdump(MSG_DEBUG
, "P2PS: Probe Request service hash values",
569 hash
, hash_count
* P2PS_HASH_LEN
);
570 p2ps_wildcard
= p2ps_wildcard_hash(p2p
, hash
, hash_count
) &&
571 p2p_wfa_service_adv(p2p
);
573 /* Allocate temp buffer, allowing for overflow of 1 instance */
574 tmp_buf
= wpabuf_alloc(MAX_SVC_ADV_IE_LEN
+ 256 + P2PS_HASH_LEN
);
579 * Attribute data can be split into a number of IEs. Start with the
580 * first IE and the attribute headers here.
582 ie_len
= p2p_buf_add_ie_hdr(tmp_buf
);
586 wpabuf_put_u8(tmp_buf
, P2P_ATTR_ADVERTISED_SERVICE
);
587 attr_len
= wpabuf_put(tmp_buf
, sizeof(u16
));
588 WPA_PUT_LE16(attr_len
, (u16
) total_len
);
589 p2p_buf_update_ie_hdr(tmp_buf
, ie_len
);
590 pos
= wpabuf_put(tmp_buf
, 0);
593 p2p_buf_add_service_info(tmp_buf
, p2p
, 0, 0, P2PS_WILD_HASH_STR
,
594 &ie_len
, &pos
, &total_len
, attr_len
);
598 /* add advertised service info of matching services */
599 for (adv
= adv_list
; adv
&& total_len
<= MAX_SVC_ADV_LEN
;
601 const u8
*test
= hash
;
604 for (i
= 0; i
< hash_count
; i
++) {
605 /* exact name hash match */
606 if (os_memcmp(test
, adv
->hash
, P2PS_HASH_LEN
) == 0 &&
607 p2p_buf_add_service_info(tmp_buf
, p2p
,
615 * We cannot return all services matching
616 * the Probe Request frame hash attribute. In
617 * this case, drop currently written entries and
618 * return only a single wildcard advertised
619 * service info in the Probe Response frame.
624 test
+= P2PS_HASH_LEN
;
631 * Add a single attribute with P2PS wildcard if we failed
632 * to add at least one matching advertisement.
634 ie_len
= p2p_buf_add_ie_hdr(buf
);
635 wpabuf_put_u8(buf
, P2P_ATTR_ADVERTISED_SERVICE
);
636 attr_len
= wpabuf_put(buf
, sizeof(u16
));
637 pos
= wpabuf_put(buf
, 0);
640 p2p_buf_add_service_info(buf
, p2p
,
641 0, 0, P2PS_WILD_HASH_STR
,
642 &ie_len
, &pos
, &total_len
, attr_len
);
643 } else if (tmp_buf
) {
645 * TODO: An empty attribute is returned if a device is not able
646 * to match advertised services. The P2PS specification defines
647 * that if the device is not a GO it shall not send a P2PS
648 * related Probe Response frame in this case.
650 wpabuf_put_buf(buf
, tmp_buf
);
653 wpabuf_free(tmp_buf
);
657 void p2p_buf_add_session_id(struct wpabuf
*buf
, u32 id
, const u8
*mac
)
662 /* Session ID Info */
663 wpabuf_put_u8(buf
, P2P_ATTR_SESSION_ID
);
664 wpabuf_put_le16(buf
, (u16
) (sizeof(u32
) + ETH_ALEN
));
665 wpabuf_put_le32(buf
, id
);
666 wpabuf_put_data(buf
, mac
, ETH_ALEN
);
667 wpa_printf(MSG_DEBUG
, "P2P: * Session ID Info (%x) " MACSTR
,
672 void p2p_buf_add_feature_capability(struct wpabuf
*buf
, u16 len
, const u8
*mask
)
674 if (!buf
|| !len
|| !mask
)
677 /* Feature Capability */
678 wpabuf_put_u8(buf
, P2P_ATTR_FEATURE_CAPABILITY
);
679 wpabuf_put_le16(buf
, len
);
680 wpabuf_put_data(buf
, mask
, len
);
681 wpa_printf(MSG_DEBUG
, "P2P: * Feature Capability (%d)", len
);
685 void p2p_buf_add_persistent_group_info(struct wpabuf
*buf
, const u8
*dev_addr
,
686 const u8
*ssid
, size_t ssid_len
)
689 wpabuf_put_u8(buf
, P2P_ATTR_PERSISTENT_GROUP
);
690 wpabuf_put_le16(buf
, ETH_ALEN
+ ssid_len
);
691 wpabuf_put_data(buf
, dev_addr
, ETH_ALEN
);
692 wpabuf_put_data(buf
, ssid
, ssid_len
);
693 wpa_printf(MSG_DEBUG
, "P2P: * P2P Group ID " MACSTR
,
698 static int p2p_add_wps_string(struct wpabuf
*buf
, enum wps_attribute attr
,
703 len
= val
? os_strlen(val
) : 0;
704 if (wpabuf_tailroom(buf
) < 4 + len
)
706 wpabuf_put_be16(buf
, attr
);
707 #ifndef CONFIG_WPS_STRICT
710 * Some deployed WPS implementations fail to parse zeor-length
711 * attributes. As a workaround, send a space character if the
712 * device attribute string is empty.
714 if (wpabuf_tailroom(buf
) < 3)
716 wpabuf_put_be16(buf
, 1);
717 wpabuf_put_u8(buf
, ' ');
720 #endif /* CONFIG_WPS_STRICT */
721 wpabuf_put_be16(buf
, len
);
723 wpabuf_put_data(buf
, val
, len
);
728 int p2p_build_wps_ie(struct p2p_data
*p2p
, struct wpabuf
*buf
, int pw_id
,
734 if (wpabuf_tailroom(buf
) < 6)
736 wpabuf_put_u8(buf
, WLAN_EID_VENDOR_SPECIFIC
);
737 len
= wpabuf_put(buf
, 1);
738 wpabuf_put_be32(buf
, WPS_DEV_OUI_WFA
);
740 if (wps_build_version(buf
) < 0)
744 if (wpabuf_tailroom(buf
) < 5)
746 wpabuf_put_be16(buf
, ATTR_WPS_STATE
);
747 wpabuf_put_be16(buf
, 1);
748 wpabuf_put_u8(buf
, WPS_STATE_NOT_CONFIGURED
);
752 if (wpabuf_tailroom(buf
) < 6)
754 /* Device Password ID */
755 wpabuf_put_be16(buf
, ATTR_DEV_PASSWORD_ID
);
756 wpabuf_put_be16(buf
, 2);
757 wpa_printf(MSG_DEBUG
, "P2P: WPS IE Device Password ID: %d",
759 wpabuf_put_be16(buf
, pw_id
);
763 if (wpabuf_tailroom(buf
) < 5)
765 wpabuf_put_be16(buf
, ATTR_RESPONSE_TYPE
);
766 wpabuf_put_be16(buf
, 1);
767 wpabuf_put_u8(buf
, WPS_RESP_ENROLLEE_INFO
);
769 if (wps_build_uuid_e(buf
, p2p
->cfg
->uuid
) < 0 ||
770 p2p_add_wps_string(buf
, ATTR_MANUFACTURER
,
771 p2p
->cfg
->manufacturer
) < 0 ||
772 p2p_add_wps_string(buf
, ATTR_MODEL_NAME
,
773 p2p
->cfg
->model_name
) < 0 ||
774 p2p_add_wps_string(buf
, ATTR_MODEL_NUMBER
,
775 p2p
->cfg
->model_number
) < 0 ||
776 p2p_add_wps_string(buf
, ATTR_SERIAL_NUMBER
,
777 p2p
->cfg
->serial_number
) < 0)
780 if (wpabuf_tailroom(buf
) < 4 + WPS_DEV_TYPE_LEN
)
782 wpabuf_put_be16(buf
, ATTR_PRIMARY_DEV_TYPE
);
783 wpabuf_put_be16(buf
, WPS_DEV_TYPE_LEN
);
784 wpabuf_put_data(buf
, p2p
->cfg
->pri_dev_type
, WPS_DEV_TYPE_LEN
);
786 if (p2p_add_wps_string(buf
, ATTR_DEV_NAME
, p2p
->cfg
->dev_name
)
790 if (wpabuf_tailroom(buf
) < 6)
792 wpabuf_put_be16(buf
, ATTR_CONFIG_METHODS
);
793 wpabuf_put_be16(buf
, 2);
794 wpabuf_put_be16(buf
, p2p
->cfg
->config_methods
);
797 if (wps_build_wfa_ext(buf
, 0, NULL
, 0) < 0)
800 if (all_attr
&& p2p
->cfg
->num_sec_dev_types
) {
801 if (wpabuf_tailroom(buf
) <
802 4 + WPS_DEV_TYPE_LEN
* p2p
->cfg
->num_sec_dev_types
)
804 wpabuf_put_be16(buf
, ATTR_SECONDARY_DEV_TYPE_LIST
);
805 wpabuf_put_be16(buf
, WPS_DEV_TYPE_LEN
*
806 p2p
->cfg
->num_sec_dev_types
);
807 wpabuf_put_data(buf
, p2p
->cfg
->sec_dev_type
,
809 p2p
->cfg
->num_sec_dev_types
);
812 /* Add the WPS vendor extensions */
813 for (i
= 0; i
< P2P_MAX_WPS_VENDOR_EXT
; i
++) {
814 if (p2p
->wps_vendor_ext
[i
] == NULL
)
816 if (wpabuf_tailroom(buf
) <
817 4 + wpabuf_len(p2p
->wps_vendor_ext
[i
]))
819 wpabuf_put_be16(buf
, ATTR_VENDOR_EXT
);
820 wpabuf_put_be16(buf
, wpabuf_len(p2p
->wps_vendor_ext
[i
]));
821 wpabuf_put_buf(buf
, p2p
->wps_vendor_ext
[i
]);
824 p2p_buf_update_ie_hdr(buf
, len
);