Wifi: DPP STA Enrollee-Responder mode

Added below HIDL APIs for DPP STA Enrollee-Responder mode
1. API to start DPP in Enrollee-Responder mode
2. API to generate DPP bootstrap URI
3. API to stop DPP in Enrollee-Responder mode
which internally remove the bootstrap and stop listen.

Bug: 162686712
Test: VTS test
Change-Id: I979b6a7a2fe90f48d478f48da73269fd3f5cb347
diff --git a/wifi/supplicant/1.4/ISupplicantStaIface.hal b/wifi/supplicant/1.4/ISupplicantStaIface.hal
index f9e4c9b..7441ba5 100644
--- a/wifi/supplicant/1.4/ISupplicantStaIface.hal
+++ b/wifi/supplicant/1.4/ISupplicantStaIface.hal
@@ -71,8 +71,7 @@
      *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
      *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
      */
-    initiateVenueUrlAnqpQuery(MacAddress macAddress)
-        generates (SupplicantStatus status);
+    initiateVenueUrlAnqpQuery(MacAddress macAddress) generates (SupplicantStatus status);
 
     /**
      * Get wpa driver capabilities.
@@ -84,4 +83,55 @@
      */
     getWpaDriverCapabilities_1_4() generates (SupplicantStatus status,
         bitfield<WpaDriverCapabilitiesMask> driverCapabilitiesMask);
+
+    /**
+     * Generates DPP bootstrap information: Bootstrap ID, DPP URI and listen
+     * channel for responder mode.
+     *
+     * @param MacAddress MAC address of the interface for the DPP operation.
+     * @param deviceInfo Device specific information.
+     *        As per DPP Specification V1.0 section 5.2,
+     *        allowed Range of ASCII characters in deviceInfo - %x20-7E
+     *        semicolon is not allowed.
+     * @param DppCurve Elliptic curve cryptography type used to generate DPP
+     * public/private key pair.
+     * @return status of operation and bootstrap info.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    generateDppBootstrapInfoForResponder(MacAddress macAddress, string deviceInfo, DppCurve curve)
+        generates (SupplicantStatus status, DppResponderBootstrapInfo bootstrapInfo);
+
+    /**
+     * Start DPP in Enrollee-Responder mode.
+     * Framework must first call |generateDppBootstrapInfoForResponder| to generate
+     * the bootstrapping information: Bootstrap ID, DPP URI and the listen channel.
+     * Then call this API with derived listen channel to start listening for
+     * authentication request from Peer initiator.
+     *
+     * @param listenChannel DPP listen channel.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    startDppEnrolleeResponder(uint32_t listenChannel) generates (SupplicantStatus status);
+
+    /**
+     * Stop DPP Responder operation - Remove the bootstrap code and stop listening.
+     *
+     * @param ownBootstrapId Local device's URI ID obtained through
+     *        |generateDppBootstrapInfoForResponder| call.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    stopDppResponder(uint32_t ownBootstrapId) generates (SupplicantStatus status);
 };
diff --git a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal
index 852696d..efcebda 100644
--- a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal
+++ b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal
@@ -40,8 +40,12 @@
         /**
          * 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 */
+        @1.0::ISupplicantStaIfaceCallback.AnqpData V1_0;
+
+        /*
+         * Container for v1.0 of this struct
+         */
+        vec<uint8_t> venueUrl;
     };
 
     /**
diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
index 80beedf..6bed5ab 100644
--- a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
+++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
@@ -17,7 +17,7 @@
 package android.hardware.wifi.supplicant@1.4;
 
 import @1.3::ISupplicantStaNetwork;
-import @1.4::ISupplicantStaNetworkCallback;
+import ISupplicantStaNetworkCallback;
 
 /**
  * Interface exposed by the supplicant for each station mode network
diff --git a/wifi/supplicant/1.4/types.hal b/wifi/supplicant/1.4/types.hal
index 18af8fe..aec61c4 100644
--- a/wifi/supplicant/1.4/types.hal
+++ b/wifi/supplicant/1.4/types.hal
@@ -18,6 +18,7 @@
 
 import @1.0::SupplicantStatusCode;
 import @1.3::ConnectionCapabilities;
+import @1.3::DppFailureCode;
 import @1.3::WpaDriverCapabilitiesMask;
 
 /**
@@ -40,6 +41,29 @@
 };
 
 /**
+ * DppFailureCode: Error codes for DPP (Easy Connect)
+ */
+enum DppFailureCode : @1.3::DppFailureCode {
+    /**
+     * Failure to generate a DPP URI.
+     */
+    URI_GENERATION,
+};
+
+/**
+ * DppCurve: Elliptic curve cryptography type used to generate DPP
+ * public/private key pair.
+ */
+enum DppCurve : uint32_t {
+    PRIME256V1,
+    SECP384R1,
+    SECP521R1,
+    BRAINPOOLP256R1,
+    BRAINPOOLP384R1,
+    BRAINPOOLP512R1,
+};
+
+/**
  * Connection Capabilities supported by current network and device
  */
 struct ConnectionCapabilities {
@@ -47,6 +71,7 @@
      * Baseline information as defined in HAL 1.3.
      */
     @1.3::ConnectionCapabilities V1_3;
+
     /**
      * detailed network mode for legacy network
      */
@@ -64,13 +89,14 @@
  * Generic structure to return the status of any supplicant operation.
  */
 struct SupplicantStatus {
-  SupplicantStatusCode code;
-  /**
-   * A vendor specific error message to provide more information beyond the
-   * status code.
-   * This will be used for debbuging purposes only.
-   */
-  string debugMessage;
+    SupplicantStatusCode code;
+
+    /**
+     * A vendor specific error message to provide more information beyond the
+     * status code.
+     * This will be used for debbuging purposes only.
+     */
+    string debugMessage;
 };
 
 /**
@@ -78,7 +104,27 @@
  */
 enum WpaDriverCapabilitiesMask : @1.3::WpaDriverCapabilitiesMask {
     /**
-     *
      */
     SAE_PK = 1 << 2,
 };
+
+/**
+ * DPP bootstrap info generated for responder mode operation
+ */
+struct DppResponderBootstrapInfo {
+    /**
+     * Generated bootstrap identifier
+     */
+    uint32_t bootstrapId;
+
+    /**
+     * The Wi-Fi channel that the DPP responder is listening on.
+     */
+    uint32_t listenChannel;
+
+    /**
+     * Bootstrapping URI per DPP specification, "section 5.2 Bootstrapping
+     * information", may contain listen channel, MAC address, public key, or other information.
+     */
+    string uri;
+};
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 c0b5a70..ccd469d 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
@@ -19,6 +19,7 @@
 #include <android/hardware/wifi/supplicant/1.1/ISupplicant.h>
 #include <android/hardware/wifi/supplicant/1.2/types.h>
 #include <android/hardware/wifi/supplicant/1.3/ISupplicant.h>
+#include <android/hardware/wifi/supplicant/1.3/ISupplicantStaNetwork.h>
 #include <android/hardware/wifi/supplicant/1.3/types.h>
 #include <android/hardware/wifi/supplicant/1.4/ISupplicant.h>
 #include <android/hardware/wifi/supplicant/1.4/ISupplicantStaIface.h>
@@ -45,7 +46,10 @@
 using ::android::hardware::wifi::supplicant::V1_2::DppNetRole;
 using ::android::hardware::wifi::supplicant::V1_2::DppProgressCode;
 using ::android::hardware::wifi::supplicant::V1_3::DppSuccessCode;
+using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaNetwork;
 using ::android::hardware::wifi::supplicant::V1_4::ConnectionCapabilities;
+using ::android::hardware::wifi::supplicant::V1_4::DppCurve;
+using ::android::hardware::wifi::supplicant::V1_4::DppResponderBootstrapInfo;
 using ::android::hardware::wifi::supplicant::V1_4::ISupplicant;
 using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface;
 using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIfaceCallback;
@@ -74,6 +78,24 @@
     sp<ISupplicantStaIface> sta_iface_;
     // MAC address to use for various tests.
     std::array<uint8_t, 6> mac_addr_;
+
+    bool isDppSupported() {
+        uint32_t keyMgmtMask = 0;
+
+        // We need to first get the key management capabilities from the device.
+        // If DPP is not supported, we just pass the test.
+        sta_iface_->getKeyMgmtCapabilities_1_3(
+            [&](const SupplicantStatus& status, uint32_t keyMgmtMaskInternal) {
+                EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+                keyMgmtMask = keyMgmtMaskInternal;
+            });
+
+        if (!(keyMgmtMask & ISupplicantStaNetwork::KeyMgmtMask::DPP)) {
+            // DPP not supported
+            return false;
+        }
+        return true;
+    }
 };
 
 class IfaceCallback : public ISupplicantStaIfaceCallback {
@@ -255,6 +277,48 @@
         });
 }
 
+/*
+ * StartDppEnrolleeResponder
+ */
+TEST_P(SupplicantStaIfaceHidlTest, StartDppEnrolleeResponder) {
+    // We need to first get the key management capabilities from the device.
+    // If DPP is not supported, we just pass the test.
+    if (!isDppSupported()) {
+        // DPP not supported
+        return;
+    }
+
+    hidl_string deviceInfo = "DPP_Responder_Mode_VTS_Test";
+    uint32_t bootstrap_id = 0;
+    uint32_t listen_channel = 0;
+    uint8_t mac_address[6] = {0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+
+    // Generate DPP bootstrap information
+    sta_iface_->generateDppBootstrapInfoForResponder(
+        mac_address, deviceInfo, DppCurve::PRIME256V1,
+        [&](const SupplicantStatusV1_4& status,
+            DppResponderBootstrapInfo bootstrapInfo) {
+            EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code);
+            EXPECT_NE(-1, bootstrapInfo.bootstrapId);
+            EXPECT_NE(0, bootstrapInfo.bootstrapId);
+            bootstrap_id = bootstrapInfo.bootstrapId;
+            listen_channel = bootstrapInfo.listenChannel;
+            EXPECT_NE(0, bootstrapInfo.listenChannel);
+        });
+
+    // Start DPP as Enrollee-Responder.
+    sta_iface_->startDppEnrolleeResponder(
+        listen_channel, [&](const SupplicantStatusV1_4& status) {
+            EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code);
+        });
+
+    // Stop DPP Enrollee-Responder mode, ie remove the URI and stop listen.
+    sta_iface_->stopDppResponder(
+        bootstrap_id, [&](const SupplicantStatusV1_4& status) {
+            EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code);
+        });
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest);
 INSTANTIATE_TEST_CASE_P(
     PerInstance, SupplicantStaIfaceHidlTest,