+
+
+int wpas_p2p_set_cross_connect(struct wpa_supplicant *wpa_s, int enabled)
+{
+ if (wpa_s->global->p2p_disabled)
+ return -1;
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)
+ return -1;
+
+ wpa_s->global->cross_connection = enabled;
+ p2p_set_cross_connect(wpa_s->global->p2p, enabled);
+
+ if (!enabled) {
+ struct wpa_supplicant *iface;
+
+ for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
+ {
+ if (iface->cross_connect_enabled == 0)
+ continue;
+
+ iface->cross_connect_enabled = 0;
+ iface->cross_connect_in_use = 0;
+ wpa_msg(iface->parent, MSG_INFO,
+ P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
+ iface->ifname, iface->cross_connect_uplink);
+ }
+ }
+
+ return 0;
+}
+
+
+static void wpas_p2p_enable_cross_connect(struct wpa_supplicant *uplink)
+{
+ struct wpa_supplicant *iface;
+
+ if (!uplink->global->cross_connection)
+ return;
+
+ for (iface = uplink->global->ifaces; iface; iface = iface->next) {
+ if (!iface->cross_connect_enabled)
+ continue;
+ if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) !=
+ 0)
+ continue;
+ if (iface->ap_iface == NULL)
+ continue;
+ if (iface->cross_connect_in_use)
+ continue;
+
+ iface->cross_connect_in_use = 1;
+ wpa_msg(iface->parent, MSG_INFO,
+ P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s",
+ iface->ifname, iface->cross_connect_uplink);
+ }
+}
+
+
+static void wpas_p2p_disable_cross_connect(struct wpa_supplicant *uplink)
+{
+ struct wpa_supplicant *iface;
+
+ for (iface = uplink->global->ifaces; iface; iface = iface->next) {
+ if (!iface->cross_connect_enabled)
+ continue;
+ if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) !=
+ 0)
+ continue;
+ if (!iface->cross_connect_in_use)
+ continue;
+
+ wpa_msg(iface->parent, MSG_INFO,
+ P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
+ iface->ifname, iface->cross_connect_uplink);
+ iface->cross_connect_in_use = 0;
+ }
+}
+
+
+void wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s)
+{
+ if (wpa_s->ap_iface || wpa_s->current_ssid == NULL ||
+ wpa_s->current_ssid->mode != WPAS_MODE_INFRA ||
+ wpa_s->cross_connect_disallowed)
+ wpas_p2p_disable_cross_connect(wpa_s);
+ else
+ wpas_p2p_enable_cross_connect(wpa_s);
+}
+
+
+void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s)
+{
+ wpas_p2p_disable_cross_connect(wpa_s);
+}
+
+
+static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_supplicant *iface;
+
+ if (!wpa_s->global->cross_connection)
+ return;
+
+ for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
+ if (iface == wpa_s)
+ continue;
+ if (iface->drv_flags &
+ WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)
+ continue;
+ if (iface->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE)
+ continue;
+
+ wpa_s->cross_connect_enabled = 1;
+ os_strlcpy(wpa_s->cross_connect_uplink, iface->ifname,
+ sizeof(wpa_s->cross_connect_uplink));
+ wpa_printf(MSG_DEBUG, "P2P: Enable cross connection from "
+ "%s to %s whenever uplink is available",
+ wpa_s->ifname, wpa_s->cross_connect_uplink);
+
+ if (iface->ap_iface || iface->current_ssid == NULL ||
+ iface->current_ssid->mode != WPAS_MODE_INFRA ||
+ iface->cross_connect_disallowed ||
+ iface->wpa_state != WPA_COMPLETED)
+ break;
+
+ wpa_s->cross_connect_in_use = 1;
+ wpa_msg(wpa_s->parent, MSG_INFO,
+ P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s",
+ wpa_s->ifname, wpa_s->cross_connect_uplink);
+ break;
+ }
+}