diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 9a0b7be03..4bdc13d9e 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -2212,7 +2212,21 @@ enum wpa_event_type { * e.g., because of a regulatory domain change triggered by scan * results including an AP advertising a country code. */ - EVENT_CHANNEL_LIST_CHANGED + EVENT_CHANNEL_LIST_CHANGED, + + /** + * EVENT_INTERFACE_UNAVAILABLE - Notify that interface is unavailable + * + * This event is used to indicate that the driver cannot maintain this + * interface in its operation mode anymore. The most likely use for + * this is to indicate that AP mode operation is not available due to + * operating channel would need to be changed to a DFS channel when + * the driver does not support radar detection and another virtual + * interfaces caused the operating channel to change. Other similar + * resource conflicts could also trigger this for station mode + * interfaces. + */ + EVENT_INTERFACE_UNAVAILABLE }; diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index de030d253..c0d993561 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1837,6 +1837,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, break; /* Ignore event during drv initialization */ #ifdef CONFIG_P2P wpas_p2p_update_channel_list(wpa_s); +#endif /* CONFIG_P2P */ + break; + case EVENT_INTERFACE_UNAVAILABLE: +#ifdef CONFIG_P2P + wpas_p2p_interface_unavailable(wpa_s); #endif /* CONFIG_P2P */ break; default: diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 7a7524e87..194a430ee 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -220,6 +220,9 @@ static void wpas_p2p_group_delete(struct wpa_supplicant *wpa_s) case P2P_GROUP_REMOVAL_IDLE_TIMEOUT: reason = " reason=IDLE"; break; + case P2P_GROUP_REMOVAL_UNAVAILABLE: + reason = " reason=UNAVAILABLE"; + break; default: reason = ""; break; @@ -3742,3 +3745,15 @@ int wpas_p2p_cancel(struct wpa_supplicant *wpa_s) return 0; } + + +void wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group) + return; + + wpa_printf(MSG_DEBUG, "P2P: Remove group due to driver resource not " + "being available anymore"); + wpa_s->removal_reason = P2P_GROUP_REMOVAL_UNAVAILABLE; + wpas_p2p_group_delete(wpa_s); +} diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index 9b76b4a6e..a411c9a4f 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -117,5 +117,6 @@ void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s); int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s); void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s); int wpas_p2p_cancel(struct wpa_supplicant *wpa_s); +void wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s); #endif /* P2P_SUPPLICANT_H */ diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index f5e80bab0..a4d7511c5 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -518,7 +518,8 @@ struct wpa_supplicant { enum { P2P_GROUP_REMOVAL_UNKNOWN, P2P_GROUP_REMOVAL_REQUESTED, - P2P_GROUP_REMOVAL_IDLE_TIMEOUT + P2P_GROUP_REMOVAL_IDLE_TIMEOUT, + P2P_GROUP_REMOVAL_UNAVAILABLE } removal_reason; #endif /* CONFIG_P2P */