/*
 * P2P - IE builder
 * Copyright (c) 2009-2010, Atheros Communications
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"

#include "common.h"
#include "common/ieee802_11_defs.h"
#include "common/qca-vendor.h"
#include "wps/wps_i.h"
#include "p2p_i.h"


void p2p_buf_add_action_hdr(struct wpabuf *buf, u8 subtype, u8 dialog_token)
{
	wpabuf_put_u8(buf, WLAN_ACTION_VENDOR_SPECIFIC);
	wpabuf_put_be32(buf, P2P_IE_VENDOR_TYPE);

	wpabuf_put_u8(buf, subtype); /* OUI Subtype */
	wpabuf_put_u8(buf, dialog_token);
	wpa_printf(MSG_DEBUG, "P2P: * Dialog Token: %d", dialog_token);
}


void p2p_buf_add_public_action_hdr(struct wpabuf *buf, u8 subtype,
				   u8 dialog_token)
{
	wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
	wpabuf_put_u8(buf, WLAN_PA_VENDOR_SPECIFIC);
	wpabuf_put_be32(buf, P2P_IE_VENDOR_TYPE);

	wpabuf_put_u8(buf, subtype); /* OUI Subtype */
	wpabuf_put_u8(buf, dialog_token);
	wpa_printf(MSG_DEBUG, "P2P: * Dialog Token: %d", dialog_token);
}


u8 * p2p_buf_add_ie_hdr(struct wpabuf *buf)
{
	u8 *len;

	/* P2P IE header */
	wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
	len = wpabuf_put(buf, 1); /* IE length to be filled */
	wpabuf_put_be32(buf, P2P_IE_VENDOR_TYPE);
	wpa_printf(MSG_DEBUG, "P2P: * P2P IE header");
	return len;
}


void p2p_buf_update_ie_hdr(struct wpabuf *buf, u8 *len)
{
	/* Update P2P IE Length */
	*len = (u8 *) wpabuf_put(buf, 0) - len - 1;
}


void p2p_buf_add_capability(struct wpabuf *buf, u8 dev_capab, u8 group_capab)
{
	/* P2P Capability */
	wpabuf_put_u8(buf, P2P_ATTR_CAPABILITY);
	wpabuf_put_le16(buf, 2);
	wpabuf_put_u8(buf, dev_capab); /* Device Capabilities */
	wpabuf_put_u8(buf, group_capab); /* Group Capabilities */
	wpa_printf(MSG_DEBUG, "P2P: * Capability dev=%02x group=%02x",
		   dev_capab, group_capab);
}


void p2p_buf_add_go_intent(struct wpabuf *buf, u8 go_intent)
{
	/* Group Owner Intent */
	wpabuf_put_u8(buf, P2P_ATTR_GROUP_OWNER_INTENT);
	wpabuf_put_le16(buf, 1);
	wpabuf_put_u8(buf, go_intent);
	wpa_printf(MSG_DEBUG, "P2P: * GO Intent: Intent %u Tie breaker %u",
		   go_intent >> 1, go_intent & 0x01);
}


void p2p_buf_add_listen_channel(struct wpabuf *buf, const char *country,
				u8 reg_class, u8 channel)
{
	/* Listen Channel */
	wpabuf_put_u8(buf, P2P_ATTR_LISTEN_CHANNEL);
	wpabuf_put_le16(buf, 5);
	wpabuf_put_data(buf, country, 3);
	wpabuf_put_u8(buf, reg_class); /* Regulatory Class */
	wpabuf_put_u8(buf, channel); /* Channel Number */
	wpa_printf(MSG_DEBUG, "P2P: * Listen Channel: Regulatory Class %u "
		   "Channel %u", reg_class, channel);
}


void p2p_buf_add_operating_channel(struct wpabuf *buf, const char *country,
				   u8 reg_class, u8 channel)
{
	/* Operating Channel */
	wpabuf_put_u8(buf, P2P_ATTR_OPERATING_CHANNEL);
	wpabuf_put_le16(buf, 5);
	wpabuf_put_data(buf, country, 3);
	wpabuf_put_u8(buf, reg_class); /* Regulatory Class */
	wpabuf_put_u8(buf, channel); /* Channel Number */
	wpa_printf(MSG_DEBUG, "P2P: * Operating Channel: Regulatory Class %u "
		   "Channel %u", reg_class, channel);
}


void p2p_buf_add_pref_channel_list(struct wpabuf *buf,
				   const u32 *preferred_freq_list,
				   unsigned int size)
{
	unsigned int i, count = 0;
	u8 op_class, op_channel;

	if (!size)
		return;

	/*
	 * First, determine the number of P2P supported channels in the
	 * pref_freq_list returned from driver. This is needed for calculations
	 * of the vendor IE size.
	 */
	for (i = 0; i < size; i++) {
		if (p2p_freq_to_channel(preferred_freq_list[i], &op_class,
					&op_channel) == 0)
			count++;
	}

	wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
	wpabuf_put_u8(buf, 4 + count * sizeof(u16));
	wpabuf_put_be24(buf, OUI_QCA);
	wpabuf_put_u8(buf, QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST);
	for (i = 0; i < size; i++) {
		if (p2p_freq_to_channel(preferred_freq_list[i], &op_class,
					&op_channel) < 0) {
			wpa_printf(MSG_DEBUG, "Unsupported frequency %u MHz",
				   preferred_freq_list[i]);
			continue;
		}
		wpabuf_put_u8(buf, op_class);
		wpabuf_put_u8(buf, op_channel);
	}
}


void p2p_buf_add_channel_list(struct wpabuf *buf, const char *country,
			      struct p2p_channels *chan)
{
	u8 *len;
	size_t i;

	/* Channel List */
	wpabuf_put_u8(buf, P2P_ATTR_CHANNEL_LIST);
	len = wpabuf_put(buf, 2); /* IE length to be filled */
	wpabuf_put_data(buf, country, 3); /* Country String */

	for (i = 0; i < chan->reg_classes; i++) {
		struct p2p_reg_class *c = &chan->reg_class[i];
		wpabuf_put_u8(buf, c->reg_class);
		wpabuf_put_u8(buf, c->channels);
		wpabuf_put_data(buf, c->channel, c->channels);
	}

	/* Update attribute length */
	WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
	wpa_hexdump(MSG_DEBUG, "P2P: * Channel List",
		    len + 2, (u8 *) wpabuf_put(buf, 0) - len - 2);
}


void p2p_buf_add_status(struct wpabuf *buf, u8 status)
{
	/* Status */
	wpabuf_put_u8(buf, P2P_ATTR_STATUS);
	wpabuf_put_le16(buf, 1);
	wpabuf_put_u8(buf, status);
	wpa_printf(MSG_DEBUG, "P2P: * Status: %d", status);
}


void p2p_buf_add_device_info(struct wpabuf *buf, struct p2p_data *p2p,
			     struct p2p_device *peer)
{
	u8 *len;
	u16 methods;
	size_t nlen, i;

	/* P2P Device Info */
	wpabuf_put_u8(buf, P2P_ATTR_DEVICE_INFO);
	len = wpabuf_put(buf, 2); /* IE length to be filled */

	/* P2P Device address */
	wpabuf_put_data(buf, p2p->cfg->dev_addr, ETH_ALEN);

	/* Config Methods */
	methods = 0;
	if (peer && peer->wps_method != WPS_NOT_READY) {
		if (peer->wps_method == WPS_PBC)
			methods |= WPS_CONFIG_PUSHBUTTON;
		else if (peer->wps_method == WPS_PIN_DISPLAY ||
			 peer->wps_method == WPS_PIN_KEYPAD) {
			methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
			methods |= WPS_CONFIG_P2PS;
		}
	} else if (p2p->cfg->config_methods) {
		methods |= p2p->cfg->config_methods &
			(WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_DISPLAY |
			 WPS_CONFIG_KEYPAD | WPS_CONFIG_P2PS);
	} else {
		methods |= WPS_CONFIG_PUSHBUTTON;
		methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
		methods |= WPS_CONFIG_P2PS;
	}
	wpabuf_put_be16(buf, methods);

	/* Primary Device Type */
	wpabuf_put_data(buf, p2p->cfg->pri_dev_type,
			sizeof(p2p->cfg->pri_dev_type));

	/* Number of Secondary Device Types */
	wpabuf_put_u8(buf, p2p->cfg->num_sec_dev_types);

	/* Secondary Device Type List */
	for (i = 0; i < p2p->cfg->num_sec_dev_types; i++)
		wpabuf_put_data(buf, p2p->cfg->sec_dev_type[i],
				WPS_DEV_TYPE_LEN);

	/* Device Name */
	nlen = p2p->cfg->dev_name ? os_strlen(p2p->cfg->dev_name) : 0;
	wpabuf_put_be16(buf, ATTR_DEV_NAME);
	wpabuf_put_be16(buf, nlen);
	wpabuf_put_data(buf, p2p->cfg->dev_name, nlen);

	/* Update attribute length */
	WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
	wpa_printf(MSG_DEBUG, "P2P: * Device Info");
}


void p2p_buf_add_device_id(struct wpabuf *buf, const u8 *dev_addr)
{
	/* P2P Device ID */
	wpabuf_put_u8(buf, P2P_ATTR_DEVICE_ID);
	wpabuf_put_le16(buf, ETH_ALEN);
	wpabuf_put_data(buf, dev_addr, ETH_ALEN);
	wpa_printf(MSG_DEBUG, "P2P: * Device ID: " MACSTR, MAC2STR(dev_addr));
}


void p2p_buf_add_config_timeout(struct wpabuf *buf, u8 go_timeout,
				u8 client_timeout)
{
	/* Configuration Timeout */
	wpabuf_put_u8(buf, P2P_ATTR_CONFIGURATION_TIMEOUT);
	wpabuf_put_le16(buf, 2);
	wpabuf_put_u8(buf, go_timeout);
	wpabuf_put_u8(buf, client_timeout);
	wpa_printf(MSG_DEBUG, "P2P: * Configuration Timeout: GO %d (*10ms)  "
		   "client %d (*10ms)", go_timeout, client_timeout);
}


void p2p_buf_add_intended_addr(struct wpabuf *buf, const u8 *interface_addr)
{
	/* Intended P2P Interface Address */
	wpabuf_put_u8(buf, P2P_ATTR_INTENDED_INTERFACE_ADDR);
	wpabuf_put_le16(buf, ETH_ALEN);
	wpabuf_put_data(buf, interface_addr, ETH_ALEN);
	wpa_printf(MSG_DEBUG, "P2P: * Intended P2P Interface Address " MACSTR,
		   MAC2STR(interface_addr));
}


void p2p_buf_add_group_bssid(struct wpabuf *buf, const u8 *bssid)
{
	/* P2P Group BSSID */
	wpabuf_put_u8(buf, P2P_ATTR_GROUP_BSSID);
	wpabuf_put_le16(buf, ETH_ALEN);
	wpabuf_put_data(buf, bssid, ETH_ALEN);
	wpa_printf(MSG_DEBUG, "P2P: * P2P Group BSSID " MACSTR,
		   MAC2STR(bssid));
}


void p2p_buf_add_group_id(struct wpabuf *buf, const u8 *dev_addr,
			  const u8 *ssid, size_t ssid_len)
{
	/* P2P Group ID */
	wpabuf_put_u8(buf, P2P_ATTR_GROUP_ID);
	wpabuf_put_le16(buf, ETH_ALEN + ssid_len);
	wpabuf_put_data(buf, dev_addr, ETH_ALEN);
	wpabuf_put_data(buf, ssid, ssid_len);
	wpa_printf(MSG_DEBUG, "P2P: * P2P Group ID " MACSTR,
		   MAC2STR(dev_addr));
	wpa_hexdump_ascii(MSG_DEBUG, "P2P: P2P Group ID SSID", ssid, ssid_len);
}


void p2p_buf_add_invitation_flags(struct wpabuf *buf, u8 flags)
{
	/* Invitation Flags */
	wpabuf_put_u8(buf, P2P_ATTR_INVITATION_FLAGS);
	wpabuf_put_le16(buf, 1);
	wpabuf_put_u8(buf, flags);
	wpa_printf(MSG_DEBUG, "P2P: * Invitation Flags: bitmap 0x%x", flags);
}


static void p2p_buf_add_noa_desc(struct wpabuf *buf, struct p2p_noa_desc *desc)
{
	if (desc == NULL)
		return;

	wpabuf_put_u8(buf, desc->count_type);
	wpabuf_put_le32(buf, desc->duration);
	wpabuf_put_le32(buf, desc->interval);
	wpabuf_put_le32(buf, desc->start_time);
}


void p2p_buf_add_noa(struct wpabuf *buf, u8 noa_index, u8 opp_ps, u8 ctwindow,
		     struct p2p_noa_desc *desc1, struct p2p_noa_desc *desc2)
{
	/* Notice of Absence */
	wpabuf_put_u8(buf, P2P_ATTR_NOTICE_OF_ABSENCE);
	wpabuf_put_le16(buf, 2 + (desc1 ? 13 : 0) + (desc2 ? 13 : 0));
	wpabuf_put_u8(buf, noa_index);
	wpabuf_put_u8(buf, (opp_ps ? 0x80 : 0) | (ctwindow & 0x7f));
	p2p_buf_add_noa_desc(buf, desc1);
	p2p_buf_add_noa_desc(buf, desc2);
	wpa_printf(MSG_DEBUG, "P2P: * Notice of Absence");
}


void p2p_buf_add_ext_listen_timing(struct wpabuf *buf, u16 period,
				   u16 interval)
{
	/* Extended Listen Timing */
	wpabuf_put_u8(buf, P2P_ATTR_EXT_LISTEN_TIMING);
	wpabuf_put_le16(buf, 4);
	wpabuf_put_le16(buf, period);
	wpabuf_put_le16(buf, interval);
	wpa_printf(MSG_DEBUG, "P2P: * Extended Listen Timing (period %u msec  "
		   "interval %u msec)", period, interval);
}


void p2p_buf_add_p2p_interface(struct wpabuf *buf, struct p2p_data *p2p)
{
	/* P2P Interface */
	wpabuf_put_u8(buf, P2P_ATTR_INTERFACE);
	wpabuf_put_le16(buf, ETH_ALEN + 1 + ETH_ALEN);
	/* P2P Device address */
	wpabuf_put_data(buf, p2p->cfg->dev_addr, ETH_ALEN);
	/*
	 * FIX: Fetch interface address list from driver. Do not include
	 * the P2P Device address if it is never used as interface address.
	 */
	/* P2P Interface Address Count */
	wpabuf_put_u8(buf, 1);
	wpabuf_put_data(buf, p2p->cfg->dev_addr, ETH_ALEN);
}


void p2p_buf_add_oob_go_neg_channel(struct wpabuf *buf, const char *country,
				    u8 oper_class, u8 channel,
				    enum p2p_role_indication role)
{
	/* OOB Group Owner Negotiation Channel */
	wpabuf_put_u8(buf, P2P_ATTR_OOB_GO_NEG_CHANNEL);
	wpabuf_put_le16(buf, 6);
	wpabuf_put_data(buf, country, 3);
	wpabuf_put_u8(buf, oper_class); /* Operating Class */
	wpabuf_put_u8(buf, channel); /* Channel Number */
	wpabuf_put_u8(buf, (u8) role); /* Role indication */
	wpa_printf(MSG_DEBUG, "P2P: * OOB GO Negotiation Channel: Operating "
		   "Class %u Channel %u Role %d",
		   oper_class, channel, role);
}


void p2p_buf_add_service_hash(struct wpabuf *buf, struct p2p_data *p2p)
{
	if (!p2p)
		return;

	/* Service Hash */
	wpabuf_put_u8(buf, P2P_ATTR_SERVICE_HASH);
	wpabuf_put_le16(buf, p2p->p2ps_seek_count * P2PS_HASH_LEN);
	wpabuf_put_data(buf, p2p->p2ps_seek_hash,
			p2p->p2ps_seek_count * P2PS_HASH_LEN);
	wpa_hexdump(MSG_DEBUG, "P2P: * Service Hash",
		    p2p->p2ps_seek_hash, p2p->p2ps_seek_count * P2PS_HASH_LEN);
}


void p2p_buf_add_session_info(struct wpabuf *buf, const char *info)
{
	size_t info_len = 0;

	if (info && info[0])
		info_len = os_strlen(info);

	/* Session Information Data Info */
	wpabuf_put_u8(buf, P2P_ATTR_SESSION_INFORMATION_DATA);
	wpabuf_put_le16(buf, (u16) info_len);

	if (info) {
		wpabuf_put_data(buf, info, info_len);
		wpa_printf(MSG_DEBUG, "P2P: * Session Info Data (%s)", info);
	}
}


void p2p_buf_add_connection_capability(struct wpabuf *buf, u8 connection_cap)
{
	/* Connection Capability Info */
	wpabuf_put_u8(buf, P2P_ATTR_CONNECTION_CAPABILITY);
	wpabuf_put_le16(buf, 1);
	wpabuf_put_u8(buf, connection_cap);
	wpa_printf(MSG_DEBUG, "P2P: * Connection Capability: 0x%x",
		   connection_cap);
}


void p2p_buf_add_advertisement_id(struct wpabuf *buf, u32 id, const u8 *mac)
{
	if (!buf || !mac)
		return;

	/* Advertisement ID Info */
	wpabuf_put_u8(buf, P2P_ATTR_ADVERTISEMENT_ID);
	wpabuf_put_le16(buf, (u16) (sizeof(u32) + ETH_ALEN));
	wpabuf_put_le32(buf, id);
	wpabuf_put_data(buf, mac, ETH_ALEN);
	wpa_printf(MSG_DEBUG, "P2P: * Advertisement ID (%x) " MACSTR,
		   id, MAC2STR(mac));
}


static int p2ps_wildcard_hash(struct p2p_data *p2p,
			      const u8 *hash, u8 hash_count)
{
	u8 i;
	const u8 *test = hash;

	for (i = 0; i < hash_count; i++) {
		if (os_memcmp(test, p2p->wild_card_hash, P2PS_HASH_LEN) == 0)
			return 1;
		test += P2PS_HASH_LEN;
	}

	return 0;
}


static int p2p_wfa_service_adv(struct p2p_data *p2p)
{
	struct p2ps_advertisement *adv;

	for (adv = p2p->p2ps_adv_list; adv; adv = adv->next) {
		if (os_strncmp(adv->svc_name, P2PS_WILD_HASH_STR,
			       os_strlen(P2PS_WILD_HASH_STR)) == 0)
			return 1;
	}

	return 0;
}


static int p2p_buf_add_service_info(struct wpabuf *buf, struct p2p_data *p2p,
				    u32 adv_id, u16 config_methods,
				    const char *svc_name, u8 **ie_len, u8 **pos,
				    size_t *total_len, u8 *attr_len)
{
	size_t svc_len;
	size_t remaining;
	size_t info_len;

	p2p_dbg(p2p, "Add service info for %s (adv_id=%u)", svc_name, adv_id);
	svc_len = os_strlen(svc_name);
	info_len = sizeof(adv_id) + sizeof(config_methods) + sizeof(u8) +
		svc_len;

	if (info_len + *total_len > MAX_SVC_ADV_LEN) {
		p2p_dbg(p2p,
			"Unsufficient buffer, failed to add advertised service info");
		return -1;
	}

	if (svc_len > 255) {
		p2p_dbg(p2p,
			"Invalid service name length (%u bytes), failed to add advertised service info",
			(unsigned int) svc_len);
		return -1;
	}

	if (*ie_len) {
		int ie_data_len = (*pos - *ie_len) - 1;

		if (ie_data_len < 0 || ie_data_len > 255) {
			p2p_dbg(p2p,
				"Invalid IE length, failed to add advertised service info");
			return -1;
		}
		remaining = 255 - ie_data_len;
	} else {
		/*
		 * Adding new P2P IE header takes 6 extra bytes:
		 * - 2 byte IE header (1 byte IE id and 1 byte length)
		 * - 4 bytes of IE_VENDOR_TYPE are reduced from 255 below
		 */
		*ie_len = p2p_buf_add_ie_hdr(buf);
		remaining = 255 - 4;
	}

	if (remaining < sizeof(u32) + sizeof(u16) + sizeof(u8)) {
		/*
		 * Split adv_id, config_methods, and svc_name_len between two
		 * IEs.
		 */
		size_t front = remaining;
		size_t back = sizeof(u32) + sizeof(u16) + sizeof(u8) - front;
		u8 holder[sizeof(u32) + sizeof(u16) + sizeof(u8)];

		WPA_PUT_LE32(holder, adv_id);
		WPA_PUT_BE16(&holder[sizeof(u32)], config_methods);
		holder[sizeof(u32) + sizeof(u16)] = svc_len;

		if (front)
			wpabuf_put_data(buf, holder, front);

		p2p_buf_update_ie_hdr(buf, *ie_len);
		*ie_len = p2p_buf_add_ie_hdr(buf);

		wpabuf_put_data(buf, &holder[front], back);
		remaining = 255 - 4 - (sizeof(u32) + sizeof(u16) + sizeof(u8)) -
			back;
	} else {
		wpabuf_put_le32(buf, adv_id);
		wpabuf_put_be16(buf, config_methods);
		wpabuf_put_u8(buf, svc_len);
		remaining -= sizeof(adv_id) + sizeof(config_methods) +
			sizeof(u8);
	}

	if (remaining < svc_len) {
		/* split svc_name between two or three IEs */
		size_t front = remaining;
		size_t back = svc_len - front;

		if (front)
			wpabuf_put_data(buf, svc_name, front);

		p2p_buf_update_ie_hdr(buf, *ie_len);
		*ie_len = p2p_buf_add_ie_hdr(buf);

		/* In rare cases, we must split across 3 attributes */
		if (back > 255 - 4) {
			wpabuf_put_data(buf, &svc_name[front], 255 - 4);
			back -= 255 - 4;
			front += 255 - 4;
			p2p_buf_update_ie_hdr(buf, *ie_len);
			*ie_len = p2p_buf_add_ie_hdr(buf);
		}

		wpabuf_put_data(buf, &svc_name[front], back);
		remaining = 255 - 4 - back;
	} else {
		wpabuf_put_data(buf, svc_name, svc_len);
		remaining -= svc_len;
	}

	p2p_buf_update_ie_hdr(buf, *ie_len);

	/* set *ie_len to NULL if a new IE has to be added on the next call */
	if (!remaining)
		*ie_len = NULL;

	/* set *pos to point to the next byte to update */
	*pos = wpabuf_put(buf, 0);

	*total_len += info_len;
	WPA_PUT_LE16(attr_len, (u16) *total_len);
	return 0;
}


void p2p_buf_add_service_instance(struct wpabuf *buf, struct p2p_data *p2p,
				  u8 hash_count, const u8 *hash,
				  struct p2ps_advertisement *adv_list)
{
	struct p2ps_advertisement *adv;
	int p2ps_wildcard;
	size_t total_len;
	struct wpabuf *tmp_buf = NULL;
	u8 *pos, *attr_len, *ie_len = NULL;

	if (!adv_list || !hash || !hash_count)
		return;

	wpa_hexdump(MSG_DEBUG, "P2PS: Probe Request service hash values",
		    hash, hash_count * P2PS_HASH_LEN);
	p2ps_wildcard = p2ps_wildcard_hash(p2p, hash, hash_count) &&
		p2p_wfa_service_adv(p2p);

	/* Allocate temp buffer, allowing for overflow of 1 instance */
	tmp_buf = wpabuf_alloc(MAX_SVC_ADV_IE_LEN + 256 + P2PS_HASH_LEN);
	if (!tmp_buf)
		return;

	/*
	 * Attribute data can be split into a number of IEs. Start with the
	 * first IE and the attribute headers here.
	 */
	ie_len = p2p_buf_add_ie_hdr(tmp_buf);

	total_len = 0;

	wpabuf_put_u8(tmp_buf, P2P_ATTR_ADVERTISED_SERVICE);
	attr_len = wpabuf_put(tmp_buf, sizeof(u16));
	WPA_PUT_LE16(attr_len, (u16) total_len);
	p2p_buf_update_ie_hdr(tmp_buf, ie_len);
	pos = wpabuf_put(tmp_buf, 0);

	if (p2ps_wildcard) {
		/* org.wi-fi.wfds match found */
		p2p_buf_add_service_info(tmp_buf, p2p, 0, 0, P2PS_WILD_HASH_STR,
					 &ie_len, &pos, &total_len, attr_len);
	}

	/* add advertised service info of matching services */
	for (adv = adv_list; adv && total_len <= MAX_SVC_ADV_LEN;
	     adv = adv->next) {
		const u8 *test = hash;
		u8 i;

		for (i = 0; i < hash_count; i++) {
			/* exact name hash match */
			if (os_memcmp(test, adv->hash, P2PS_HASH_LEN) == 0 &&
			    p2p_buf_add_service_info(tmp_buf, p2p,
						     adv->id,
						     adv->config_methods,
						     adv->svc_name,
						     &ie_len, &pos,
						     &total_len,
						     attr_len))
				break;

			test += P2PS_HASH_LEN;
		}
	}

	if (total_len)
		wpabuf_put_buf(buf, tmp_buf);
	wpabuf_free(tmp_buf);
}


void p2p_buf_add_session_id(struct wpabuf *buf, u32 id, const u8 *mac)
{
	if (!buf || !mac)
		return;

	/* Session ID Info */
	wpabuf_put_u8(buf, P2P_ATTR_SESSION_ID);
	wpabuf_put_le16(buf, (u16) (sizeof(u32) + ETH_ALEN));
	wpabuf_put_le32(buf, id);
	wpabuf_put_data(buf, mac, ETH_ALEN);
	wpa_printf(MSG_DEBUG, "P2P: * Session ID Info (%x) " MACSTR,
		   id, MAC2STR(mac));
}


void p2p_buf_add_feature_capability(struct wpabuf *buf, u16 len, const u8 *mask)
{
	if (!buf || !len || !mask)
		return;

	/* Feature Capability */
	wpabuf_put_u8(buf, P2P_ATTR_FEATURE_CAPABILITY);
	wpabuf_put_le16(buf, len);
	wpabuf_put_data(buf, mask, len);
	wpa_printf(MSG_DEBUG, "P2P: * Feature Capability (%d)", len);
}


void p2p_buf_add_persistent_group_info(struct wpabuf *buf, const u8 *dev_addr,
				       const u8 *ssid, size_t ssid_len)
{
	/* P2P Group ID */
	wpabuf_put_u8(buf, P2P_ATTR_PERSISTENT_GROUP);
	wpabuf_put_le16(buf, ETH_ALEN + ssid_len);
	wpabuf_put_data(buf, dev_addr, ETH_ALEN);
	wpabuf_put_data(buf, ssid, ssid_len);
	wpa_printf(MSG_DEBUG, "P2P: * P2P Group ID " MACSTR,
		   MAC2STR(dev_addr));
}


static int p2p_add_wps_string(struct wpabuf *buf, enum wps_attribute attr,
			      const char *val)
{
	size_t len;

	len = val ? os_strlen(val) : 0;
	if (wpabuf_tailroom(buf) < 4 + len)
		return -1;
	wpabuf_put_be16(buf, attr);
#ifndef CONFIG_WPS_STRICT
	if (len == 0) {
		/*
		 * Some deployed WPS implementations fail to parse zeor-length
		 * attributes. As a workaround, send a space character if the
		 * device attribute string is empty.
		 */
		if (wpabuf_tailroom(buf) < 3)
			return -1;
		wpabuf_put_be16(buf, 1);
		wpabuf_put_u8(buf, ' ');
		return 0;
	}
#endif /* CONFIG_WPS_STRICT */
	wpabuf_put_be16(buf, len);
	if (val)
		wpabuf_put_data(buf, val, len);
	return 0;
}


int p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id,
		     int all_attr)
{
	u8 *len;
	int i;

	if (wpabuf_tailroom(buf) < 6)
		return -1;
	wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
	len = wpabuf_put(buf, 1);
	wpabuf_put_be32(buf, WPS_DEV_OUI_WFA);

	if (wps_build_version(buf) < 0)
		return -1;

	if (all_attr) {
		if (wpabuf_tailroom(buf) < 5)
			return -1;
		wpabuf_put_be16(buf, ATTR_WPS_STATE);
		wpabuf_put_be16(buf, 1);
		wpabuf_put_u8(buf, WPS_STATE_NOT_CONFIGURED);
	}

	if (pw_id >= 0) {
		if (wpabuf_tailroom(buf) < 6)
			return -1;
		/* Device Password ID */
		wpabuf_put_be16(buf, ATTR_DEV_PASSWORD_ID);
		wpabuf_put_be16(buf, 2);
		wpa_printf(MSG_DEBUG, "P2P: WPS IE Device Password ID: %d",
			   pw_id);
		wpabuf_put_be16(buf, pw_id);
	}

	if (all_attr) {
		if (wpabuf_tailroom(buf) < 5)
			return -1;
		wpabuf_put_be16(buf, ATTR_RESPONSE_TYPE);
		wpabuf_put_be16(buf, 1);
		wpabuf_put_u8(buf, WPS_RESP_ENROLLEE_INFO);

		if (wps_build_uuid_e(buf, p2p->cfg->uuid) < 0 ||
		    p2p_add_wps_string(buf, ATTR_MANUFACTURER,
				       p2p->cfg->manufacturer) < 0 ||
		    p2p_add_wps_string(buf, ATTR_MODEL_NAME,
				       p2p->cfg->model_name) < 0 ||
		    p2p_add_wps_string(buf, ATTR_MODEL_NUMBER,
				       p2p->cfg->model_number) < 0 ||
		    p2p_add_wps_string(buf, ATTR_SERIAL_NUMBER,
				       p2p->cfg->serial_number) < 0)
			return -1;

		if (wpabuf_tailroom(buf) < 4 + WPS_DEV_TYPE_LEN)
			return -1;
		wpabuf_put_be16(buf, ATTR_PRIMARY_DEV_TYPE);
		wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN);
		wpabuf_put_data(buf, p2p->cfg->pri_dev_type, WPS_DEV_TYPE_LEN);

		if (p2p_add_wps_string(buf, ATTR_DEV_NAME, p2p->cfg->dev_name)
		    < 0)
			return -1;

		if (wpabuf_tailroom(buf) < 6)
			return -1;
		wpabuf_put_be16(buf, ATTR_CONFIG_METHODS);
		wpabuf_put_be16(buf, 2);
		wpabuf_put_be16(buf, p2p->cfg->config_methods);
	}

	if (wps_build_wfa_ext(buf, 0, NULL, 0) < 0)
		return -1;

	if (all_attr && p2p->cfg->num_sec_dev_types) {
		if (wpabuf_tailroom(buf) <
		    4 + WPS_DEV_TYPE_LEN * p2p->cfg->num_sec_dev_types)
			return -1;
		wpabuf_put_be16(buf, ATTR_SECONDARY_DEV_TYPE_LIST);
		wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN *
				p2p->cfg->num_sec_dev_types);
		wpabuf_put_data(buf, p2p->cfg->sec_dev_type,
				WPS_DEV_TYPE_LEN *
				p2p->cfg->num_sec_dev_types);
	}

	/* Add the WPS vendor extensions */
	for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
		if (p2p->wps_vendor_ext[i] == NULL)
			break;
		if (wpabuf_tailroom(buf) <
		    4 + wpabuf_len(p2p->wps_vendor_ext[i]))
			continue;
		wpabuf_put_be16(buf, ATTR_VENDOR_EXT);
		wpabuf_put_be16(buf, wpabuf_len(p2p->wps_vendor_ext[i]));
		wpabuf_put_buf(buf, p2p->wps_vendor_ext[i]);
	}

	p2p_buf_update_ie_hdr(buf, len);

	return 0;
}
