+ return -1;
+}
+
+
+struct ctrl_iface_priv *
+wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
+{
+ struct ctrl_iface_priv *priv;
+
+ priv = os_zalloc(sizeof(*priv));
+ if (priv == NULL)
+ return NULL;
+ dl_list_init(&priv->ctrl_dst);
+ priv->wpa_s = wpa_s;
+ priv->sock = -1;
+
+ if (wpa_s->conf->ctrl_interface == NULL)
+ return priv;
+
+#ifdef ANDROID
+ if (wpa_s->global->params.ctrl_interface) {
+ int same = 0;
+
+ if (wpa_s->global->params.ctrl_interface[0] == '/') {
+ if (os_strcmp(wpa_s->global->params.ctrl_interface,
+ wpa_s->conf->ctrl_interface) == 0)
+ same = 1;
+ } else if (os_strncmp(wpa_s->global->params.ctrl_interface,
+ "@android:", 9) == 0 ||
+ os_strncmp(wpa_s->global->params.ctrl_interface,
+ "@abstract:", 10) == 0) {
+ char *pos;
+
+ /*
+ * Currently, Android uses @android:wpa_* as the naming
+ * convention for the global ctrl interface. This logic
+ * needs to be revisited if the above naming convention
+ * is modified.
+ */
+ pos = os_strchr(wpa_s->global->params.ctrl_interface,
+ '_');
+ if (pos &&
+ os_strcmp(pos + 1,
+ wpa_s->conf->ctrl_interface) == 0)
+ same = 1;
+ }
+
+ if (same) {
+ /*
+ * The invalid configuration combination might be
+ * possible to hit in an Android OTA upgrade case, so
+ * instead of refusing to start the wpa_supplicant
+ * process, do not open the per-interface ctrl_iface
+ * and continue with the global control interface that
+ * was set from the command line since the Wi-Fi
+ * framework will use it for operations.
+ */
+ wpa_printf(MSG_ERROR,
+ "global ctrl interface %s matches ctrl interface %s - do not open per-interface ctrl interface",
+ wpa_s->global->params.ctrl_interface,
+ wpa_s->conf->ctrl_interface);
+ return priv;
+ }
+ }
+#endif /* ANDROID */
+
+ if (wpas_ctrl_iface_open_sock(wpa_s, priv) < 0) {
+ os_free(priv);
+ return NULL;
+ }
+
+ return priv;
+}
+
+
+static int wpas_ctrl_iface_reinit(struct wpa_supplicant *wpa_s,
+ struct ctrl_iface_priv *priv)
+{
+ int res;
+
+ if (priv->sock <= 0)
+ return -1;
+
+ /*
+ * On Android, the control socket being used may be the socket
+ * that is created when wpa_supplicant is started as a /init.*.rc
+ * service. Such a socket is maintained as a key-value pair in
+ * Android's environment. Closing this control socket would leave us
+ * in a bad state with an invalid socket descriptor.
+ */
+ if (priv->android_control_socket)
+ return priv->sock;
+
+ eloop_unregister_read_sock(priv->sock);
+ close(priv->sock);
+ priv->sock = -1;
+ res = wpas_ctrl_iface_open_sock(wpa_s, priv);
+ if (res < 0)
+ return -1;
+ return priv->sock;