wifi: support multi-BSS PMK cache

The wifi framework stores opaque data and might not eliminate
duplicate entries for the same BSS. While setting a PMK cache,
check the expiration of existing entry to avoid overriding the latest one.

Bug: 203492843
Test: connect to multi-BSS SAE networks and PMK caches are found
      and work on reconnecting them.
      * setup two BSSes with the same SSID.
      * connect to the first BSS and check PMK cache is added.
      * connect to another SSID and re-connect to the first BSS,
        PMK cache is found and works.
      * connect to the second BSS and check PMK cache is added.
      * connect to another SSID and re-connect to the second BSS,
        PMK cache is found and works.
      * connect to the first BSS and PMK cache is found and works.
      * connect to the second BSS and PMK cache is found and works.
Change-Id: Id50dd1b87826dfda232a27db0965dbf5de526b84
diff --git a/wpa_supplicant/aidl/sta_network.cpp b/wpa_supplicant/aidl/sta_network.cpp
index b6294da..b59d103 100644
--- a/wpa_supplicant/aidl/sta_network.cpp
+++ b/wpa_supplicant/aidl/sta_network.cpp
@@ -2071,6 +2071,15 @@
 	ss.write((char *) serializedEntry.data(), std::streamsize(serializedEntry.size()));
 	misc_utils::deserializePmkCacheEntry(ss, new_entry);
 	new_entry->network_ctx = wpa_ssid;
+
+	// If there is an entry has a later expiration, ignore this one.
+	struct rsn_pmksa_cache_entry *existing_entry = wpa_sm_pmksa_cache_get(
+		wpa_s->wpa, new_entry->aa, NULL, NULL, new_entry->akmp);
+	if (NULL != existing_entry &&
+		existing_entry->expiration >= new_entry->expiration) {
+		return ndk::ScopedAStatus::ok();
+	}
+
 	wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, new_entry);
 
 	return ndk::ScopedAStatus::ok();