Cumulative patch from commit 39a5800f7c2a9de743c673a78929ac46a099b1a4

39a5800 wpa_supplicant: Allow disabling LDPC
7230040 Interworking: Read IMSI if not read at supplicant start
62f736d Interworking: Init scard when a credential requires SIM access
729897a Interworking: Fix incorrect compile PCSC flag
21611ea edit: Increase buffer size to 4096 bytes
0b2c59e OSU server: Add example scripts for Hotspot 2.0 PKI
0f27c20 HS 2.0R2: Add example OSU SPP server implementation
1e03c6c XML: Remove forgotten, unused definition of debug_print_func
5cfc87b Make hs20_wan_metrics parser error print more helpful
4be20bf Fix validation of anqp_3gpp_cell_net configuration parameter
23587e3 Remove duplicated vht_capab parser entry
18a8e55 Notify STA of disconnection based on ACL change
8943cc9 RADIUS server: Add support for MAC ACL
dc87541 Clean up debug print for PSK file search
bbbacbf DFS: Print CAC info in ctrl_iface STATUS command
ace0fbd P2P: Fix segfault when PBC overlap is detected
cf15b15 Add writing of network block ocsp parameter
5c9da16 nl80211: Set all BSS interfaces down when tearing down AP in MBSS mode
f1c4dbf wpa_supplicant: Remove pending sme-connect radio work
4f560cd wpa_supplicant: Override HT A-MPDU size if VHT A-MPDU was overridden
3ae8b7b hostapd: Add vendor command support
782e2f7 P2P: Do not initiate scan on P2P Device when enabled
74a1319 Fix issue with incorrect secondary_channel in HT40/HT80
96ecea5 Pass TDLS peer capability information in tdls_mgmt
78cd7e6 Sync with wireless-testing.git include/uapi/linux/nl80211.h
b36935b nl80211: Fix EAPOL frames not being delivered
6997f8b nl80211: Set interface address even if using old interface
9b4d9c8 nl80211: Print if_indices list in debug log
762c41a eloop: Add assert() on negative fd when using select() code path
978c673 Add a note on using 'iw list' to determine multi-BSS support

Change-Id: I89af7f8d92ed706c8909ed3cc9c49d6e1277a2b0
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index 71163c3..3450ffe 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -260,8 +260,10 @@
 		info_ids[num_info_ids++] = ANQP_IP_ADDR_TYPE_AVAILABILITY;
 	if (all || cred_with_nai_realm(wpa_s))
 		info_ids[num_info_ids++] = ANQP_NAI_REALM;
-	if (all || cred_with_3gpp(wpa_s))
+	if (all || cred_with_3gpp(wpa_s)) {
 		info_ids[num_info_ids++] = ANQP_3GPP_CELLULAR_NETWORK;
+		wpa_supplicant_scard_init(wpa_s, NULL);
+	}
 	if (all || cred_with_domain(wpa_s))
 		info_ids[num_info_ids++] = ANQP_DOMAIN_NAME;
 	wpa_hexdump(MSG_DEBUG, "Interworking: ANQP Query info",
@@ -1748,6 +1750,31 @@
 }
 
 
+#ifdef PCSC_FUNCS
+static int interworking_pcsc_read_imsi(struct wpa_supplicant *wpa_s)
+{
+	size_t len;
+
+	if (wpa_s->imsi[0] && wpa_s->mnc_len)
+		return 0;
+
+	len = sizeof(wpa_s->imsi) - 1;
+	if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
+		scard_deinit(wpa_s->scard);
+		wpa_s->scard = NULL;
+		wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
+		return -1;
+	}
+	wpa_s->imsi[len] = '\0';
+	wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
+	wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
+		   wpa_s->imsi, wpa_s->mnc_len);
+
+	return 0;
+}
+#endif /* PCSC_FUNCS */
+
+
 static struct wpa_cred * interworking_credentials_available_3gpp(
 	struct wpa_supplicant *wpa_s, struct wpa_bss *bss, int ignore_bw,
 	int *excluded)
@@ -1786,8 +1813,9 @@
 		size_t msin_len;
 
 #ifdef PCSC_FUNCS
-		if (cred->pcsc && wpa_s->conf->pcsc_reader && wpa_s->scard &&
-		    wpa_s->imsi[0]) {
+		if (cred->pcsc && wpa_s->scard) {
+			if (interworking_pcsc_read_imsi(wpa_s) < 0)
+				continue;
 			imsi = wpa_s->imsi;
 			mnc_len = wpa_s->mnc_len;
 			goto compare;
@@ -2043,13 +2071,14 @@
 	int mnc_len = 0;
 	if (cred->imsi)
 		imsi = cred->imsi;
-#ifdef CONFIG_PCSC
-	else if (cred->pcsc && wpa_s->conf->pcsc_reader &&
-		 wpa_s->scard && wpa_s->imsi[0]) {
+#ifdef PCSC_FUNCS
+	else if (cred->pcsc && wpa_s->scard) {
+		if (interworking_pcsc_read_imsi(wpa_s) < 0)
+			return -1;
 		imsi = wpa_s->imsi;
 		mnc_len = wpa_s->mnc_len;
 	}
-#endif /* CONFIG_PCSC */
+#endif /* PCSC_FUNCS */
 #ifdef CONFIG_EAP_PROXY
 	else if (cred->pcsc && wpa_s->mnc_len > 0 && wpa_s->imsi[0]) {
 		imsi = wpa_s->imsi;