/*
 * Generic advertisement service (GAS) server
 * Copyright (c) 2011-2014, Qualcomm Atheros, Inc.
 *
 * 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/gas.h"
#include "common/wpa_ctrl.h"
#include "utils/eloop.h"
#include "hostapd.h"
#include "ap_config.h"
#include "ap_drv_ops.h"
#include "dpp_hostapd.h"
#include "sta_info.h"
#include "gas_serv.h"


#ifdef CONFIG_DPP
static void gas_serv_write_dpp_adv_proto(struct wpabuf *buf)
{
	wpabuf_put_u8(buf, WLAN_EID_ADV_PROTO);
	wpabuf_put_u8(buf, 8); /* Length */
	wpabuf_put_u8(buf, 0x7f);
	wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
	wpabuf_put_u8(buf, 5);
	wpabuf_put_be24(buf, OUI_WFA);
	wpabuf_put_u8(buf, DPP_OUI_TYPE);
	wpabuf_put_u8(buf, 0x01);
}
#endif /* CONFIG_DPP */


static void convert_to_protected_dual(struct wpabuf *msg)
{
	u8 *categ = wpabuf_mhead_u8(msg);
	*categ = WLAN_ACTION_PROTECTED_DUAL;
}


static struct gas_dialog_info *
gas_dialog_create(struct hostapd_data *hapd, const u8 *addr, u8 dialog_token)
{
	struct sta_info *sta;
	struct gas_dialog_info *dia = NULL;
	int i, j;

	sta = ap_get_sta(hapd, addr);
	if (!sta) {
		/*
		 * We need a STA entry to be able to maintain state for
		 * the GAS query.
		 */
		wpa_printf(MSG_DEBUG, "ANQP: Add a temporary STA entry for "
			   "GAS query");
		sta = ap_sta_add(hapd, addr);
		if (!sta) {
			wpa_printf(MSG_DEBUG, "Failed to add STA " MACSTR
				   " for GAS query", MAC2STR(addr));
			return NULL;
		}
		sta->flags |= WLAN_STA_GAS;
		/*
		 * The default inactivity is 300 seconds. We don't need
		 * it to be that long. Use five second timeout and increase this
		 * with the comeback_delay for testing cases.
		 */
		ap_sta_session_timeout(hapd, sta,
				       hapd->conf->gas_comeback_delay / 1024 +
				       5);
	} else {
		ap_sta_replenish_timeout(hapd, sta, 5);
	}

	if (sta->gas_dialog == NULL) {
		sta->gas_dialog = os_calloc(GAS_DIALOG_MAX,
					    sizeof(struct gas_dialog_info));
		if (sta->gas_dialog == NULL)
			return NULL;
	}

	for (i = sta->gas_dialog_next, j = 0; j < GAS_DIALOG_MAX; i++, j++) {
		if (i == GAS_DIALOG_MAX)
			i = 0;
		if (sta->gas_dialog[i].valid)
			continue;
		dia = &sta->gas_dialog[i];
		dia->valid = 1;
		dia->dialog_token = dialog_token;
		sta->gas_dialog_next = (++i == GAS_DIALOG_MAX) ? 0 : i;
		return dia;
	}

	wpa_msg(hapd->msg_ctx, MSG_ERROR, "ANQP: Could not create dialog for "
		MACSTR " dialog_token %u. Consider increasing "
		"GAS_DIALOG_MAX.", MAC2STR(addr), dialog_token);

	return NULL;
}


struct gas_dialog_info *
gas_serv_dialog_find(struct hostapd_data *hapd, const u8 *addr,
		     u8 dialog_token)
{
	struct sta_info *sta;
	int i;

	sta = ap_get_sta(hapd, addr);
	if (!sta) {
		wpa_printf(MSG_DEBUG, "ANQP: could not find STA " MACSTR,
			   MAC2STR(addr));
		return NULL;
	}
	for (i = 0; sta->gas_dialog && i < GAS_DIALOG_MAX; i++) {
		if (sta->gas_dialog[i].dialog_token != dialog_token ||
		    !sta->gas_dialog[i].valid)
			continue;
		ap_sta_replenish_timeout(hapd, sta, 5);
		return &sta->gas_dialog[i];
	}
	wpa_printf(MSG_DEBUG, "ANQP: Could not find dialog for "
		   MACSTR " dialog_token %u", MAC2STR(addr), dialog_token);
	return NULL;
}


void gas_serv_dialog_clear(struct gas_dialog_info *dia)
{
	wpabuf_free(dia->sd_resp);
	os_memset(dia, 0, sizeof(*dia));
}


static void gas_serv_free_dialogs(struct hostapd_data *hapd,
				  const u8 *sta_addr)
{
	struct sta_info *sta;
	int i;

	sta = ap_get_sta(hapd, sta_addr);
	if (sta == NULL || sta->gas_dialog == NULL)
		return;

	for (i = 0; i < GAS_DIALOG_MAX; i++) {
		if (sta->gas_dialog[i].valid)
			return;
	}

	os_free(sta->gas_dialog);
	sta->gas_dialog = NULL;
}


#ifdef CONFIG_HS20
static void anqp_add_hs_capab_list(struct hostapd_data *hapd,
				   struct wpabuf *buf)
{
	u8 *len;

	len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
	wpabuf_put_be24(buf, OUI_WFA);
	wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
	wpabuf_put_u8(buf, HS20_STYPE_CAPABILITY_LIST);
	wpabuf_put_u8(buf, 0); /* Reserved */
	wpabuf_put_u8(buf, HS20_STYPE_CAPABILITY_LIST);
	if (hapd->conf->hs20_oper_friendly_name)
		wpabuf_put_u8(buf, HS20_STYPE_OPERATOR_FRIENDLY_NAME);
	if (hapd->conf->hs20_wan_metrics)
		wpabuf_put_u8(buf, HS20_STYPE_WAN_METRICS);
	if (hapd->conf->hs20_connection_capability)
		wpabuf_put_u8(buf, HS20_STYPE_CONNECTION_CAPABILITY);
	if (hapd->conf->nai_realm_data)
		wpabuf_put_u8(buf, HS20_STYPE_NAI_HOME_REALM_QUERY);
	if (hapd->conf->hs20_operating_class)
		wpabuf_put_u8(buf, HS20_STYPE_OPERATING_CLASS);
	if (hapd->conf->hs20_osu_providers_count)
		wpabuf_put_u8(buf, HS20_STYPE_OSU_PROVIDERS_LIST);
	if (hapd->conf->hs20_osu_providers_nai_count)
		wpabuf_put_u8(buf, HS20_STYPE_OSU_PROVIDERS_NAI_LIST);
	if (hapd->conf->hs20_icons_count)
		wpabuf_put_u8(buf, HS20_STYPE_ICON_REQUEST);
	if (hapd->conf->hs20_operator_icon_count)
		wpabuf_put_u8(buf, HS20_STYPE_OPERATOR_ICON_METADATA);
	gas_anqp_set_element_len(buf, len);
}
#endif /* CONFIG_HS20 */


static struct anqp_element * get_anqp_elem(struct hostapd_data *hapd,
					   u16 infoid)
{
	struct anqp_element *elem;

	dl_list_for_each(elem, &hapd->conf->anqp_elem, struct anqp_element,
			 list) {
		if (elem->infoid == infoid)
			return elem;
	}

	return NULL;
}


static void anqp_add_elem(struct hostapd_data *hapd, struct wpabuf *buf,
			  u16 infoid)
{
	struct anqp_element *elem;

	elem = get_anqp_elem(hapd, infoid);
	if (!elem)
		return;
	if (wpabuf_tailroom(buf) < 2 + 2 + wpabuf_len(elem->payload)) {
		wpa_printf(MSG_DEBUG, "ANQP: No room for InfoID %u payload",
			   infoid);
		return;
	}

	wpabuf_put_le16(buf, infoid);
	wpabuf_put_le16(buf, wpabuf_len(elem->payload));
	wpabuf_put_buf(buf, elem->payload);
}


static int anqp_add_override(struct hostapd_data *hapd, struct wpabuf *buf,
			     u16 infoid)
{
	if (get_anqp_elem(hapd, infoid)) {
		anqp_add_elem(hapd, buf, infoid);
		return 1;
	}

	return 0;
}


static void anqp_add_capab_list(struct hostapd_data *hapd,
				struct wpabuf *buf)
{
	u8 *len;
	u16 id;

	if (anqp_add_override(hapd, buf, ANQP_CAPABILITY_LIST))
		return;

	len = gas_anqp_add_element(buf, ANQP_CAPABILITY_LIST);
	wpabuf_put_le16(buf, ANQP_CAPABILITY_LIST);
	if (hapd->conf->venue_name || get_anqp_elem(hapd, ANQP_VENUE_NAME))
		wpabuf_put_le16(buf, ANQP_VENUE_NAME);
	if (get_anqp_elem(hapd, ANQP_EMERGENCY_CALL_NUMBER))
		wpabuf_put_le16(buf, ANQP_EMERGENCY_CALL_NUMBER);
	if (hapd->conf->network_auth_type ||
	    get_anqp_elem(hapd, ANQP_NETWORK_AUTH_TYPE))
		wpabuf_put_le16(buf, ANQP_NETWORK_AUTH_TYPE);
	if (hapd->conf->roaming_consortium ||
	    get_anqp_elem(hapd, ANQP_ROAMING_CONSORTIUM))
		wpabuf_put_le16(buf, ANQP_ROAMING_CONSORTIUM);
	if (hapd->conf->ipaddr_type_configured ||
	    get_anqp_elem(hapd, ANQP_IP_ADDR_TYPE_AVAILABILITY))
		wpabuf_put_le16(buf, ANQP_IP_ADDR_TYPE_AVAILABILITY);
	if (hapd->conf->nai_realm_data ||
	    get_anqp_elem(hapd, ANQP_NAI_REALM))
		wpabuf_put_le16(buf, ANQP_NAI_REALM);
	if (hapd->conf->anqp_3gpp_cell_net ||
	    get_anqp_elem(hapd, ANQP_3GPP_CELLULAR_NETWORK))
		wpabuf_put_le16(buf, ANQP_3GPP_CELLULAR_NETWORK);
	if (get_anqp_elem(hapd, ANQP_AP_GEOSPATIAL_LOCATION))
		wpabuf_put_le16(buf, ANQP_AP_GEOSPATIAL_LOCATION);
	if (get_anqp_elem(hapd, ANQP_AP_CIVIC_LOCATION))
		wpabuf_put_le16(buf, ANQP_AP_CIVIC_LOCATION);
	if (get_anqp_elem(hapd, ANQP_AP_LOCATION_PUBLIC_URI))
		wpabuf_put_le16(buf, ANQP_AP_LOCATION_PUBLIC_URI);
	if (hapd->conf->domain_name || get_anqp_elem(hapd, ANQP_DOMAIN_NAME))
		wpabuf_put_le16(buf, ANQP_DOMAIN_NAME);
	if (get_anqp_elem(hapd, ANQP_EMERGENCY_ALERT_URI))
		wpabuf_put_le16(buf, ANQP_EMERGENCY_ALERT_URI);
	if (get_anqp_elem(hapd, ANQP_TDLS_CAPABILITY))
		wpabuf_put_le16(buf, ANQP_TDLS_CAPABILITY);
	if (get_anqp_elem(hapd, ANQP_EMERGENCY_NAI))
		wpabuf_put_le16(buf, ANQP_EMERGENCY_NAI);
	if (get_anqp_elem(hapd, ANQP_NEIGHBOR_REPORT))
		wpabuf_put_le16(buf, ANQP_NEIGHBOR_REPORT);
#ifdef CONFIG_FILS
	if (!dl_list_empty(&hapd->conf->fils_realms) ||
	    get_anqp_elem(hapd, ANQP_FILS_REALM_INFO))
		wpabuf_put_le16(buf, ANQP_FILS_REALM_INFO);
#endif /* CONFIG_FILS */
	if (get_anqp_elem(hapd, ANQP_CAG))
		wpabuf_put_le16(buf, ANQP_CAG);
	if (hapd->conf->venue_url || get_anqp_elem(hapd, ANQP_VENUE_URL))
		wpabuf_put_le16(buf, ANQP_VENUE_URL);
	if (get_anqp_elem(hapd, ANQP_ADVICE_OF_CHARGE))
		wpabuf_put_le16(buf, ANQP_ADVICE_OF_CHARGE);
	if (get_anqp_elem(hapd, ANQP_LOCAL_CONTENT))
		wpabuf_put_le16(buf, ANQP_LOCAL_CONTENT);
	for (id = 280; id < 300; id++) {
		if (get_anqp_elem(hapd, id))
			wpabuf_put_le16(buf, id);
	}
#ifdef CONFIG_HS20
	anqp_add_hs_capab_list(hapd, buf);
#endif /* CONFIG_HS20 */
	gas_anqp_set_element_len(buf, len);
}


static void anqp_add_venue_name(struct hostapd_data *hapd, struct wpabuf *buf)
{
	if (anqp_add_override(hapd, buf, ANQP_VENUE_NAME))
		return;

	if (hapd->conf->venue_name) {
		u8 *len;
		unsigned int i;
		len = gas_anqp_add_element(buf, ANQP_VENUE_NAME);
		wpabuf_put_u8(buf, hapd->conf->venue_group);
		wpabuf_put_u8(buf, hapd->conf->venue_type);
		for (i = 0; i < hapd->conf->venue_name_count; i++) {
			struct hostapd_lang_string *vn;
			vn = &hapd->conf->venue_name[i];
			wpabuf_put_u8(buf, 3 + vn->name_len);
			wpabuf_put_data(buf, vn->lang, 3);
			wpabuf_put_data(buf, vn->name, vn->name_len);
		}
		gas_anqp_set_element_len(buf, len);
	}
}


static void anqp_add_venue_url(struct hostapd_data *hapd, struct wpabuf *buf)
{
	if (anqp_add_override(hapd, buf, ANQP_VENUE_URL))
		return;

	if (hapd->conf->venue_url) {
		u8 *len;
		unsigned int i;

		len = gas_anqp_add_element(buf, ANQP_VENUE_URL);
		for (i = 0; i < hapd->conf->venue_url_count; i++) {
			struct hostapd_venue_url *url;

			url = &hapd->conf->venue_url[i];
			wpabuf_put_u8(buf, 1 + url->url_len);
			wpabuf_put_u8(buf, url->venue_number);
			wpabuf_put_data(buf, url->url, url->url_len);
		}
		gas_anqp_set_element_len(buf, len);
	}
}


static void anqp_add_network_auth_type(struct hostapd_data *hapd,
				       struct wpabuf *buf)
{
	if (anqp_add_override(hapd, buf, ANQP_NETWORK_AUTH_TYPE))
		return;

	if (hapd->conf->network_auth_type) {
		wpabuf_put_le16(buf, ANQP_NETWORK_AUTH_TYPE);
		wpabuf_put_le16(buf, hapd->conf->network_auth_type_len);
		wpabuf_put_data(buf, hapd->conf->network_auth_type,
				hapd->conf->network_auth_type_len);
	}
}


static void anqp_add_roaming_consortium(struct hostapd_data *hapd,
					struct wpabuf *buf)
{
	unsigned int i;
	u8 *len;

	if (anqp_add_override(hapd, buf, ANQP_ROAMING_CONSORTIUM))
		return;

	len = gas_anqp_add_element(buf, ANQP_ROAMING_CONSORTIUM);
	for (i = 0; i < hapd->conf->roaming_consortium_count; i++) {
		struct hostapd_roaming_consortium *rc;
		rc = &hapd->conf->roaming_consortium[i];
		wpabuf_put_u8(buf, rc->len);
		wpabuf_put_data(buf, rc->oi, rc->len);
	}
	gas_anqp_set_element_len(buf, len);
}


static void anqp_add_ip_addr_type_availability(struct hostapd_data *hapd,
					       struct wpabuf *buf)
{
	if (anqp_add_override(hapd, buf, ANQP_IP_ADDR_TYPE_AVAILABILITY))
		return;

	if (hapd->conf->ipaddr_type_configured) {
		wpabuf_put_le16(buf, ANQP_IP_ADDR_TYPE_AVAILABILITY);
		wpabuf_put_le16(buf, 1);
		wpabuf_put_u8(buf, hapd->conf->ipaddr_type_availability);
	}
}


static void anqp_add_nai_realm_eap(struct wpabuf *buf,
				   struct hostapd_nai_realm_data *realm)
{
	unsigned int i, j;

	wpabuf_put_u8(buf, realm->eap_method_count);

	for (i = 0; i < realm->eap_method_count; i++) {
		struct hostapd_nai_realm_eap *eap = &realm->eap_method[i];
		wpabuf_put_u8(buf, 2 + (3 * eap->num_auths));
		wpabuf_put_u8(buf, eap->eap_method);
		wpabuf_put_u8(buf, eap->num_auths);
		for (j = 0; j < eap->num_auths; j++) {
			wpabuf_put_u8(buf, eap->auth_id[j]);
			wpabuf_put_u8(buf, 1);
			wpabuf_put_u8(buf, eap->auth_val[j]);
		}
	}
}


static void anqp_add_nai_realm_data(struct wpabuf *buf,
				    struct hostapd_nai_realm_data *realm,
				    unsigned int realm_idx)
{
	u8 *realm_data_len;

	wpa_printf(MSG_DEBUG, "realm=%s, len=%d", realm->realm[realm_idx],
		   (int) os_strlen(realm->realm[realm_idx]));
	realm_data_len = wpabuf_put(buf, 2);
	wpabuf_put_u8(buf, realm->encoding);
	wpabuf_put_u8(buf, os_strlen(realm->realm[realm_idx]));
	wpabuf_put_str(buf, realm->realm[realm_idx]);
	anqp_add_nai_realm_eap(buf, realm);
	gas_anqp_set_element_len(buf, realm_data_len);
}


static int hs20_add_nai_home_realm_matches(struct hostapd_data *hapd,
					   struct wpabuf *buf,
					   const u8 *home_realm,
					   size_t home_realm_len)
{
	unsigned int i, j, k;
	u8 num_realms, num_matching = 0, encoding, realm_len, *realm_list_len;
	struct hostapd_nai_realm_data *realm;
	const u8 *pos, *realm_name, *end;
	struct {
		unsigned int realm_data_idx;
		unsigned int realm_idx;
	} matches[10];

	pos = home_realm;
	end = pos + home_realm_len;
	if (end - pos < 1) {
		wpa_hexdump(MSG_DEBUG, "Too short NAI Home Realm Query",
			    home_realm, home_realm_len);
		return -1;
	}
	num_realms = *pos++;

	for (i = 0; i < num_realms && num_matching < 10; i++) {
		if (end - pos < 2) {
			wpa_hexdump(MSG_DEBUG,
				    "Truncated NAI Home Realm Query",
				    home_realm, home_realm_len);
			return -1;
		}
		encoding = *pos++;
		realm_len = *pos++;
		if (realm_len > end - pos) {
			wpa_hexdump(MSG_DEBUG,
				    "Truncated NAI Home Realm Query",
				    home_realm, home_realm_len);
			return -1;
		}
		realm_name = pos;
		for (j = 0; j < hapd->conf->nai_realm_count &&
			     num_matching < 10; j++) {
			const u8 *rpos, *rend;
			realm = &hapd->conf->nai_realm_data[j];
			if (encoding != realm->encoding)
				continue;

			rpos = realm_name;
			while (rpos < realm_name + realm_len &&
			       num_matching < 10) {
				for (rend = rpos;
				     rend < realm_name + realm_len; rend++) {
					if (*rend == ';')
						break;
				}
				for (k = 0; k < MAX_NAI_REALMS &&
					     realm->realm[k] &&
					     num_matching < 10; k++) {
					if ((int) os_strlen(realm->realm[k]) !=
					    rend - rpos ||
					    os_strncmp((char *) rpos,
						       realm->realm[k],
						       rend - rpos) != 0)
						continue;
					matches[num_matching].realm_data_idx =
						j;
					matches[num_matching].realm_idx = k;
					num_matching++;
				}
				rpos = rend + 1;
			}
		}
		pos += realm_len;
	}

	realm_list_len = gas_anqp_add_element(buf, ANQP_NAI_REALM);
	wpabuf_put_le16(buf, num_matching);

	/*
	 * There are two ways to format. 1. each realm in a NAI Realm Data unit
	 * 2. all realms that share the same EAP methods in a NAI Realm Data
	 * unit. The first format is likely to be bigger in size than the
	 * second, but may be easier to parse and process by the receiver.
	 */
	for (i = 0; i < num_matching; i++) {
		wpa_printf(MSG_DEBUG, "realm_idx %d, realm_data_idx %d",
			   matches[i].realm_data_idx, matches[i].realm_idx);
		realm = &hapd->conf->nai_realm_data[matches[i].realm_data_idx];
		anqp_add_nai_realm_data(buf, realm, matches[i].realm_idx);
	}
	gas_anqp_set_element_len(buf, realm_list_len);
	return 0;
}


static void anqp_add_nai_realm(struct hostapd_data *hapd, struct wpabuf *buf,
			       const u8 *home_realm, size_t home_realm_len,
			       int nai_realm, int nai_home_realm)
{
	if (nai_realm && !nai_home_realm &&
	    anqp_add_override(hapd, buf, ANQP_NAI_REALM))
		return;

	if (nai_realm && hapd->conf->nai_realm_data) {
		u8 *len;
		unsigned int i, j;
		len = gas_anqp_add_element(buf, ANQP_NAI_REALM);
		wpabuf_put_le16(buf, hapd->conf->nai_realm_count);
		for (i = 0; i < hapd->conf->nai_realm_count; i++) {
			u8 *realm_data_len, *realm_len;
			struct hostapd_nai_realm_data *realm;

			realm = &hapd->conf->nai_realm_data[i];
			realm_data_len = wpabuf_put(buf, 2);
			wpabuf_put_u8(buf, realm->encoding);
			realm_len = wpabuf_put(buf, 1);
			for (j = 0; realm->realm[j]; j++) {
				if (j > 0)
					wpabuf_put_u8(buf, ';');
				wpabuf_put_str(buf, realm->realm[j]);
			}
			*realm_len = (u8 *) wpabuf_put(buf, 0) - realm_len - 1;
			anqp_add_nai_realm_eap(buf, realm);
			gas_anqp_set_element_len(buf, realm_data_len);
		}
		gas_anqp_set_element_len(buf, len);
	} else if (nai_home_realm && hapd->conf->nai_realm_data && home_realm) {
		hs20_add_nai_home_realm_matches(hapd, buf, home_realm,
						home_realm_len);
	}
}


static void anqp_add_3gpp_cellular_network(struct hostapd_data *hapd,
					   struct wpabuf *buf)
{
	if (anqp_add_override(hapd, buf, ANQP_3GPP_CELLULAR_NETWORK))
		return;

	if (hapd->conf->anqp_3gpp_cell_net) {
		wpabuf_put_le16(buf, ANQP_3GPP_CELLULAR_NETWORK);
		wpabuf_put_le16(buf,
				hapd->conf->anqp_3gpp_cell_net_len);
		wpabuf_put_data(buf, hapd->conf->anqp_3gpp_cell_net,
				hapd->conf->anqp_3gpp_cell_net_len);
	}
}


static void anqp_add_domain_name(struct hostapd_data *hapd, struct wpabuf *buf)
{
	if (anqp_add_override(hapd, buf, ANQP_DOMAIN_NAME))
		return;

	if (hapd->conf->domain_name) {
		wpabuf_put_le16(buf, ANQP_DOMAIN_NAME);
		wpabuf_put_le16(buf, hapd->conf->domain_name_len);
		wpabuf_put_data(buf, hapd->conf->domain_name,
				hapd->conf->domain_name_len);
	}
}


#ifdef CONFIG_FILS
static void anqp_add_fils_realm_info(struct hostapd_data *hapd,
				     struct wpabuf *buf)
{
	size_t count;

	if (anqp_add_override(hapd, buf, ANQP_FILS_REALM_INFO))
		return;

	count = dl_list_len(&hapd->conf->fils_realms);
	if (count > 10000)
		count = 10000;
	if (count) {
		struct fils_realm *realm;

		wpabuf_put_le16(buf, ANQP_FILS_REALM_INFO);
		wpabuf_put_le16(buf, 2 * count);

		dl_list_for_each(realm, &hapd->conf->fils_realms,
				 struct fils_realm, list) {
			if (count == 0)
				break;
			wpabuf_put_data(buf, realm->hash, 2);
			count--;
		}
	}
}
#endif /* CONFIG_FILS */


#ifdef CONFIG_HS20

static void anqp_add_operator_friendly_name(struct hostapd_data *hapd,
					    struct wpabuf *buf)
{
	if (hapd->conf->hs20_oper_friendly_name) {
		u8 *len;
		unsigned int i;
		len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
		wpabuf_put_be24(buf, OUI_WFA);
		wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
		wpabuf_put_u8(buf, HS20_STYPE_OPERATOR_FRIENDLY_NAME);
		wpabuf_put_u8(buf, 0); /* Reserved */
		for (i = 0; i < hapd->conf->hs20_oper_friendly_name_count; i++)
		{
			struct hostapd_lang_string *vn;
			vn = &hapd->conf->hs20_oper_friendly_name[i];
			wpabuf_put_u8(buf, 3 + vn->name_len);
			wpabuf_put_data(buf, vn->lang, 3);
			wpabuf_put_data(buf, vn->name, vn->name_len);
		}
		gas_anqp_set_element_len(buf, len);
	}
}


static void anqp_add_wan_metrics(struct hostapd_data *hapd,
				 struct wpabuf *buf)
{
	if (hapd->conf->hs20_wan_metrics) {
		u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
		wpabuf_put_be24(buf, OUI_WFA);
		wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
		wpabuf_put_u8(buf, HS20_STYPE_WAN_METRICS);
		wpabuf_put_u8(buf, 0); /* Reserved */
		wpabuf_put_data(buf, hapd->conf->hs20_wan_metrics, 13);
		gas_anqp_set_element_len(buf, len);
	}
}


static void anqp_add_connection_capability(struct hostapd_data *hapd,
					   struct wpabuf *buf)
{
	if (hapd->conf->hs20_connection_capability) {
		u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
		wpabuf_put_be24(buf, OUI_WFA);
		wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
		wpabuf_put_u8(buf, HS20_STYPE_CONNECTION_CAPABILITY);
		wpabuf_put_u8(buf, 0); /* Reserved */
		wpabuf_put_data(buf, hapd->conf->hs20_connection_capability,
				hapd->conf->hs20_connection_capability_len);
		gas_anqp_set_element_len(buf, len);
	}
}


static void anqp_add_operating_class(struct hostapd_data *hapd,
				     struct wpabuf *buf)
{
	if (hapd->conf->hs20_operating_class) {
		u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
		wpabuf_put_be24(buf, OUI_WFA);
		wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
		wpabuf_put_u8(buf, HS20_STYPE_OPERATING_CLASS);
		wpabuf_put_u8(buf, 0); /* Reserved */
		wpabuf_put_data(buf, hapd->conf->hs20_operating_class,
				hapd->conf->hs20_operating_class_len);
		gas_anqp_set_element_len(buf, len);
	}
}


static void anqp_add_icon(struct wpabuf *buf, struct hostapd_bss_config *bss,
			  const char *name)
{
	size_t j;
	struct hs20_icon *icon = NULL;

	for (j = 0; j < bss->hs20_icons_count && !icon; j++) {
		if (os_strcmp(name, bss->hs20_icons[j].name) == 0)
			icon = &bss->hs20_icons[j];
	}
	if (!icon)
		return; /* icon info not found */

	wpabuf_put_le16(buf, icon->width);
	wpabuf_put_le16(buf, icon->height);
	wpabuf_put_data(buf, icon->language, 3);
	wpabuf_put_u8(buf, os_strlen(icon->type));
	wpabuf_put_str(buf, icon->type);
	wpabuf_put_u8(buf, os_strlen(icon->name));
	wpabuf_put_str(buf, icon->name);
}


static void anqp_add_osu_provider(struct wpabuf *buf,
				  struct hostapd_bss_config *bss,
				  struct hs20_osu_provider *p)
{
	u8 *len, *len2, *count;
	unsigned int i;

	len = wpabuf_put(buf, 2); /* OSU Provider Length to be filled */

	/* OSU Friendly Name Duples */
	len2 = wpabuf_put(buf, 2);
	for (i = 0; i < p->friendly_name_count; i++) {
		struct hostapd_lang_string *s = &p->friendly_name[i];
		wpabuf_put_u8(buf, 3 + s->name_len);
		wpabuf_put_data(buf, s->lang, 3);
		wpabuf_put_data(buf, s->name, s->name_len);
	}
	WPA_PUT_LE16(len2, (u8 *) wpabuf_put(buf, 0) - len2 - 2);

	/* OSU Server URI */
	if (p->server_uri) {
		wpabuf_put_u8(buf, os_strlen(p->server_uri));
		wpabuf_put_str(buf, p->server_uri);
	} else
		wpabuf_put_u8(buf, 0);

	/* OSU Method List */
	count = wpabuf_put(buf, 1);
	for (i = 0; p->method_list && p->method_list[i] >= 0; i++)
		wpabuf_put_u8(buf, p->method_list[i]);
	*count = i;

	/* Icons Available */
	len2 = wpabuf_put(buf, 2);
	for (i = 0; i < p->icons_count; i++)
		anqp_add_icon(buf, bss, p->icons[i]);
	WPA_PUT_LE16(len2, (u8 *) wpabuf_put(buf, 0) - len2 - 2);

	/* OSU_NAI */
	if (p->osu_nai) {
		wpabuf_put_u8(buf, os_strlen(p->osu_nai));
		wpabuf_put_str(buf, p->osu_nai);
	} else
		wpabuf_put_u8(buf, 0);

	/* OSU Service Description Duples */
	len2 = wpabuf_put(buf, 2);
	for (i = 0; i < p->service_desc_count; i++) {
		struct hostapd_lang_string *s = &p->service_desc[i];
		wpabuf_put_u8(buf, 3 + s->name_len);
		wpabuf_put_data(buf, s->lang, 3);
		wpabuf_put_data(buf, s->name, s->name_len);
	}
	WPA_PUT_LE16(len2, (u8 *) wpabuf_put(buf, 0) - len2 - 2);

	WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
}


static void anqp_add_osu_providers_list(struct hostapd_data *hapd,
					struct wpabuf *buf)
{
	if (hapd->conf->hs20_osu_providers_count) {
		size_t i;
		u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
		wpabuf_put_be24(buf, OUI_WFA);
		wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
		wpabuf_put_u8(buf, HS20_STYPE_OSU_PROVIDERS_LIST);
		wpabuf_put_u8(buf, 0); /* Reserved */

		/* OSU SSID */
		wpabuf_put_u8(buf, hapd->conf->osu_ssid_len);
		wpabuf_put_data(buf, hapd->conf->osu_ssid,
				hapd->conf->osu_ssid_len);

		/* Number of OSU Providers */
		wpabuf_put_u8(buf, hapd->conf->hs20_osu_providers_count);

		for (i = 0; i < hapd->conf->hs20_osu_providers_count; i++) {
			anqp_add_osu_provider(
				buf, hapd->conf,
				&hapd->conf->hs20_osu_providers[i]);
		}

		gas_anqp_set_element_len(buf, len);
	}
}


static void anqp_add_osu_provider_nai(struct wpabuf *buf,
				      struct hs20_osu_provider *p)
{
	/* OSU_NAI for shared BSS (Single SSID) */
	if (p->osu_nai2) {
		wpabuf_put_u8(buf, os_strlen(p->osu_nai2));
		wpabuf_put_str(buf, p->osu_nai2);
	} else {
		wpabuf_put_u8(buf, 0);
	}
}


static void anqp_add_osu_providers_nai_list(struct hostapd_data *hapd,
					    struct wpabuf *buf)
{
	if (hapd->conf->hs20_osu_providers_nai_count) {
		size_t i;
		u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
		wpabuf_put_be24(buf, OUI_WFA);
		wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
		wpabuf_put_u8(buf, HS20_STYPE_OSU_PROVIDERS_NAI_LIST);
		wpabuf_put_u8(buf, 0); /* Reserved */

		for (i = 0; i < hapd->conf->hs20_osu_providers_count; i++) {
			anqp_add_osu_provider_nai(
				buf, &hapd->conf->hs20_osu_providers[i]);
		}

		gas_anqp_set_element_len(buf, len);
	}
}


static void anqp_add_icon_binary_file(struct hostapd_data *hapd,
				      struct wpabuf *buf,
				      const u8 *name, size_t name_len)
{
	struct hs20_icon *icon;
	size_t i;
	u8 *len;

	wpa_hexdump_ascii(MSG_DEBUG, "HS 2.0: Requested Icon Filename",
			  name, name_len);
	for (i = 0; i < hapd->conf->hs20_icons_count; i++) {
		icon = &hapd->conf->hs20_icons[i];
		if (name_len == os_strlen(icon->name) &&
		    os_memcmp(name, icon->name, name_len) == 0)
			break;
	}

	if (i < hapd->conf->hs20_icons_count)
		icon = &hapd->conf->hs20_icons[i];
	else
		icon = NULL;

	len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
	wpabuf_put_be24(buf, OUI_WFA);
	wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
	wpabuf_put_u8(buf, HS20_STYPE_ICON_BINARY_FILE);
	wpabuf_put_u8(buf, 0); /* Reserved */

	if (icon) {
		char *data;
		size_t data_len;

		data = os_readfile(icon->file, &data_len);
		if (data == NULL || data_len > 65535) {
			wpabuf_put_u8(buf, 2); /* Download Status:
						* Unspecified file error */
			wpabuf_put_u8(buf, 0);
			wpabuf_put_le16(buf, 0);
		} else {
			wpabuf_put_u8(buf, 0); /* Download Status: Success */
			wpabuf_put_u8(buf, os_strlen(icon->type));
			wpabuf_put_str(buf, icon->type);
			wpabuf_put_le16(buf, data_len);
			wpabuf_put_data(buf, data, data_len);
		}
		os_free(data);
	} else {
		wpabuf_put_u8(buf, 1); /* Download Status: File not found */
		wpabuf_put_u8(buf, 0);
		wpabuf_put_le16(buf, 0);
	}

	gas_anqp_set_element_len(buf, len);
}


static void anqp_add_operator_icon_metadata(struct hostapd_data *hapd,
					    struct wpabuf *buf)
{
	struct hostapd_bss_config *bss = hapd->conf;
	size_t i;
	u8 *len;

	if (!bss->hs20_operator_icon_count)
		return;

	len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);

	wpabuf_put_be24(buf, OUI_WFA);
	wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
	wpabuf_put_u8(buf, HS20_STYPE_OPERATOR_ICON_METADATA);
	wpabuf_put_u8(buf, 0); /* Reserved */

	for (i = 0; i < bss->hs20_operator_icon_count; i++)
		anqp_add_icon(buf, bss, bss->hs20_operator_icon[i]);

	gas_anqp_set_element_len(buf, len);
}

#endif /* CONFIG_HS20 */


#ifdef CONFIG_MBO
static void anqp_add_mbo_cell_data_conn_pref(struct hostapd_data *hapd,
					     struct wpabuf *buf)
{
	if (hapd->conf->mbo_cell_data_conn_pref >= 0) {
		u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
		wpabuf_put_be24(buf, OUI_WFA);
		wpabuf_put_u8(buf, MBO_ANQP_OUI_TYPE);
		wpabuf_put_u8(buf, MBO_ANQP_SUBTYPE_CELL_CONN_PREF);
		wpabuf_put_u8(buf, hapd->conf->mbo_cell_data_conn_pref);
		gas_anqp_set_element_len(buf, len);
	}
}
#endif /* CONFIG_MBO */


static size_t anqp_get_required_len(struct hostapd_data *hapd,
				    const u16 *infoid,
				    unsigned int num_infoid)
{
	size_t len = 0;
	unsigned int i;

	for (i = 0; i < num_infoid; i++) {
		struct anqp_element *elem = get_anqp_elem(hapd, infoid[i]);

		if (elem)
			len += 2 + 2 + wpabuf_len(elem->payload);
	}

	return len;
}


static struct wpabuf *
gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
				unsigned int request,
				const u8 *home_realm, size_t home_realm_len,
				const u8 *icon_name, size_t icon_name_len,
				const u16 *extra_req,
				unsigned int num_extra_req)
{
	struct wpabuf *buf;
	size_t len;
	unsigned int i;

	len = 1400;
	if (request & (ANQP_REQ_NAI_REALM | ANQP_REQ_NAI_HOME_REALM))
		len += 1000;
	if (request & ANQP_REQ_ICON_REQUEST)
		len += 65536;
#ifdef CONFIG_FILS
	if (request & ANQP_FILS_REALM_INFO)
		len += 2 * dl_list_len(&hapd->conf->fils_realms);
#endif /* CONFIG_FILS */
	len += anqp_get_required_len(hapd, extra_req, num_extra_req);

	buf = wpabuf_alloc(len);
	if (buf == NULL)
		return NULL;

	if (request & ANQP_REQ_CAPABILITY_LIST)
		anqp_add_capab_list(hapd, buf);
	if (request & ANQP_REQ_VENUE_NAME)
		anqp_add_venue_name(hapd, buf);
	if (request & ANQP_REQ_EMERGENCY_CALL_NUMBER)
		anqp_add_elem(hapd, buf, ANQP_EMERGENCY_CALL_NUMBER);
	if (request & ANQP_REQ_NETWORK_AUTH_TYPE)
		anqp_add_network_auth_type(hapd, buf);
	if (request & ANQP_REQ_ROAMING_CONSORTIUM)
		anqp_add_roaming_consortium(hapd, buf);
	if (request & ANQP_REQ_IP_ADDR_TYPE_AVAILABILITY)
		anqp_add_ip_addr_type_availability(hapd, buf);
	if (request & (ANQP_REQ_NAI_REALM | ANQP_REQ_NAI_HOME_REALM))
		anqp_add_nai_realm(hapd, buf, home_realm, home_realm_len,
				   request & ANQP_REQ_NAI_REALM,
				   request & ANQP_REQ_NAI_HOME_REALM);
	if (request & ANQP_REQ_3GPP_CELLULAR_NETWORK)
		anqp_add_3gpp_cellular_network(hapd, buf);
	if (request & ANQP_REQ_AP_GEOSPATIAL_LOCATION)
		anqp_add_elem(hapd, buf, ANQP_AP_GEOSPATIAL_LOCATION);
	if (request & ANQP_REQ_AP_CIVIC_LOCATION)
		anqp_add_elem(hapd, buf, ANQP_AP_CIVIC_LOCATION);
	if (request & ANQP_REQ_AP_LOCATION_PUBLIC_URI)
		anqp_add_elem(hapd, buf, ANQP_AP_LOCATION_PUBLIC_URI);
	if (request & ANQP_REQ_DOMAIN_NAME)
		anqp_add_domain_name(hapd, buf);
	if (request & ANQP_REQ_EMERGENCY_ALERT_URI)
		anqp_add_elem(hapd, buf, ANQP_EMERGENCY_ALERT_URI);
	if (request & ANQP_REQ_TDLS_CAPABILITY)
		anqp_add_elem(hapd, buf, ANQP_TDLS_CAPABILITY);
	if (request & ANQP_REQ_EMERGENCY_NAI)
		anqp_add_elem(hapd, buf, ANQP_EMERGENCY_NAI);

	for (i = 0; i < num_extra_req; i++) {
#ifdef CONFIG_FILS
		if (extra_req[i] == ANQP_FILS_REALM_INFO) {
			anqp_add_fils_realm_info(hapd, buf);
			continue;
		}
#endif /* CONFIG_FILS */
		if (extra_req[i] == ANQP_VENUE_URL) {
			anqp_add_venue_url(hapd, buf);
			continue;
		}
		anqp_add_elem(hapd, buf, extra_req[i]);
	}

#ifdef CONFIG_HS20
	if (request & ANQP_REQ_HS_CAPABILITY_LIST)
		anqp_add_hs_capab_list(hapd, buf);
	if (request & ANQP_REQ_OPERATOR_FRIENDLY_NAME)
		anqp_add_operator_friendly_name(hapd, buf);
	if (request & ANQP_REQ_WAN_METRICS)
		anqp_add_wan_metrics(hapd, buf);
	if (request & ANQP_REQ_CONNECTION_CAPABILITY)
		anqp_add_connection_capability(hapd, buf);
	if (request & ANQP_REQ_OPERATING_CLASS)
		anqp_add_operating_class(hapd, buf);
	if (request & ANQP_REQ_OSU_PROVIDERS_LIST)
		anqp_add_osu_providers_list(hapd, buf);
	if (request & ANQP_REQ_ICON_REQUEST)
		anqp_add_icon_binary_file(hapd, buf, icon_name, icon_name_len);
	if (request & ANQP_REQ_OPERATOR_ICON_METADATA)
		anqp_add_operator_icon_metadata(hapd, buf);
	if (request & ANQP_REQ_OSU_PROVIDERS_NAI_LIST)
		anqp_add_osu_providers_nai_list(hapd, buf);
#endif /* CONFIG_HS20 */

#ifdef CONFIG_MBO
	if (request & ANQP_REQ_MBO_CELL_DATA_CONN_PREF)
		anqp_add_mbo_cell_data_conn_pref(hapd, buf);
#endif /* CONFIG_MBO */

	return buf;
}


#define ANQP_MAX_EXTRA_REQ 20

struct anqp_query_info {
	unsigned int request;
	const u8 *home_realm_query;
	size_t home_realm_query_len;
	const u8 *icon_name;
	size_t icon_name_len;
	int p2p_sd;
	u16 extra_req[ANQP_MAX_EXTRA_REQ];
	unsigned int num_extra_req;
};


static void set_anqp_req(unsigned int bit, const char *name, int local,
			 struct anqp_query_info *qi)
{
	qi->request |= bit;
	if (local) {
		wpa_printf(MSG_DEBUG, "ANQP: %s (local)", name);
	} else {
		wpa_printf(MSG_DEBUG, "ANQP: %s not available", name);
	}
}


static void rx_anqp_query_list_id(struct hostapd_data *hapd, u16 info_id,
				  struct anqp_query_info *qi)
{
	switch (info_id) {
	case ANQP_CAPABILITY_LIST:
		set_anqp_req(ANQP_REQ_CAPABILITY_LIST, "Capability List", 1,
			     qi);
		break;
	case ANQP_VENUE_NAME:
		set_anqp_req(ANQP_REQ_VENUE_NAME, "Venue Name",
			     hapd->conf->venue_name != NULL, qi);
		break;
	case ANQP_EMERGENCY_CALL_NUMBER:
		set_anqp_req(ANQP_REQ_EMERGENCY_CALL_NUMBER,
			     "Emergency Call Number",
			     get_anqp_elem(hapd, info_id) != NULL, qi);
		break;
	case ANQP_NETWORK_AUTH_TYPE:
		set_anqp_req(ANQP_REQ_NETWORK_AUTH_TYPE, "Network Auth Type",
			     hapd->conf->network_auth_type != NULL, qi);
		break;
	case ANQP_ROAMING_CONSORTIUM:
		set_anqp_req(ANQP_REQ_ROAMING_CONSORTIUM, "Roaming Consortium",
			     hapd->conf->roaming_consortium != NULL, qi);
		break;
	case ANQP_IP_ADDR_TYPE_AVAILABILITY:
		set_anqp_req(ANQP_REQ_IP_ADDR_TYPE_AVAILABILITY,
			     "IP Addr Type Availability",
			     hapd->conf->ipaddr_type_configured, qi);
		break;
	case ANQP_NAI_REALM:
		set_anqp_req(ANQP_REQ_NAI_REALM, "NAI Realm",
			     hapd->conf->nai_realm_data != NULL, qi);
		break;
	case ANQP_3GPP_CELLULAR_NETWORK:
		set_anqp_req(ANQP_REQ_3GPP_CELLULAR_NETWORK,
			     "3GPP Cellular Network",
			     hapd->conf->anqp_3gpp_cell_net != NULL, qi);
		break;
	case ANQP_AP_GEOSPATIAL_LOCATION:
		set_anqp_req(ANQP_REQ_AP_GEOSPATIAL_LOCATION,
			     "AP Geospatial Location",
			     get_anqp_elem(hapd, info_id) != NULL, qi);
		break;
	case ANQP_AP_CIVIC_LOCATION:
		set_anqp_req(ANQP_REQ_AP_CIVIC_LOCATION,
			     "AP Civic Location",
			     get_anqp_elem(hapd, info_id) != NULL, qi);
		break;
	case ANQP_AP_LOCATION_PUBLIC_URI:
		set_anqp_req(ANQP_REQ_AP_LOCATION_PUBLIC_URI,
			     "AP Location Public URI",
			     get_anqp_elem(hapd, info_id) != NULL, qi);
		break;
	case ANQP_DOMAIN_NAME:
		set_anqp_req(ANQP_REQ_DOMAIN_NAME, "Domain Name",
			     hapd->conf->domain_name != NULL, qi);
		break;
	case ANQP_EMERGENCY_ALERT_URI:
		set_anqp_req(ANQP_REQ_EMERGENCY_ALERT_URI,
			     "Emergency Alert URI",
			     get_anqp_elem(hapd, info_id) != NULL, qi);
		break;
	case ANQP_TDLS_CAPABILITY:
		set_anqp_req(ANQP_REQ_TDLS_CAPABILITY,
			     "TDLS Capability",
			     get_anqp_elem(hapd, info_id) != NULL, qi);
		break;
	case ANQP_EMERGENCY_NAI:
		set_anqp_req(ANQP_REQ_EMERGENCY_NAI,
			     "Emergency NAI",
			     get_anqp_elem(hapd, info_id) != NULL, qi);
		break;
	default:
#ifdef CONFIG_FILS
		if (info_id == ANQP_FILS_REALM_INFO &&
		    !dl_list_empty(&hapd->conf->fils_realms)) {
			wpa_printf(MSG_DEBUG,
				   "ANQP: FILS Realm Information (local)");
		} else
#endif /* CONFIG_FILS */
		if (info_id == ANQP_VENUE_URL && hapd->conf->venue_url) {
			wpa_printf(MSG_DEBUG,
				   "ANQP: Venue URL (local)");
		} else if (!get_anqp_elem(hapd, info_id)) {
			wpa_printf(MSG_DEBUG, "ANQP: Unsupported Info Id %u",
				   info_id);
			break;
		}
		if (qi->num_extra_req == ANQP_MAX_EXTRA_REQ) {
			wpa_printf(MSG_DEBUG,
				   "ANQP: No more room for extra requests - ignore Info Id %u",
				   info_id);
			break;
		}
		wpa_printf(MSG_DEBUG, "ANQP: Info Id %u (local)", info_id);
		qi->extra_req[qi->num_extra_req] = info_id;
		qi->num_extra_req++;
		break;
	}
}


static void rx_anqp_query_list(struct hostapd_data *hapd,
			       const u8 *pos, const u8 *end,
			       struct anqp_query_info *qi)
{
	wpa_printf(MSG_DEBUG, "ANQP: %u Info IDs requested in Query list",
		   (unsigned int) (end - pos) / 2);

	while (end - pos >= 2) {
		rx_anqp_query_list_id(hapd, WPA_GET_LE16(pos), qi);
		pos += 2;
	}
}


#ifdef CONFIG_HS20

static void rx_anqp_hs_query_list(struct hostapd_data *hapd, u8 subtype,
				  struct anqp_query_info *qi)
{
	switch (subtype) {
	case HS20_STYPE_CAPABILITY_LIST:
		set_anqp_req(ANQP_REQ_HS_CAPABILITY_LIST, "HS Capability List",
			     1, qi);
		break;
	case HS20_STYPE_OPERATOR_FRIENDLY_NAME:
		set_anqp_req(ANQP_REQ_OPERATOR_FRIENDLY_NAME,
			     "Operator Friendly Name",
			     hapd->conf->hs20_oper_friendly_name != NULL, qi);
		break;
	case HS20_STYPE_WAN_METRICS:
		set_anqp_req(ANQP_REQ_WAN_METRICS, "WAN Metrics",
			     hapd->conf->hs20_wan_metrics != NULL, qi);
		break;
	case HS20_STYPE_CONNECTION_CAPABILITY:
		set_anqp_req(ANQP_REQ_CONNECTION_CAPABILITY,
			     "Connection Capability",
			     hapd->conf->hs20_connection_capability != NULL,
			     qi);
		break;
	case HS20_STYPE_OPERATING_CLASS:
		set_anqp_req(ANQP_REQ_OPERATING_CLASS, "Operating Class",
			     hapd->conf->hs20_operating_class != NULL, qi);
		break;
	case HS20_STYPE_OSU_PROVIDERS_LIST:
		set_anqp_req(ANQP_REQ_OSU_PROVIDERS_LIST, "OSU Providers list",
			     hapd->conf->hs20_osu_providers_count, qi);
		break;
	case HS20_STYPE_OPERATOR_ICON_METADATA:
		set_anqp_req(ANQP_REQ_OPERATOR_ICON_METADATA,
			     "Operator Icon Metadata",
			     hapd->conf->hs20_operator_icon_count, qi);
		break;
	case HS20_STYPE_OSU_PROVIDERS_NAI_LIST:
		set_anqp_req(ANQP_REQ_OSU_PROVIDERS_NAI_LIST,
			     "OSU Providers NAI List",
			     hapd->conf->hs20_osu_providers_nai_count, qi);
		break;
	default:
		wpa_printf(MSG_DEBUG, "ANQP: Unsupported HS 2.0 subtype %u",
			   subtype);
		break;
	}
}


static void rx_anqp_hs_nai_home_realm(struct hostapd_data *hapd,
				      const u8 *pos, const u8 *end,
				      struct anqp_query_info *qi)
{
	qi->request |= ANQP_REQ_NAI_HOME_REALM;
	qi->home_realm_query = pos;
	qi->home_realm_query_len = end - pos;
	if (hapd->conf->nai_realm_data != NULL) {
		wpa_printf(MSG_DEBUG, "ANQP: HS 2.0 NAI Home Realm Query "
			   "(local)");
	} else {
		wpa_printf(MSG_DEBUG, "ANQP: HS 2.0 NAI Home Realm Query not "
			   "available");
	}
}


static void rx_anqp_hs_icon_request(struct hostapd_data *hapd,
				    const u8 *pos, const u8 *end,
				    struct anqp_query_info *qi)
{
	qi->request |= ANQP_REQ_ICON_REQUEST;
	qi->icon_name = pos;
	qi->icon_name_len = end - pos;
	if (hapd->conf->hs20_icons_count) {
		wpa_printf(MSG_DEBUG, "ANQP: HS 2.0 Icon Request Query "
			   "(local)");
	} else {
		wpa_printf(MSG_DEBUG, "ANQP: HS 2.0 Icon Request Query not "
			   "available");
	}
}


static void rx_anqp_vendor_specific_hs20(struct hostapd_data *hapd,
					 const u8 *pos, const u8 *end,
					 struct anqp_query_info *qi)
{
	u8 subtype;

	if (end - pos <= 1)
		return;

	subtype = *pos++;
	pos++; /* Reserved */
	switch (subtype) {
	case HS20_STYPE_QUERY_LIST:
		wpa_printf(MSG_DEBUG, "ANQP: HS 2.0 Query List");
		while (pos < end) {
			rx_anqp_hs_query_list(hapd, *pos, qi);
			pos++;
		}
		break;
	case HS20_STYPE_NAI_HOME_REALM_QUERY:
		rx_anqp_hs_nai_home_realm(hapd, pos, end, qi);
		break;
	case HS20_STYPE_ICON_REQUEST:
		rx_anqp_hs_icon_request(hapd, pos, end, qi);
		break;
	default:
		wpa_printf(MSG_DEBUG, "ANQP: Unsupported HS 2.0 query subtype "
			   "%u", subtype);
		break;
	}
}

#endif /* CONFIG_HS20 */


#ifdef CONFIG_P2P
static void rx_anqp_vendor_specific_p2p(struct hostapd_data *hapd,
					struct anqp_query_info *qi)
{
	/*
	 * This is for P2P SD and will be taken care of by the P2P
	 * implementation. This query needs to be ignored in the generic
	 * GAS server to avoid duplicated response.
	 */
	wpa_printf(MSG_DEBUG,
		   "ANQP: Ignore WFA vendor type %u (P2P SD) in generic GAS server",
		   P2P_OUI_TYPE);
	qi->p2p_sd = 1;
	return;
}
#endif /* CONFIG_P2P */


#ifdef CONFIG_MBO

static void rx_anqp_mbo_query_list(struct hostapd_data *hapd, u8 subtype,
				  struct anqp_query_info *qi)
{
	switch (subtype) {
	case MBO_ANQP_SUBTYPE_CELL_CONN_PREF:
		set_anqp_req(ANQP_REQ_MBO_CELL_DATA_CONN_PREF,
			     "Cellular Data Connection Preference",
			     hapd->conf->mbo_cell_data_conn_pref >= 0, qi);
		break;
	default:
		wpa_printf(MSG_DEBUG, "ANQP: Unsupported MBO subtype %u",
			   subtype);
		break;
	}
}


static void rx_anqp_vendor_specific_mbo(struct hostapd_data *hapd,
					const u8 *pos, const u8 *end,
					struct anqp_query_info *qi)
{
	u8 subtype;

	if (end - pos < 1)
		return;

	subtype = *pos++;
	switch (subtype) {
	case MBO_ANQP_SUBTYPE_QUERY_LIST:
		wpa_printf(MSG_DEBUG, "ANQP: MBO Query List");
		while (pos < end) {
			rx_anqp_mbo_query_list(hapd, *pos, qi);
			pos++;
		}
		break;
	default:
		wpa_printf(MSG_DEBUG, "ANQP: Unsupported MBO query subtype %u",
			   subtype);
		break;
	}
}

#endif /* CONFIG_MBO */


static void rx_anqp_vendor_specific(struct hostapd_data *hapd,
				    const u8 *pos, const u8 *end,
				    struct anqp_query_info *qi)
{
	u32 oui;

	if (end - pos < 4) {
		wpa_printf(MSG_DEBUG, "ANQP: Too short vendor specific ANQP "
			   "Query element");
		return;
	}

	oui = WPA_GET_BE24(pos);
	pos += 3;
	if (oui != OUI_WFA) {
		wpa_printf(MSG_DEBUG, "ANQP: Unsupported vendor OUI %06x",
			   oui);
		return;
	}

	switch (*pos) {
#ifdef CONFIG_P2P
	case P2P_OUI_TYPE:
		rx_anqp_vendor_specific_p2p(hapd, qi);
		break;
#endif /* CONFIG_P2P */
#ifdef CONFIG_HS20
	case HS20_ANQP_OUI_TYPE:
		rx_anqp_vendor_specific_hs20(hapd, pos + 1, end, qi);
		break;
#endif /* CONFIG_HS20 */
#ifdef CONFIG_MBO
	case MBO_ANQP_OUI_TYPE:
		rx_anqp_vendor_specific_mbo(hapd, pos + 1, end, qi);
		break;
#endif /* CONFIG_MBO */
	default:
		wpa_printf(MSG_DEBUG, "ANQP: Unsupported WFA vendor type %u",
			   *pos);
		break;
	}
}


static void gas_serv_req_local_processing(struct hostapd_data *hapd,
					  const u8 *sa, u8 dialog_token,
					  struct anqp_query_info *qi, int prot,
					  int std_addr3)
{
	struct wpabuf *buf, *tx_buf;

	buf = gas_serv_build_gas_resp_payload(hapd, qi->request,
					      qi->home_realm_query,
					      qi->home_realm_query_len,
					      qi->icon_name, qi->icon_name_len,
					      qi->extra_req, qi->num_extra_req);
	wpa_hexdump_buf(MSG_MSGDUMP, "ANQP: Locally generated ANQP responses",
			buf);
	if (!buf)
		return;
#ifdef CONFIG_P2P
	if (wpabuf_len(buf) == 0 && qi->p2p_sd) {
		wpa_printf(MSG_DEBUG,
			   "ANQP: Do not send response to P2P SD from generic GAS service (P2P SD implementation will process this)");
		wpabuf_free(buf);
		return;
	}
#endif /* CONFIG_P2P */

	if (wpabuf_len(buf) > hapd->conf->gas_frag_limit ||
	    hapd->conf->gas_comeback_delay) {
		struct gas_dialog_info *di;
		u16 comeback_delay = 1;

		if (hapd->conf->gas_comeback_delay) {
			/* Testing - allow overriding of the delay value */
			comeback_delay = hapd->conf->gas_comeback_delay;
		}

		wpa_printf(MSG_DEBUG, "ANQP: Too long response to fit in "
			   "initial response - use GAS comeback");
		di = gas_dialog_create(hapd, sa, dialog_token);
		if (!di) {
			wpa_printf(MSG_INFO, "ANQP: Could not create dialog "
				   "for " MACSTR " (dialog token %u)",
				   MAC2STR(sa), dialog_token);
			wpabuf_free(buf);
			tx_buf = gas_anqp_build_initial_resp_buf(
				dialog_token, WLAN_STATUS_UNSPECIFIED_FAILURE,
				0, NULL);
		} else {
			di->prot = prot;
			di->sd_resp = buf;
			di->sd_resp_pos = 0;
			tx_buf = gas_anqp_build_initial_resp_buf(
				dialog_token, WLAN_STATUS_SUCCESS,
				comeback_delay, NULL);
		}
	} else {
		wpa_printf(MSG_DEBUG, "ANQP: Initial response (no comeback)");
		tx_buf = gas_anqp_build_initial_resp_buf(
			dialog_token, WLAN_STATUS_SUCCESS, 0, buf);
		wpabuf_free(buf);
	}
	if (!tx_buf)
		return;
	if (prot)
		convert_to_protected_dual(tx_buf);
	if (std_addr3)
		hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa,
					wpabuf_head(tx_buf),
					wpabuf_len(tx_buf));
	else
		hostapd_drv_send_action_addr3_ap(hapd, hapd->iface->freq, 0, sa,
						 wpabuf_head(tx_buf),
						 wpabuf_len(tx_buf));
	wpabuf_free(tx_buf);
}


#ifdef CONFIG_DPP
void gas_serv_req_dpp_processing(struct hostapd_data *hapd,
				 const u8 *sa, u8 dialog_token,
				 int prot, struct wpabuf *buf)
{
	struct wpabuf *tx_buf;

	if (wpabuf_len(buf) > hapd->conf->gas_frag_limit ||
	    hapd->conf->gas_comeback_delay) {
		struct gas_dialog_info *di;
		u16 comeback_delay = 1;

		if (hapd->conf->gas_comeback_delay) {
			/* Testing - allow overriding of the delay value */
			comeback_delay = hapd->conf->gas_comeback_delay;
		}

		wpa_printf(MSG_DEBUG,
			   "DPP: Too long response to fit in initial response - use GAS comeback");
		di = gas_dialog_create(hapd, sa, dialog_token);
		if (!di) {
			wpa_printf(MSG_INFO, "DPP: Could not create dialog for "
				   MACSTR " (dialog token %u)",
				   MAC2STR(sa), dialog_token);
			wpabuf_free(buf);
			tx_buf = gas_build_initial_resp(
				dialog_token, WLAN_STATUS_UNSPECIFIED_FAILURE,
				0, 10);
			if (tx_buf)
				gas_serv_write_dpp_adv_proto(tx_buf);
		} else {
			di->prot = prot;
			di->sd_resp = buf;
			di->sd_resp_pos = 0;
			di->dpp = 1;
			tx_buf = gas_build_initial_resp(
				dialog_token, WLAN_STATUS_SUCCESS,
				comeback_delay, 10 + 2);
			if (tx_buf) {
				gas_serv_write_dpp_adv_proto(tx_buf);
				wpabuf_put_le16(tx_buf, 0);
			}
		}
	} else {
		wpa_printf(MSG_DEBUG,
			   "DPP: GAS Initial response (no comeback)");
		tx_buf = gas_build_initial_resp(
			dialog_token, WLAN_STATUS_SUCCESS, 0,
			10 + 2 + wpabuf_len(buf));
		if (tx_buf) {
			gas_serv_write_dpp_adv_proto(tx_buf);
			wpabuf_put_le16(tx_buf, wpabuf_len(buf));
			wpabuf_put_buf(tx_buf, buf);
			hostapd_dpp_gas_status_handler(hapd, 1);
		}
		wpabuf_free(buf);
	}
	if (!tx_buf)
		return;
	if (prot)
		convert_to_protected_dual(tx_buf);
	hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa,
				wpabuf_head(tx_buf),
				wpabuf_len(tx_buf));
	wpabuf_free(tx_buf);
}
#endif /* CONFIG_DPP */


static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd,
					const u8 *sa,
					const u8 *data, size_t len, int prot,
					int std_addr3)
{
	const u8 *pos = data;
	const u8 *end = data + len;
	const u8 *next;
	u8 dialog_token;
	u16 slen;
	struct anqp_query_info qi;
	const u8 *adv_proto;
#ifdef CONFIG_DPP
	int dpp = 0;
#endif /* CONFIG_DPP */

	if (len < 1 + 2)
		return;

	os_memset(&qi, 0, sizeof(qi));

	dialog_token = *pos++;
	wpa_msg(hapd->msg_ctx, MSG_DEBUG,
		"GAS: GAS Initial Request from " MACSTR " (dialog token %u) ",
		MAC2STR(sa), dialog_token);

	if (*pos != WLAN_EID_ADV_PROTO) {
		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
			"GAS: Unexpected IE in GAS Initial Request: %u", *pos);
		return;
	}
	adv_proto = pos++;

	slen = *pos++;
	if (slen > end - pos || slen < 2) {
		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
			"GAS: Invalid IE in GAS Initial Request");
		return;
	}
	next = pos + slen;
	pos++; /* skip QueryRespLenLimit and PAME-BI */

#ifdef CONFIG_DPP
	if (slen == 8 && *pos == WLAN_EID_VENDOR_SPECIFIC &&
	    pos[1] == 5 && WPA_GET_BE24(&pos[2]) == OUI_WFA &&
	    pos[5] == DPP_OUI_TYPE && pos[6] == 0x01) {
		wpa_printf(MSG_DEBUG, "DPP: Configuration Request");
		dpp = 1;
	} else
#endif /* CONFIG_DPP */

	if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) {
		struct wpabuf *buf;
		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
			"GAS: Unsupported GAS advertisement protocol id %u",
			*pos);
		if (sa[0] & 0x01)
			return; /* Invalid source address - drop silently */
		buf = gas_build_initial_resp(
			dialog_token, WLAN_STATUS_GAS_ADV_PROTO_NOT_SUPPORTED,
			0, 2 + slen + 2);
		if (buf == NULL)
			return;
		wpabuf_put_data(buf, adv_proto, 2 + slen);
		wpabuf_put_le16(buf, 0); /* Query Response Length */
		if (prot)
			convert_to_protected_dual(buf);
		if (std_addr3)
			hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa,
						wpabuf_head(buf),
						wpabuf_len(buf));
		else
			hostapd_drv_send_action_addr3_ap(hapd,
							 hapd->iface->freq, 0,
							 sa, wpabuf_head(buf),
							 wpabuf_len(buf));
		wpabuf_free(buf);
		return;
	}

	pos = next;
	/* Query Request */
	if (end - pos < 2)
		return;
	slen = WPA_GET_LE16(pos);
	pos += 2;
	if (slen > end - pos)
		return;
	end = pos + slen;

#ifdef CONFIG_DPP
	if (dpp) {
		struct wpabuf *msg;

		msg = hostapd_dpp_gas_req_handler(hapd, sa, pos, slen,
						  data, len);
		if (!msg)
			return;
		gas_serv_req_dpp_processing(hapd, sa, dialog_token, prot, msg);
		return;
	}
#endif /* CONFIG_DPP */

	/* ANQP Query Request */
	while (pos < end) {
		u16 info_id, elen;

		if (end - pos < 4)
			return;

		info_id = WPA_GET_LE16(pos);
		pos += 2;
		elen = WPA_GET_LE16(pos);
		pos += 2;

		if (elen > end - pos) {
			wpa_printf(MSG_DEBUG, "ANQP: Invalid Query Request");
			return;
		}

		switch (info_id) {
		case ANQP_QUERY_LIST:
			rx_anqp_query_list(hapd, pos, pos + elen, &qi);
			break;
		case ANQP_VENDOR_SPECIFIC:
			rx_anqp_vendor_specific(hapd, pos, pos + elen, &qi);
			break;
		default:
			wpa_printf(MSG_DEBUG, "ANQP: Unsupported Query "
				   "Request element %u", info_id);
			break;
		}

		pos += elen;
	}

	gas_serv_req_local_processing(hapd, sa, dialog_token, &qi, prot,
				      std_addr3);
}


static void gas_serv_rx_gas_comeback_req(struct hostapd_data *hapd,
					 const u8 *sa,
					 const u8 *data, size_t len, int prot,
					 int std_addr3)
{
	struct gas_dialog_info *dialog;
	struct wpabuf *buf, *tx_buf;
	u8 dialog_token;
	size_t frag_len;
	int more = 0;

	wpa_hexdump(MSG_DEBUG, "GAS: RX GAS Comeback Request", data, len);
	if (len < 1)
		return;
	dialog_token = *data;
	wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: Dialog Token: %u",
		dialog_token);

	dialog = gas_serv_dialog_find(hapd, sa, dialog_token);
	if (!dialog) {
		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: No pending SD "
			"response fragment for " MACSTR " dialog token %u",
			MAC2STR(sa), dialog_token);

		if (sa[0] & 0x01)
			return; /* Invalid source address - drop silently */
		tx_buf = gas_anqp_build_comeback_resp_buf(
			dialog_token, WLAN_STATUS_NO_OUTSTANDING_GAS_REQ, 0, 0,
			0, NULL);
		if (tx_buf == NULL)
			return;
		goto send_resp;
	}

	frag_len = wpabuf_len(dialog->sd_resp) - dialog->sd_resp_pos;
	if (frag_len > hapd->conf->gas_frag_limit) {
		frag_len = hapd->conf->gas_frag_limit;
		more = 1;
	}
	wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: resp frag_len %u",
		(unsigned int) frag_len);
	buf = wpabuf_alloc_copy(wpabuf_head_u8(dialog->sd_resp) +
				dialog->sd_resp_pos, frag_len);
	if (buf == NULL) {
		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: Failed to allocate "
			"buffer");
		gas_serv_dialog_clear(dialog);
		return;
	}
#ifdef CONFIG_DPP
	if (dialog->dpp) {
		tx_buf = gas_build_comeback_resp(dialog_token,
						 WLAN_STATUS_SUCCESS,
						 dialog->sd_frag_id, more, 0,
						 10 + 2 + frag_len);
		if (tx_buf) {
			gas_serv_write_dpp_adv_proto(tx_buf);
			wpabuf_put_le16(tx_buf, frag_len);
			wpabuf_put_buf(tx_buf, buf);
		}
	} else
#endif /* CONFIG_DPP */
	tx_buf = gas_anqp_build_comeback_resp_buf(dialog_token,
						  WLAN_STATUS_SUCCESS,
						  dialog->sd_frag_id,
						  more, 0, buf);
	wpabuf_free(buf);
	if (tx_buf == NULL) {
		gas_serv_dialog_clear(dialog);
		return;
	}
	wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: Tx GAS Comeback Response "
		"(frag_id %d more=%d frag_len=%d)",
		dialog->sd_frag_id, more, (int) frag_len);
	dialog->sd_frag_id++;
	dialog->sd_resp_pos += frag_len;

	if (more) {
		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: %d more bytes remain "
			"to be sent",
			(int) (wpabuf_len(dialog->sd_resp) -
			       dialog->sd_resp_pos));
	} else {
		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: All fragments of "
			"SD response sent");
#ifdef CONFIG_DPP
		if (dialog->dpp)
			hostapd_dpp_gas_status_handler(hapd, 1);
#endif /* CONFIG_DPP */
		gas_serv_dialog_clear(dialog);
		gas_serv_free_dialogs(hapd, sa);
	}

send_resp:
	if (prot)
		convert_to_protected_dual(tx_buf);
	if (std_addr3)
		hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa,
					wpabuf_head(tx_buf),
					wpabuf_len(tx_buf));
	else
		hostapd_drv_send_action_addr3_ap(hapd, hapd->iface->freq, 0, sa,
						 wpabuf_head(tx_buf),
						 wpabuf_len(tx_buf));
	wpabuf_free(tx_buf);
}


static void gas_serv_rx_public_action(void *ctx, const u8 *buf, size_t len,
				      int freq)
{
	struct hostapd_data *hapd = ctx;
	const struct ieee80211_mgmt *mgmt;
	const u8 *sa, *data;
	int prot, std_addr3;

	mgmt = (const struct ieee80211_mgmt *) buf;
	if (len < IEEE80211_HDRLEN + 2)
		return;
	if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
	    mgmt->u.action.category != WLAN_ACTION_PROTECTED_DUAL)
		return;
	/*
	 * Note: Public Action and Protected Dual of Public Action frames share
	 * the same payload structure, so it is fine to use definitions of
	 * Public Action frames to process both.
	 */
	prot = mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL;
	sa = mgmt->sa;
	if (hapd->conf->gas_address3 == 1)
		std_addr3 = 1;
	else if (hapd->conf->gas_address3 == 2)
		std_addr3 = 0;
	else
		std_addr3 = is_broadcast_ether_addr(mgmt->bssid);
	len -= IEEE80211_HDRLEN + 1;
	data = buf + IEEE80211_HDRLEN + 1;
	switch (data[0]) {
	case WLAN_PA_GAS_INITIAL_REQ:
		gas_serv_rx_gas_initial_req(hapd, sa, data + 1, len - 1, prot,
					    std_addr3);
		break;
	case WLAN_PA_GAS_COMEBACK_REQ:
		gas_serv_rx_gas_comeback_req(hapd, sa, data + 1, len - 1, prot,
					     std_addr3);
		break;
	}
}


int gas_serv_init(struct hostapd_data *hapd)
{
	hapd->public_action_cb2 = gas_serv_rx_public_action;
	hapd->public_action_cb2_ctx = hapd;
	return 0;
}


void gas_serv_deinit(struct hostapd_data *hapd)
{
}
