Merge "Add HAL support for Passpoint venue URL"
diff --git a/wifi/supplicant/1.4/ISupplicantStaIface.hal b/wifi/supplicant/1.4/ISupplicantStaIface.hal
index 096d8d5..db9a35b 100644
--- a/wifi/supplicant/1.4/ISupplicantStaIface.hal
+++ b/wifi/supplicant/1.4/ISupplicantStaIface.hal
@@ -16,6 +16,9 @@
 
 package android.hardware.wifi.supplicant@1.4;
 
+import @1.0::SupplicantStatus;
+import @1.0::ISupplicantStaIface;
+import @1.0::MacAddress;
 import ISupplicantStaIfaceCallback;
 import @1.3::ISupplicantStaIface;
 
@@ -24,7 +27,6 @@
  * interface (e.g wlan0) it controls.
  */
 interface ISupplicantStaIface extends @1.3::ISupplicantStaIface {
-
     /**
      * Get Connection capabilities
      *
@@ -54,4 +56,21 @@
      */
     registerCallback_1_4(ISupplicantStaIfaceCallback callback)
         generates (SupplicantStatus status);
+
+    /**
+     * Initiate Venue URL ANQP (for IEEE 802.11u Interworking/Hotspot 2.0) query with the
+     * specified access point. This specific query can be used only post connection, once security
+     * is established and PMF is enabled, to avoid spoofing preassociation ANQP responses.
+     * The ANQP data fetched must be returned in the
+     * |ISupplicantStaIfaceCallback.onAnqpQueryDone| callback.
+     *
+     * @param macAddress MAC address of the access point.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    initiateVenueUrlAnqpQuery(MacAddress macAddress)
+        generates (SupplicantStatus status);
 };
diff --git a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal
index 20bce34..852696d 100644
--- a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal
+++ b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal
@@ -16,6 +16,8 @@
 
 package android.hardware.wifi.supplicant@1.4;
 
+import @1.0::ISupplicantStaIfaceCallback.AnqpData;
+import @1.0::ISupplicantStaIfaceCallback.Hs20AnqpData;
 import @1.3::ISupplicantStaIfaceCallback;
 import @1.0::ISupplicantStaIfaceCallback.State;
 import @1.0::Bssid;
@@ -30,6 +32,19 @@
  */
 interface ISupplicantStaIfaceCallback extends @1.3::ISupplicantStaIfaceCallback {
     /**
+     * ANQP data for IEEE Std 802.11-2016.
+     * The format of the data within these elements follows the IEEE
+     * Std 802.11-2016 standard, section 9.4.5.
+     */
+    struct AnqpData {
+        /**
+         * Baseline information as defined in HAL 1.0.
+         */
+        @1.0::ISupplicantStaIfaceCallback.AnqpData V1_0; /* Container for v1.0 of this struct */
+        vec<uint8_t> venueUrl; /* Venue URL ANQP-element */
+    };
+
+    /**
      * Used to indicate a Hotspot 2.0 terms and conditions acceptance is requested from the user
      * before allowing the device to get internet access.
      *
@@ -37,4 +52,16 @@
      * @param url URL of the T&C server.
      */
     oneway onHs20TermsAndConditionsAcceptanceRequestedNotification(Bssid bssid, string url);
+
+    /**
+     * Used to indicate the result of ANQP (either for IEEE 802.11u Interworking
+     * or Hotspot 2.0) query.
+     *
+     * @param bssid BSSID of the access point.
+     * @param data ANQP data fetched from the access point.
+     *        All the fields in this struct must be empty if the query failed.
+     * @param hs20Data ANQP data fetched from the Hotspot 2.0 access point.
+     *        All the fields in this struct must be empty if the query failed.
+     */
+    oneway onAnqpQueryDone_1_4(Bssid bssid, AnqpData data, Hs20AnqpData hs20Data);
 };
diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 88396b6..e079abc 100644
--- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -50,6 +50,10 @@
 using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface;
 using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIfaceCallback;
 
+namespace {
+constexpr uint8_t kTestMacAddr[] = {0x56, 0x67, 0x67, 0xf4, 0x56, 0x92};
+}  // namespace
+
 using SupplicantStatusV1_4 =
     ::android::hardware::wifi::supplicant::V1_4::SupplicantStatus;
 using SupplicantStatusCodeV1_4 =
@@ -61,11 +65,15 @@
         SupplicantHidlTestBaseV1_4::SetUp();
         sta_iface_ = getSupplicantStaIface_1_4(supplicant_);
         ASSERT_NE(sta_iface_.get(), nullptr);
+
+        memcpy(mac_addr_.data(), kTestMacAddr, mac_addr_.size());
     }
 
    protected:
     // ISupplicantStaIface object used for all tests in this fixture.
     sp<ISupplicantStaIface> sta_iface_;
+    // MAC address to use for various tests.
+    std::array<uint8_t, 6> mac_addr_;
 };
 
 class IfaceCallback : public ISupplicantStaIfaceCallback {
@@ -79,7 +87,8 @@
     }
     Return<void> onAnqpQueryDone(
         const hidl_array<uint8_t, 6>& /* bssid */,
-        const ISupplicantStaIfaceCallback::AnqpData& /* data */,
+        const ::android::hardware::wifi::supplicant::V1_0::
+            ISupplicantStaIfaceCallback::AnqpData& /* data */,
         const ISupplicantStaIfaceCallback::Hs20AnqpData& /* hs20Data */)
         override {
         return Void();
@@ -193,6 +202,14 @@
         const hidl_vec<uint8_t>& /* ssid */, bool /* filsHlpSent */) override {
         return Void();
     }
+    Return<void> onAnqpQueryDone_1_4(
+        const hidl_array<uint8_t, 6>& /* bssid */,
+        const ::android::hardware::wifi::supplicant::V1_4::
+            ISupplicantStaIfaceCallback::AnqpData& /* data */,
+        const ISupplicantStaIfaceCallback::Hs20AnqpData& /* hs20Data */)
+        override {
+        return Void();
+    }
 };
 
 /*
@@ -216,6 +233,18 @@
         });
 }
 
+/*
+ * InitiateVenueUrlAnqpQuery.
+ */
+TEST_P(SupplicantStaIfaceHidlTest, InitiateVenueUrlAnqpQuery) {
+    sta_iface_->initiateVenueUrlAnqpQuery(
+        mac_addr_, [](const SupplicantStatusV1_4& status) {
+            // These requests will fail unless the BSSID mentioned is actually
+            // present in scan results.
+            EXPECT_EQ(SupplicantStatusCodeV1_4::FAILURE_UNKNOWN, status.code);
+        });
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest);
 INSTANTIATE_TEST_CASE_P(
     PerInstance, SupplicantStaIfaceHidlTest,