Accumulative patch from commit 565110cd554801fa301c55010b3e9e14f43d7973

nl80211: Include interface name in more debug prints
Convert WPS NFC python scripts from using wpactrl to wpaspy
wpa_supplicant: Fix lookup of cached PMKSA
Add capability flag for IBSS and add get_capability modes
hostapd: Fix client reassociation after disconnect due to ACK failure
Fix build with CONFIG_NO_CONFIG_BLOBS
Fix build without CONFIG_CTRL_IFACE or CONFIG_NO_STDOUT_DEBUG
libtommath: Avoid a compiler warning on unused variable
libtommath: Condition fast_s_mp_mul_digs() on LTM_FAST
P2P: Remove persistent group peer if it rejects invitation
P2P: Allow shared interface channel preference to be ignored
P2P: Fix shared frequency preference for concurrent operations
P2P: Use best-overall channel in p2p_reselect_channel()
P2P: Allow all channels for multi-channel concurrency (no negotiation)
TDLS: Disable link to existing peer with lower address
Fix compiler warning when CONFIG_IEEE80211R is not included
WPS NFC: Fix build without CONFIG_WPS_ER
FT: Add support for IEEE 802.11r with driver-based SME

Change-Id: I1d5ced870c33d5cb73ecc6f04e272a3cf50f344a
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 6860765..1ffe05e 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -3019,6 +3019,7 @@
 	{ INT(p2p_go_ht40), 0 },
 	{ INT(p2p_disabled), 0 },
 	{ INT(p2p_no_group_iface), 0 },
+	{ INT_RANGE(p2p_ignore_shared_freq, 0, 1), 0 },
 #endif /* CONFIG_P2P */
 	{ FUNC(country), CFG_CHANGED_COUNTRY },
 	{ INT(bss_max_count), 0 },
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 2e3e76b..03fe6fc 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -571,6 +571,7 @@
 	int p2p_intra_bss;
 	unsigned int num_p2p_pref_chan;
 	struct p2p_channel *p2p_pref_chan;
+	int p2p_ignore_shared_freq;
 
 	struct wpabuf *wps_vendor_ext_m1;
 
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index d636a67..a8c57eb 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -2869,6 +2869,46 @@
 }
 
 
+static int ctrl_iface_get_capability_modes(int res, char *strict,
+					   struct wpa_driver_capa *capa,
+					   char *buf, size_t buflen)
+{
+	int ret, first = 1;
+	char *pos, *end;
+	size_t len;
+
+	pos = buf;
+	end = pos + buflen;
+
+	if (res < 0) {
+		if (strict)
+			return 0;
+		len = os_strlcpy(buf, "IBSS AP", buflen);
+		if (len >= buflen)
+			return -1;
+		return len;
+	}
+
+	if (capa->flags & WPA_DRIVER_FLAGS_IBSS) {
+		ret = os_snprintf(pos, end - pos, "%sIBSS", first ? "" : " ");
+		if (ret < 0 || ret >= end - pos)
+			return pos - buf;
+		pos += ret;
+		first = 0;
+	}
+
+	if (capa->flags & WPA_DRIVER_FLAGS_AP) {
+		ret = os_snprintf(pos, end - pos, "%sAP", first ? "" : " ");
+		if (ret < 0 || ret >= end - pos)
+			return pos - buf;
+		pos += ret;
+		first = 0;
+	}
+
+	return pos - buf;
+}
+
+
 static int ctrl_iface_get_capability_channels(struct wpa_supplicant *wpa_s,
 					      char *buf, size_t buflen)
 {
@@ -2969,6 +3009,10 @@
 		return ctrl_iface_get_capability_auth_alg(res, strict, &capa,
 							  buf, buflen);
 
+	if (os_strcmp(field, "modes") == 0)
+		return ctrl_iface_get_capability_modes(res, strict, &capa,
+						       buf, buflen);
+
 	if (os_strcmp(field, "channels") == 0)
 		return ctrl_iface_get_capability_channels(wpa_s, buf, buflen);
 
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 5b4a0a4..136dd1a 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -2430,6 +2430,7 @@
 		  END_ARGS
 	  }
 	},
+#ifndef CONFIG_NO_CONFIG_BLOBS
 	{ "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
 	  (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
 	  {
@@ -2453,6 +2454,7 @@
 		  END_ARGS
 	  }
 	},
+#endif /* CONFIG_NO_CONFIG_BLOBS */
 #ifdef CONFIG_WPS
 	{ "Start", WPAS_DBUS_NEW_IFACE_WPS,
 	  (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 8088755..335c25f 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -1696,6 +1696,8 @@
 }
 
 
+#ifndef CONFIG_NO_CONFIG_BLOBS
+
 /**
  * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
  * @message: Pointer to incoming dbus message
@@ -1860,6 +1862,9 @@
 
 }
 
+#endif /* CONFIG_NO_CONFIG_BLOBS */
+
+
 /*
  * wpas_dbus_handler_flush_bss - Flush the BSS cache
  * @message: Pointer to incoming dbus message
diff --git a/wpa_supplicant/dbus/dbus_old.c b/wpa_supplicant/dbus/dbus_old.c
index 5f298e7..85d8a78 100644
--- a/wpa_supplicant/dbus/dbus_old.c
+++ b/wpa_supplicant/dbus/dbus_old.c
@@ -268,10 +268,12 @@
 			reply = wpas_dbus_iface_get_state(message, wpa_s);
 		else if (!strcmp(method, "scanning"))
 			reply = wpas_dbus_iface_get_scanning(message, wpa_s);
+#ifndef CONFIG_NO_CONFIG_BLOBS
 		else if (!strcmp(method, "setBlobs"))
 			reply = wpas_dbus_iface_set_blobs(message, wpa_s);
 		else if (!strcmp(method, "removeBlobs"))
 			reply = wpas_dbus_iface_remove_blobs(message, wpa_s);
+#endif /* CONFIG_NO_CONFIG_BLOBS */
 #ifdef CONFIG_WPS
 		else if (!os_strcmp(method, "wpsPbc"))
 			reply = wpas_dbus_iface_wps_pbc(message, wpa_s);
diff --git a/wpa_supplicant/dbus/dbus_old_handlers.c b/wpa_supplicant/dbus/dbus_old_handlers.c
index 68e5515..e565de9 100644
--- a/wpa_supplicant/dbus/dbus_old_handlers.c
+++ b/wpa_supplicant/dbus/dbus_old_handlers.c
@@ -1300,6 +1300,8 @@
 }
 
 
+#ifndef CONFIG_NO_CONFIG_BLOBS
+
 /**
  * wpas_dbus_iface_set_blobs - Store named binary blobs (ie, for certificates)
  * @message: Pointer to incoming dbus message
@@ -1429,6 +1431,8 @@
 	return wpas_dbus_new_success_reply(message);
 }
 
+#endif /* CONFIG_NO_CONFIG_BLOBS */
+
 
 /**
  * wpas_dbus_iface_flush - Clear BSS of old or all inactive entries
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 871e99c..6b0b6f9 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1477,6 +1477,9 @@
 {
 	int l, len, found = 0, wpa_found, rsn_found;
 	const u8 *p;
+#ifdef CONFIG_IEEE80211R
+	u8 bssid[ETH_ALEN];
+#endif /* CONFIG_IEEE80211R */
 
 	wpa_dbg(wpa_s, MSG_DEBUG, "Association info event");
 	if (data->assoc_info.req_ies)
@@ -1531,7 +1534,6 @@
 #ifdef CONFIG_IEEE80211R
 #ifdef CONFIG_SME
 	if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FT) {
-		u8 bssid[ETH_ALEN];
 		if (wpa_drv_get_bssid(wpa_s, bssid) < 0 ||
 		    wpa_ft_validate_reassoc_resp(wpa_s->wpa,
 						 data->assoc_info.resp_ies,
@@ -1589,6 +1591,23 @@
 	}
 #endif /* CONFIG_SME */
 
+	/* Process FT when SME is in the driver */
+	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
+	    wpa_ft_is_completed(wpa_s->wpa)) {
+		if (wpa_drv_get_bssid(wpa_s, bssid) < 0 ||
+		    wpa_ft_validate_reassoc_resp(wpa_s->wpa,
+						 data->assoc_info.resp_ies,
+						 data->assoc_info.resp_ies_len,
+						 bssid) < 0) {
+			wpa_dbg(wpa_s, MSG_DEBUG, "FT: Validation of "
+				"Reassociation Response failed");
+			wpa_supplicant_deauthenticate(
+				wpa_s, WLAN_REASON_INVALID_IE);
+			return -1;
+		}
+		wpa_dbg(wpa_s, MSG_DEBUG, "FT: Reassociation Response done");
+	}
+
 	wpa_sm_set_ft_params(wpa_s->wpa, data->assoc_info.resp_ies,
 			     data->assoc_info.resp_ies_len);
 #endif /* CONFIG_IEEE80211R */
diff --git a/wpa_supplicant/examples/wps-nfc.py b/wpa_supplicant/examples/wps-nfc.py
index 9a6da5f..86473cd 100755
--- a/wpa_supplicant/examples/wps-nfc.py
+++ b/wpa_supplicant/examples/wps-nfc.py
@@ -20,7 +20,7 @@
 import logging
 logging.basicConfig()
 
-import wpactrl
+import wpaspy
 
 wpas_ctrl = '/var/run/wpa_supplicant'
 
@@ -39,10 +39,9 @@
 
     for ctrl in ifaces:
         try:
-            wpas = wpactrl.WPACtrl(ctrl)
+            wpas = wpaspy.Ctrl(ctrl)
             return wpas
-        except wpactrl.error, error:
-            print "Error: ", error
+        except Exception, e:
             pass
     return None
 
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index db7cd6e..6246dc0 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -100,6 +100,19 @@
 static int wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s);
 
 
+static void wpas_p2p_set_own_freq_preference(struct wpa_supplicant *wpa_s,
+					     int freq)
+{
+	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
+		return;
+	if (freq > 0 &&
+	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
+	    wpa_s->parent->conf->p2p_ignore_shared_freq)
+		freq = 0;
+	p2p_set_own_freq_preference(wpa_s->global->p2p, freq);
+}
+
+
 static void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s,
 				      struct wpa_scan_results *scan_res)
 {
@@ -2471,11 +2484,14 @@
 	}
 
 accept_inv:
+	wpas_p2p_set_own_freq_preference(wpa_s, 0);
+
 	if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, cur_bssid) == 0 &&
 	    wpa_s->assoc_freq) {
 		wpa_printf(MSG_DEBUG, "P2P: Trying to force channel to match "
 			   "the channel we are already using");
 		*force_freq = wpa_s->assoc_freq;
+		wpas_p2p_set_own_freq_preference(wpa_s, wpa_s->assoc_freq);
 	}
 
 	res = wpa_drv_shared_freq(wpa_s);
@@ -2484,6 +2500,7 @@
 			   "with the channel we are already using on a "
 			   "shared interface");
 		*force_freq = res;
+		wpas_p2p_set_own_freq_preference(wpa_s, res);
 	}
 
 	return P2P_SC_SUCCESS;
@@ -2554,8 +2571,68 @@
 }
 
 
+static void wpas_remove_persistent_peer(struct wpa_supplicant *wpa_s,
+					struct wpa_ssid *ssid,
+					const u8 *peer)
+{
+	size_t i;
+
+	if (ssid == NULL)
+		return;
+
+	for (i = 0; ssid->p2p_client_list && i < ssid->num_p2p_clients; i++) {
+		if (os_memcmp(ssid->p2p_client_list + i * ETH_ALEN, peer,
+			      ETH_ALEN) == 0)
+			break;
+	}
+	if (i >= ssid->num_p2p_clients) {
+		if (ssid->mode != WPAS_MODE_P2P_GO &&
+		    os_memcmp(ssid->bssid, peer, ETH_ALEN) == 0) {
+			wpa_printf(MSG_DEBUG, "P2P: Remove persistent group %d "
+				   "due to invitation result", ssid->id);
+			wpas_notify_network_removed(wpa_s, ssid);
+			wpa_config_remove_network(wpa_s->conf, ssid->id);
+			return;
+		}
+		return; /* Peer not found in client list */
+	}
+
+	wpa_printf(MSG_DEBUG, "P2P: Remove peer " MACSTR " from persistent "
+		   "group %d client list due to invitation result",
+		   MAC2STR(peer), ssid->id);
+	os_memmove(ssid->p2p_client_list + i * ETH_ALEN,
+		   ssid->p2p_client_list + (i + 1) * ETH_ALEN,
+		   (ssid->num_p2p_clients - i - 1) * ETH_ALEN);
+	ssid->num_p2p_clients--;
+#ifndef CONFIG_NO_CONFIG_WRITE
+	if (wpa_s->parent->conf->update_config &&
+	    wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
+		wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
+#endif /* CONFIG_NO_CONFIG_WRITE */
+}
+
+
+static void wpas_remove_persistent_client(struct wpa_supplicant *wpa_s,
+					  const u8 *peer)
+{
+	struct wpa_ssid *ssid;
+
+	wpa_s = wpa_s->global->p2p_invite_group;
+	if (wpa_s == NULL)
+		return; /* No known invitation group */
+	ssid = wpa_s->current_ssid;
+	if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
+	    !ssid->p2p_persistent_group)
+		return; /* Not operating as a GO in persistent group */
+	ssid = wpas_p2p_get_persistent(wpa_s->parent, peer,
+				       ssid->ssid, ssid->ssid_len);
+	wpas_remove_persistent_peer(wpa_s, ssid, peer);
+}
+
+
 static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
-				   const struct p2p_channels *channels)
+				   const struct p2p_channels *channels,
+				   const u8 *peer)
 {
 	struct wpa_supplicant *wpa_s = ctx;
 	struct wpa_ssid *ssid;
@@ -2570,8 +2647,13 @@
 	}
 	wpas_notify_p2p_invitation_result(wpa_s, status, bssid);
 
-	if (wpa_s->pending_invite_ssid_id == -1)
+	wpa_printf(MSG_DEBUG, "P2P: Invitation result - status=%d peer=" MACSTR,
+		   status, MAC2STR(peer));
+	if (wpa_s->pending_invite_ssid_id == -1) {
+		if (status == P2P_SC_FAIL_UNKNOWN_GROUP)
+			wpas_remove_persistent_client(wpa_s, peer);
 		return; /* Invitation to active group */
+	}
 
 	if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
 		wpa_printf(MSG_DEBUG, "P2P: Waiting for peer to start another "
@@ -2580,6 +2662,11 @@
 	}
 
 	if (status != P2P_SC_SUCCESS) {
+		if (status == P2P_SC_FAIL_UNKNOWN_GROUP) {
+			ssid = wpa_config_get_network(
+				wpa_s->conf, wpa_s->pending_invite_ssid_id);
+			wpas_remove_persistent_peer(wpa_s, ssid, peer);
+		}
 		wpas_p2p_remove_pending_group_interface(wpa_s);
 		return;
 	}
@@ -3824,6 +3911,7 @@
 				   &oper_freq);
 	if (res)
 		return res;
+	wpas_p2p_set_own_freq_preference(wpa_s, oper_freq);
 
 	wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s);
 
@@ -4056,18 +4144,45 @@
 
 	if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid) == 0 &&
 	    wpa_s->assoc_freq && !freq) {
-		wpa_printf(MSG_DEBUG, "P2P: Force GO on the channel we are "
-			   "already using");
-		params->freq = wpa_s->assoc_freq;
-		if (!freq_included(channels, params->freq)) {
-			wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not "
-				   "accepted", params->freq);
-			return -1;
+		if (!p2p_supported_freq(wpa_s->global->p2p, wpa_s->assoc_freq)
+		    || !freq_included(channels, wpa_s->assoc_freq)) {
+			if (wpa_s->drv_flags &
+			    WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) {
+				wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on "
+					   "the channel we are already using "
+					   "(%u MHz) - allow multi-channel "
+					   "concurrency", wpa_s->assoc_freq);
+			} else {
+				wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on "
+					   "the channel we are already using "
+					   "(%u MHz)", wpa_s->assoc_freq);
+				return -1;
+			}
+		} else {
+			wpa_printf(MSG_DEBUG, "P2P: Force GO on the channel we "
+				   "are already using (%u MHz)",
+				   wpa_s->assoc_freq);
+			params->freq = wpa_s->assoc_freq;
 		}
 	}
 
 	res = wpa_drv_shared_freq(wpa_s);
-	if (res > 0 && !freq) {
+	if (res > 0 && !freq &&
+	    (!p2p_supported_freq(wpa_s->global->p2p, res) ||
+	     !freq_included(channels, res))) {
+		if (wpa_s->drv_flags &
+		    WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) {
+			wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on the "
+				   "channel we are already using on a shared "
+				   "interface (%u MHz) - allow multi-channel "
+				   "concurrency", res);
+		} else {
+			wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on the "
+				   "channel we are already using on a shared "
+				   "interface (%u MHz)", res);
+			return -1;
+		}
+	} else if (res > 0 && !freq) {
 		wpa_printf(MSG_DEBUG, "P2P: Force GO on the channel we are "
 			   "already using on a shared interface");
 		params->freq = res;
@@ -4730,6 +4845,7 @@
 	int force_freq = 0, oper_freq = 0;
 	int res;
 
+	wpa_s->global->p2p_invite_group = NULL;
 	if (peer_addr)
 		os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
 	else
@@ -4822,6 +4938,7 @@
 		return -1;
 	}
 
+	wpa_s->global->p2p_invite_group = wpa_s;
 	persistent = ssid->p2p_persistent_group &&
 		wpas_p2p_get_persistent(wpa_s->parent, peer_addr,
 					ssid->ssid, ssid->ssid_len);
@@ -4868,6 +4985,7 @@
 				   &oper_freq);
 	if (res)
 		return res;
+	wpas_p2p_set_own_freq_preference(wpa_s, oper_freq);
 
 	return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
 			  ssid->ssid, ssid->ssid_len, force_freq,
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 662a131..90e4169 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -2483,7 +2483,7 @@
 	  "<<idx> | <bssid>> = get detailed scan result info" },
 	{ "get_capability", wpa_cli_cmd_get_capability, NULL,
 	  cli_cmd_flag_none,
-	  "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels> "
+	  "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/modes> "
 	  "= get capabilies" },
 	{ "reconfigure", wpa_cli_cmd_reconfigure, NULL,
 	  cli_cmd_flag_none,
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 7d50e4d..7a93716 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -661,8 +661,8 @@
 		wpa_supplicant_notify_scanning(wpa_s, 0);
 
 	if (state == WPA_COMPLETED && wpa_s->new_connection) {
-#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
 		struct wpa_ssid *ssid = wpa_s->current_ssid;
+#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
 			MACSTR " completed (auth) [id=%d id_str=%s]",
 			MAC2STR(wpa_s->bssid),
@@ -1361,8 +1361,7 @@
 				     ssid->proactive_key_caching) &&
 			(ssid->proto & WPA_PROTO_RSN);
 		if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
-					    wpa_s->current_ssid,
-					    try_opportunistic) == 0)
+					    ssid, try_opportunistic) == 0)
 			eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
 		wpa_ie_len = sizeof(wpa_ie);
 		if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
@@ -3146,6 +3145,8 @@
 
 	if (global->p2p_group_formation == wpa_s)
 		global->p2p_group_formation = NULL;
+	if (global->p2p_invite_group == wpa_s)
+		global->p2p_invite_group = NULL;
 	wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
 	os_free(wpa_s);
 
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 4ec15c1..5465c4f 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -228,6 +228,7 @@
 	struct p2p_data *p2p;
 	struct wpa_supplicant *p2p_init_wpa_s;
 	struct wpa_supplicant *p2p_group_formation;
+	struct wpa_supplicant *p2p_invite_group;
 	u8 p2p_dev_addr[ETH_ALEN];
 	struct dl_list p2p_srv_bonjour; /* struct p2p_srv_bonjour */
 	struct dl_list p2p_srv_upnp; /* struct p2p_srv_upnp */
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 7585b86..cd51873 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -798,8 +798,10 @@
 	ctx->eapol_done_cb = wpa_supplicant_notify_eapol_done;
 	ctx->eapol_send = wpa_supplicant_eapol_send;
 	ctx->set_wep_key = wpa_eapol_set_wep_key;
+#ifndef CONFIG_NO_CONFIG_BLOBS
 	ctx->set_config_blob = wpa_supplicant_set_config_blob;
 	ctx->get_config_blob = wpa_supplicant_get_config_blob;
+#endif /* CONFIG_NO_CONFIG_BLOBS */
 	ctx->aborted_cached = wpa_supplicant_aborted_cached;
 	ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path;
 	ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 509a7c0..1b1b5f7 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -2007,6 +2007,7 @@
 struct wpabuf * wpas_wps_er_nfc_handover_sel(struct wpa_supplicant *wpa_s,
 					     int ndef, const char *uuid)
 {
+#ifdef CONFIG_WPS_ER
 	struct wpabuf *ret;
 	u8 u[UUID_LEN];
 
@@ -2031,6 +2032,9 @@
 	}
 
 	return ret;
+#else /* CONFIG_WPS_ER */
+	return NULL;
+#endif /* CONFIG_WPS_ER */
 }
 #endif /* CONFIG_WPS_NFC */