binder: Add network request/response interface
1. Add a callback function in |INetworkCallback| to make
any control requests on the corresponding network to registered
callback clients.
2. Add a function in |INetwork| to send responses to the above
request from the clients.
These are used when there is a need to perform external
SIM authentication for example.
While there, fix a nit:
Network.SetSSID() is setting a regular byte array field and
not a key field.
BUG: 30815238
TEST: This will have to wait for wificond integration for testing.
Change-Id: I8bfb9c381159373697ae8d1a0d7b999fca19b3a9
Signed-off-by: Roshan Pius <rpius@google.com>
diff --git a/wpa_supplicant/binder/binder.cpp b/wpa_supplicant/binder/binder.cpp
index c93b9bc..6a45754 100644
--- a/wpa_supplicant/binder/binder.cpp
+++ b/wpa_supplicant/binder/binder.cpp
@@ -167,3 +167,23 @@
return binder_manager->notifyStateChange(wpa_s);
}
+
+int wpas_binder_notify_network_request(
+ struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+ enum wpa_ctrl_req_type rtype, const char *default_txt)
+{
+ if (!wpa_s || !wpa_s->global->binder || !ssid)
+ return 1;
+
+ wpa_printf(
+ MSG_DEBUG, "Notifying network request to binder control: %d",
+ ssid->id);
+
+ wpa_supplicant_binder::BinderManager *binder_manager =
+ wpa_supplicant_binder::BinderManager::getInstance();
+ if (!binder_manager)
+ return 1;
+
+ return binder_manager->notifyNetworkRequest(
+ wpa_s, ssid, rtype, default_txt);
+}
diff --git a/wpa_supplicant/binder/binder.h b/wpa_supplicant/binder/binder.h
index 7afc6ef..045a4fa 100644
--- a/wpa_supplicant/binder/binder.h
+++ b/wpa_supplicant/binder/binder.h
@@ -33,6 +33,9 @@
int wpas_binder_unregister_network(
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
int wpas_binder_notify_state_changed(struct wpa_supplicant *wpa_s);
+int wpas_binder_notify_network_request(
+ struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+ enum wpa_ctrl_req_type rtype, const char *default_txt);
#else /* CONFIG_CTRL_IFACE_BINDER */
static inline int wpas_binder_register_interface(struct wpa_supplicant *wpa_s)
{
@@ -56,6 +59,12 @@
{
return 0;
}
+static inline int wpas_binder_notify_network_request(
+ struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+ enum wpa_ctrl_req_type rtype, const char *default_txt)
+{
+ return 0;
+}
#endif /* CONFIG_CTRL_IFACE_BINDER */
#ifdef _cplusplus
diff --git a/wpa_supplicant/binder/binder_manager.cpp b/wpa_supplicant/binder/binder_manager.cpp
index ef96f3a..5d16355 100644
--- a/wpa_supplicant/binder/binder_manager.cpp
+++ b/wpa_supplicant/binder/binder_manager.cpp
@@ -223,8 +223,6 @@
*
* @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
* the state change event occured.
- *
- * @return 0 on success, 1 on failure.
*/
int BinderManager::notifyStateChange(struct wpa_supplicant *wpa_s)
{
@@ -232,7 +230,6 @@
return 1;
const std::string ifname(wpa_s->ifname);
-
if (iface_object_map_.find(ifname) == iface_object_map_.end())
return 1;
@@ -257,6 +254,35 @@
}
/**
+ * Notify all listeners about a request on a particular network.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is present.
+ * @param ssid |wpa_ssid| struct corresponding to the network.
+ * @param type type of request.
+ * @param param addition params associated with the request.
+ */
+int BinderManager::notifyNetworkRequest(
+ struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int type,
+ const char *param)
+{
+ if (!wpa_s || !ssid)
+ return 1;
+
+ const std::string network_key =
+ getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
+ if (network_object_map_.find(network_key) == network_object_map_.end())
+ return 1;
+
+ callWithEachNetworkCallback(
+ wpa_s->ifname, ssid->id,
+ std::bind(
+ &fi::w1::wpa_supplicant::INetworkCallback::OnNetworkRequest,
+ std::placeholders::_1, type, param));
+ return 0;
+}
+
+/**
* Retrieve the |IIface| binder object reference using the provided
* ifname.
*
diff --git a/wpa_supplicant/binder/binder_manager.h b/wpa_supplicant/binder/binder_manager.h
index 5e81078..0cb4999 100644
--- a/wpa_supplicant/binder/binder_manager.h
+++ b/wpa_supplicant/binder/binder_manager.h
@@ -47,6 +47,9 @@
int unregisterNetwork(
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
int notifyStateChange(struct wpa_supplicant *wpa_s);
+ int notifyNetworkRequest(
+ struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int type,
+ const char *param);
// Methods called from binder objects.
int getIfaceBinderObjectByIfname(
@@ -243,5 +246,22 @@
static_assert(
WPA_COMPLETED == fi::w1::wpa_supplicant::IIfaceCallback::STATE_COMPLETED,
"State value mismatch");
+
+static_assert(
+ WPA_CTRL_REQ_UNKNOWN ==
+ fi::w1::wpa_supplicant::INetwork::NETWORK_RSP_UNKNOWN,
+ "Network Rsp value mismatch");
+static_assert(
+ WPA_CTRL_REQ_EXT_CERT_CHECK ==
+ fi::w1::wpa_supplicant::INetwork::NETWORK_RSP_EXT_CERT_CHECK,
+ "Network Rsp value mismatch");
+static_assert(
+ WPA_CTRL_REQ_UNKNOWN ==
+ fi::w1::wpa_supplicant::INetworkCallback::NETWORK_REQ_UNKNOWN,
+ "Network Req value mismatch");
+static_assert(
+ WPA_CTRL_REQ_EXT_CERT_CHECK ==
+ fi::w1::wpa_supplicant::INetworkCallback::NETWORK_REQ_EXT_CERT_CHECK,
+ "Network Req value mismatch");
} // namespace wpa_supplicant_binder
#endif // WPA_SUPPLICANT_BINDER_BINDER_MANAGER_H
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetwork.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetwork.aidl
index 9bc84e2..154d0a5 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetwork.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetwork.aidl
@@ -92,6 +92,21 @@
const int EAP_PHASE2_METHOD_GTC = 4;
/**
+ * Various response types to be sent for the network using
+ * |SendNetworkResponse|.
+ */
+ const int NETWORK_RSP_UNKNOWN = 0;
+ const int NETWORK_RSP_EAP_IDENTITY = 1;
+ const int NETWORK_RSP_EAP_PASSWORD = 2;
+ const int NETWORK_RSP_EAP_NEW_PASSWORD = 3;
+ const int NETWORK_RSP_EAP_PIN = 4;
+ const int NETWORK_RSP_EAP_OTP = 5;
+ const int NETWORK_RSP_EAP_PASSPHRASE = 6;
+ const int NETWORK_RSP_SIM = 7;
+ const int NETWORK_RSP_PSK_PASSPHRASE = 8;
+ const int NETWORK_RSP_EXT_CERT_CHECK = 9;
+
+ /**
* Retrieves the ID allocated to this network by wpa_supplicant.
*
* This is not the |SSID| of the network, but an internal identifier for
@@ -353,4 +368,21 @@
* Initiate connection to this network.
*/
void Select();
+
+ /**
+ * Used to send a response to the request received on this particular network.
+ * The type of response is one of the |NETWORK_RSP_| values above and depending on
+ * the request type may include additional params.
+ *
+ * The request for the response must have been triggered via the corresponding
+ * |INetworkCallback.OnNetworkRequest| call.
+ *
+ * @param type Type of response. This will be one of the |NETWORK_RSP_|*
+ * values above.
+ * @param param Additional param associated with the response.
+ * For ex: NETWORK_RSP_SIM request type may contain either
+ * "GSM-FAIL" or "UMTS-FAIL" param to indicate the failure for
+ * external GSM or 3G authentication.
+ */
+ void SendNetworkResponse(int type, String param);
}
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetworkCallback.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetworkCallback.aidl
index 147f0a6..444210c 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetworkCallback.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetworkCallback.aidl
@@ -19,4 +19,32 @@
*/
@utf8InCpp
interface INetworkCallback {
+ /** Various request types received for the network from |OnNetworkRequest|.*/
+ const int NETWORK_REQ_UNKNOWN = 0;
+ const int NETWORK_REQ_EAP_IDENTITY = 1;
+ const int NETWORK_REQ_EAP_PASSWORD = 2;
+ const int NETWORK_REQ_EAP_NEW_PASSWORD = 3;
+ const int NETWORK_REQ_EAP_PIN = 4;
+ const int NETWORK_REQ_EAP_OTP = 5;
+ const int NETWORK_REQ_EAP_PASSPHRASE = 6;
+ const int NETWORK_REQ_SIM = 7;
+ const int NETWORK_REQ_PSK_PASSPHRASE = 8;
+ const int NETWORK_REQ_EXT_CERT_CHECK = 9;
+
+ /**
+ * Used to indicate a request on this particular network. The type of
+ * request is one of the |NETWORK_REQ_| values above and depending on
+ * the request type may include additional params.
+ *
+ * The response for the request must be sent using the corresponding
+ * |INetwork.SendNetworkResponse| call.
+ *
+ * @param type Type of request. This will be one of the |NETWORK_REQ_|*
+ * values above.
+ * @param param Additional param associated with the request.
+ * For ex: NETWORK_REQ_SIM request type may contain either
+ * "GSM-AUTH" or "UMTS-AUTH" param to indicate the need for
+ * external GSM or 3G authentication.
+ */
+ oneway void OnNetworkRequest(int type, String param);
}
diff --git a/wpa_supplicant/binder/network.cpp b/wpa_supplicant/binder/network.cpp
index 8bd745b..e4dcbd4 100644
--- a/wpa_supplicant/binder/network.cpp
+++ b/wpa_supplicant/binder/network.cpp
@@ -108,8 +108,7 @@
android::binder::Status::EX_ILLEGAL_ARGUMENT,
error_msg.c_str());
}
-
- android::binder::Status status = setByteArrayKeyFieldAndResetState(
+ android::binder::Status status = setByteArrayFieldAndResetState(
ssid.data(), ssid.size(), &(wpa_ssid->ssid), &(wpa_ssid->ssid_len),
"ssid");
if (status.isOk() && wpa_ssid->passphrase) {
@@ -725,6 +724,38 @@
return android::binder::Status::ok();
}
+android::binder::Status Network::SendNetworkResponse(
+ int type, const std::string ¶m)
+{
+ struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+ RETURN_IF_NETWORK_INVALID(wpa_ssid);
+
+ if (type < NETWORK_RSP_UNKNOWN || type > NETWORK_RSP_EXT_CERT_CHECK) {
+ const std::string error_msg =
+ "Invalid network response type: " + std::to_string(type) +
+ ".";
+ return android::binder::Status::fromExceptionCode(
+ android::binder::Status::EX_ILLEGAL_ARGUMENT,
+ error_msg.c_str());
+ }
+
+ enum wpa_ctrl_req_type rtype = (enum wpa_ctrl_req_type)type;
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ if (wpa_supplicant_ctrl_rsp_handle(
+ wpa_s, wpa_ssid, rtype, param.c_str())) {
+ const std::string error_msg =
+ "Failed handling network response: " +
+ std::to_string(type) + ".";
+ return android::binder::Status::fromServiceSpecificError(
+ ERROR_GENERIC, error_msg.c_str());
+ }
+ eapol_sm_notify_ctrl_response(wpa_s->eapol);
+ wpa_hexdump_ascii(
+ MSG_DEBUG, "network response param", (const u8 *)param.c_str(),
+ param.size());
+ return android::binder::Status::ok();
+}
+
/**
* Retrieve the underlying |wpa_ssid| struct pointer for
* this network.
diff --git a/wpa_supplicant/binder/network.h b/wpa_supplicant/binder/network.h
index 6302aa7..34418ec 100644
--- a/wpa_supplicant/binder/network.h
+++ b/wpa_supplicant/binder/network.h
@@ -105,6 +105,8 @@
android::binder::Status Enable(bool no_connect) override;
android::binder::Status Disable() override;
android::binder::Status Select() override;
+ android::binder::Status SendNetworkResponse(
+ int type, const std::string ¶m) override;
private:
struct wpa_ssid *retrieveNetworkPtr();
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 61469dc..393d7d6 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -221,6 +221,8 @@
return;
wpas_dbus_signal_network_request(wpa_s, ssid, rtype, default_txt);
+
+ wpas_binder_notify_network_request(wpa_s, ssid, rtype, default_txt);
}